package com.infoepoch.pms.dispatchassistant.infractructure.system.file;

import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.common.utils.OracleUtils;
import com.infoepoch.pms.dispatchassistant.domain.system.uploadFile.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 上传文件记录表仓储实现
 */
@Repository
public class UploadFileRepository implements IUploadFileRepository {

    private static final Logger logger = LoggerFactory.getLogger(UploadFileRepository.class);
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    /**
     * 新增
     */
    @Override
    public boolean insert(UploadFile entity) {
        String sql = "INSERT INTO UTL_UPLOAD_FILE(UF_ID, UF_FILE_NAME, UF_EXTENSION, UF_SAVE_PATH, UF_CONTENT_LENGTH, UF_CONTENT_TYPE, UF_UPLOAD_TIME, UF_HAS_DIMENSION, UF_WIDTH, UF_HEIGHT, UF_THUMBNAL_DATA, UF_UPLOAD_USER_ID, UF_UPLOAD_USER_NAME, UF_DOMAIN_ID, UF_DOMAIN_TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getId(), entity.getFileName(), entity.getExtension(), entity.getSavePath(), entity.getContentLength(), entity.getContentType(), entity.getUploadTime(), entity.getHasDimension(), entity.getWidth(), entity.getHeight(), entity.getThumbnalData(), entity.getUploadUserId(), entity.getUploadUserName(), entity.getDomainId(), entity.getDomainType());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("新增 上传文件记录表 失败。");
        }
        return result > 0;
    }

    /**
     * 更新
     */
    @Override
    public boolean update(UploadFile entity) {
        String sql = "UPDATE UTL_UPLOAD_FILE SET UF_FILE_NAME = ?, UF_EXTENSION = ?, UF_SAVE_PATH = ?, UF_CONTENT_LENGTH = ?, UF_CONTENT_TYPE = ?, UF_UPLOAD_TIME = ?, UF_HAS_DIMENSION = ?, UF_WIDTH = ?, UF_HEIGHT = ?, UF_THUMBNAL_DATA = ?, UF_UPLOAD_USER_ID = ?, UF_UPLOAD_USER_NAME = ?, UF_DOMAIN_ID = ?, UF_DOMAIN_TYPE = ? WHERE UF_ID = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getFileName(), entity.getExtension(), entity.getSavePath(), entity.getContentLength(), entity.getContentType(), entity.getUploadTime(), entity.getHasDimension(), entity.getWidth(), entity.getHeight(), entity.getThumbnalData(), entity.getUploadUserId(), entity.getUploadUserName(), entity.getDomainId(), entity.getDomainType(), entity.getId());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("更新 上传文件记录表 失败。");
        }
        return result >= 0;
    }

    /**
     * 批量新增
     */
    public int[] batchInsert(List<UploadFile> list) {
        String sql = "INSERT INTO UTL_UPLOAD_FILE(UF_ID, UF_FILE_NAME, UF_EXTENSION, UF_SAVE_PATH, UF_CONTENT_LENGTH, UF_CONTENT_TYPE, UF_UPLOAD_TIME, UF_HAS_DIMENSION, UF_WIDTH, UF_HEIGHT, UF_THUMBNAL_DATA, UF_UPLOAD_USER_ID, UF_UPLOAD_USER_NAME, UF_DOMAIN_ID, UF_DOMAIN_TYPE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                UploadFile item = list.get(i);
                ps.setString(++j, item.getId());
                ps.setString(++j, item.getFileName());
                ps.setString(++j, item.getExtension());
                ps.setString(++j, item.getSavePath());
                ps.setObject(++j, item.getContentLength());
                ps.setString(++j, item.getContentType());
                ps.setTimestamp(++j, item.getUploadTime() != null ? new Timestamp(item.getUploadTime().getTime()) : null);
                ps.setBoolean(++j, item.getHasDimension());
                ps.setBigDecimal(++j, item.getWidth());
                ps.setBigDecimal(++j, item.getHeight());
                ps.setString(++j, item.getThumbnalData());
                ps.setString(++j, item.getUploadUserId());
                ps.setString(++j, item.getUploadUserName());
                ps.setString(++j, item.getDomainId());
                ps.setString(++j, item.getDomainType());
            }

            @Override
            public int getBatchSize() {
                return list.size();
            }
        });
        return result;
    }

    /**
     * 批量更新
     */
    public int[] batchUpdate(List<UploadFile> list) {
        String sql = "UPDATE UTL_UPLOAD_FILE SET UF_FILE_NAME = ?, UF_EXTENSION = ?, UF_SAVE_PATH = ?, UF_CONTENT_LENGTH = ?, UF_CONTENT_TYPE = ?, UF_UPLOAD_TIME = ?, UF_HAS_DIMENSION = ?, UF_WIDTH = ?, UF_HEIGHT = ?, UF_THUMBNAL_DATA = ?, UF_UPLOAD_USER_ID = ?, UF_UPLOAD_USER_NAME = ?, UF_DOMAIN_ID = ?, UF_DOMAIN_TYPE = ? WHERE UF_ID = ? ";
        int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                UploadFile item = list.get(i);
                ps.setString(++j, item.getFileName());
                ps.setString(++j, item.getExtension());
                ps.setString(++j, item.getSavePath());
                ps.setObject(++j, item.getContentLength());
                ps.setString(++j, item.getContentType());
                ps.setTimestamp(++j, item.getUploadTime() != null ? new Timestamp(item.getUploadTime().getTime()) : null);
                ps.setBoolean(++j, item.getHasDimension());
                ps.setBigDecimal(++j, item.getWidth());
                ps.setBigDecimal(++j, item.getHeight());
                ps.setString(++j, item.getThumbnalData());
                ps.setString(++j, item.getUploadUserId());
                ps.setString(++j, item.getUploadUserName());
                ps.setString(++j, item.getDomainId());
                ps.setString(++j, item.getDomainType());
                ps.setString(++j, item.getId());
            }

            @Override
            public int getBatchSize() {
                return list.size();
            }
        });
        return result;
    }

    /**
     * 删除
     */
    @Override
    public boolean delete(String id) {
        String sql = "DELETE FROM UTL_UPLOAD_FILE WHERE UF_ID = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, id);
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("删除 上传文件记录表 失败。");
        }
        return result > 0;
    }

    /**
     * 根据Id查询
     */
    @Override
    public UploadFile selectById(String id) {
        String sql = "SELECT * FROM UTL_UPLOAD_FILE WHERE UF_ID = ? ";
        try {
            return jdbcTemplate.queryForObject(sql, new UploadFileRowMapper(), id);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    @Override
    public List<UploadFile> selectByIds(List<String> ids) {
        List<UploadFile> uploadFiles = new ArrayList<>();
        if (ids == null || ids.size() == 0)
            return uploadFiles;
        StringBuilder sql = new StringBuilder("SELECT * FROM UTL_UPLOAD_FILE WHERE UF_ID IN (");
        for (int i = 0; i < ids.size(); i++) {
            sql.append("?");
            if (i < ids.size() - 1) {
                sql.append(",");
            }
        }
        sql.append(")");
        try {
            return jdbcTemplate.query(sql.toString(), new UploadFileRowMapper(), ids.toArray());
        } catch (EmptyResultDataAccessException e) {
            return uploadFiles;
        }
    }

    /**
     * 根据查询条件查询单个对象
     */
    @Override
    public UploadFile selectOneByCriteria(UploadFileCriteria criteria) {
        StringBuffer buffer = new StringBuffer("SELECT * FROM UTL_UPLOAD_FILE ");
        List<Object> list = OracleUtils.combinationSql(buffer, createCriteriaSql(criteria), 1, 1);
        try {
            return jdbcTemplate.queryForObject(buffer.toString(), new UploadFileRowMapper(), list.toArray());
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * 根据查询条件查询对象集合
     */
    @Override
    public List<UploadFile> selectByCriteria(UploadFileCriteria criteria) {
        StringBuffer buffer = new StringBuffer("SELECT * FROM UTL_UPLOAD_FILE ");
        List<Object> list = OracleUtils.combinationSql(buffer, createCriteriaSql(criteria));
        try {
            return jdbcTemplate.query(buffer.toString(), new UploadFileRowMapper(), list.toArray());
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * 根据查询条件分页查询对象结合
     */
    @Override
    public List<UploadFile> selectCriteriaByPage(UploadFileCriteria criteria, int pageIndex, int pageSize) {
        StringBuffer buffer = new StringBuffer("SELECT * FROM UTL_UPLOAD_FILE ");
        List<Object> list = OracleUtils.combinationSql(buffer, createCriteriaSql(criteria), pageIndex, pageSize);
        try {
            return jdbcTemplate.query(buffer.toString(), new UploadFileRowMapper(), list.toArray());
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * 根据条件查询对象总记录数
     */
    @Override
    public int selectCountByCriteria(UploadFileCriteria criteria) {
        StringBuffer buffer = new StringBuffer("SELECT COUNT(*) FROM UTL_UPLOAD_FILE ");
        List<Object> list = OracleUtils.combinationSql(buffer, createCriteriaSql(criteria));
        Integer count = jdbcTemplate.queryForObject(buffer.toString(), Integer.class, list.toArray());
        return count == null ? 0 : count;
    }

    /**
     * RowMapper
     */
    static class UploadFileRowMapper implements RowMapper<UploadFile> {
        @Override
        public UploadFile mapRow(ResultSet rs, int i) throws SQLException {
            return new UploadFile(
                    rs.getString("UF_ID"),
                    rs.getString("UF_FILE_NAME"),
                    rs.getString("UF_EXTENSION"),
                    rs.getString("UF_SAVE_PATH"),
                    rs.getObject("UF_CONTENT_LENGTH") != null ? rs.getLong("UF_CONTENT_LENGTH") : null,
                    rs.getString("UF_CONTENT_TYPE"),
                    rs.getTimestamp("UF_UPLOAD_TIME"),
                    rs.getObject("UF_HAS_DIMENSION") != null ? rs.getBoolean("UF_HAS_DIMENSION") : null,
                    rs.getBigDecimal("UF_WIDTH"),
                    rs.getBigDecimal("UF_HEIGHT"),
                    rs.getString("UF_THUMBNAL_DATA"),
                    rs.getString("UF_UPLOAD_USER_ID"),
                    rs.getString("UF_UPLOAD_USER_NAME"),
                    rs.getString("UF_DOMAIN_ID"),
                    rs.getString("UF_DOMAIN_TYPE")
            );
        }
    }

    /**
     * 创建查询条件
     */
    private Map<String, Object> createCriteriaSql(UploadFileCriteria criteria) {
        Map<String, Object> andMap = new LinkedHashMap<>();
        if (criteria == null)
            return andMap;
        //if (criteria.byId())
        //    andMap.put(criteria.getId() == null ? " T_Id IS NULL " : " T_Id = ? ", criteria.getId());

        //文件名称（LIKE）
        if (criteria.byFileNameContain())
            andMap.put(" UF_FILE_NAME LIKE ? ", "%" + criteria.getFileNameContain() + "%");
        //后缀
        if (criteria.byExtension())
            andMap.put(criteria.getExtension() == null ? " UF_EXTENSION IS NULL " : " UF_EXTENSION = ? ", criteria.getExtension());
        //后缀（LIKE）
        if (criteria.byExtensionContain())
            andMap.put(" UF_EXTENSION LIKE ? ", "%" + criteria.getExtensionContain() + "%");
        //文件类型
        if (criteria.byContentType())
            andMap.put(criteria.getContentType() == null ? " UF_CONTENT_TYPE IS NULL " : " UF_CONTENT_TYPE = ? ", criteria.getContentType());
        //上传时间
        if (criteria.byUploadTime())
            andMap.put(criteria.getUploadTime() == null ? " UF_UPLOAD_TIME IS NULL " : " UF_UPLOAD_TIME = ? ", criteria.getUploadTime());
        //是否有尺寸，只有图片文件可以计算尺寸
        if (criteria.byHasDimension())
            andMap.put(criteria.getHasDimension() == null ? " UF_HAS_DIMENSION IS NULL " : " UF_HAS_DIMENSION = ? ", criteria.getHasDimension());
        //文件上传者ID
        if (criteria.byUploadUserId())
            andMap.put(criteria.getUploadUserId() == null ? " UF_UPLOAD_USER_ID IS NULL " : " UF_UPLOAD_USER_ID = ? ", criteria.getUploadUserId());
        //文件上传者姓名（LIKE）
        if (criteria.byUploadUserNameContain())
            andMap.put(" UF_UPLOAD_USER_NAME LIKE ? ", "%" + criteria.getUploadUserNameContain() + "%");
        //关联领域ID
        if (criteria.byDomainId())
            andMap.put(criteria.getDomainId() == null ? " UF_DOMAIN_ID IS NULL " : " UF_DOMAIN_ID = ? ", criteria.getDomainId());
        //关联单据类型
        if (criteria.byDomainType())
            andMap.put(criteria.getDomainType() == null ? " UF_DOMAIN_TYPE IS NULL " : " UF_DOMAIN_TYPE = ? ", criteria.getDomainType());
        return andMap;
    }

}
