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

import com.infoepoch.pms.dispatchassistant.domain.system.dict.IDictDataRepository;
import com.infoepoch.pms.dispatchassistant.domain.system.dict.SystemDictCriteria;
import com.infoepoch.pms.dispatchassistant.domain.system.dict.SystemDictData;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.stereotype.Repository;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

@Repository
public class DictDataRepository implements IDictDataRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public List<SystemDictData> selectByDictType(String dictType) {
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet("SELECT * FROM SYS_DICT_DATA WHERE DD_DICT_TYPE = ?", dictType);
        List<SystemDictData> dictDataList = new ArrayList<>();
        while (sqlRowSet.next())
            dictDataList.add(convert(sqlRowSet));
        return dictDataList;
    }

    @Override
    public SystemDictData selectById(String id) {
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet("SELECT * FROM SYS_DICT_DATA WHERE DD_ID = ?", id);
        if (sqlRowSet.next())
            return convert(sqlRowSet);
        return null;
    }

    @Override
    public List<SystemDictData> selectByCriteria(SystemDictCriteria criteria) {
        String baseSql = "SELECT TEMP.* FROM (SELECT ROWNUM R,V.* FROM (SELECT * FROM SYS_DICT_DATA WHERE 1=1";
        List<Object> paramList = new ArrayList<>();
        StringBuilder sql = transferCriteria(baseSql, criteria, paramList);
        sql.append(" ORDER BY DD_SORT ASC) V) TEMP");
        if (criteria.isPaginationFlag()) {
            sql.append(" WHERE TEMP.R BETWEEN ? AND ?");
            paramList.add(criteria.startIndex());
            paramList.add(criteria.endIndex());
        }
        SqlRowSet sqlRowSet = jdbcTemplate.queryForRowSet(sql.toString(), paramList.toArray());
        List<SystemDictData> dictDataList = new ArrayList<>();
        while (sqlRowSet.next())
            dictDataList.add(convert(sqlRowSet));
        return dictDataList;
    }

    @Override
    public int selectByCriteriaCount(SystemDictCriteria criteria) {
        String baseSql = "SELECT COUNT(1) FROM (SELECT * FROM SYS_DICT_DATA WHERE 1=1";
        List<Object> paramList = new ArrayList<>();
        StringBuilder sql = transferCriteria(baseSql, criteria, paramList);
        sql.append(" ORDER BY DD_SORT ASC) V");
        return jdbcTemplate.queryForObject(sql.toString(), paramList.toArray(), int.class);
    }

    @Override
    public void insert(SystemDictData dictData) {
        String sql = "INSERT INTO SYS_DICT_DATA(DD_ID,DD_DICT_TYPE,DD_SORT,DD_LABEL,DD_VALUE,DD_CSS_CLASS,DD_LIST_CLASS," +
                "DD_DEFAULT_FLAG,DD_STATUS,DD_CREATE_BY,DD_CREATE_TIME,DD_UPDATE_BY,DD_UPDATE_TIME,DD_REMARK)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        jdbcTemplate.update(sql,
                dictData.getId(),
                dictData.getDictType(),
                dictData.getSort(),
                dictData.getLabel(),
                dictData.getValue(),
                dictData.getCssClass(),
                dictData.getListClass(),
                dictData.getDefaultFlag(),
                dictData.getStatus(),
                dictData.getCreateBy(),
                dictData.getCreateTime(),
                dictData.getUpdateBy(),
                dictData.getUpdateTime(),
                dictData.getRemark()
        );
    }

    @Override
    public void update(SystemDictData dictData) {
        String sql = "UPDATE SYS_DICT_DATA SET DD_DICT_TYPE=?,DD_SORT=?,DD_LABEL=?,DD_VALUE=?,DD_CSS_CLASS=?,DD_LIST_CLASS=?," +
                "DD_DEFAULT_FLAG=?,DD_STATUS=?,DD_CREATE_BY=?,DD_CREATE_TIME=?,DD_UPDATE_BY=?,DD_UPDATE_TIME=?,DD_REMARK=?" +
                " WHERE DD_ID = ?";
        jdbcTemplate.update(sql,
                dictData.getDictType(),
                dictData.getSort(),
                dictData.getLabel(),
                dictData.getValue(),
                dictData.getCssClass(),
                dictData.getListClass(),
                dictData.getDefaultFlag(),
                dictData.getStatus(),
                dictData.getCreateBy(),
                dictData.getCreateTime(),
                dictData.getUpdateBy(),
                dictData.getUpdateTime(),
                dictData.getRemark(),
                dictData.getId()
        );
    }

    @Override
    public void batchInsert(List<SystemDictData> dictDataList) {
        String sql = "INSERT INTO SYS_DICT_DATA(DD_ID,DD_DICT_TYPE,DD_SORT,DD_LABEL,DD_VALUE,DD_CSS_CLASS,DD_LIST_CLASS," +
                "DD_DEFAULT_FLAG,DD_STATUS,DD_CREATE_BY,DD_CREATE_TIME,DD_UPDATE_BY,DD_UPDATE_TIME,DD_REMARK)" +
                " VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SystemDictData dictData = dictDataList.get(i);
                int j = 0;
                ps.setString(++j, dictData.getId());
                ps.setString(++j, dictData.getDictType());
                ps.setInt(++j, dictData.getSort());
                ps.setString(++j, dictData.getLabel());
                ps.setString(++j, dictData.getValue());
                ps.setString(++j, dictData.getCssClass());
                ps.setString(++j, dictData.getListClass());
                ps.setInt(++j, dictData.getDefaultFlag());
                ps.setInt(++j, dictData.getStatus());
                ps.setString(++j, dictData.getCreateBy());
                ps.setTimestamp(++j, dictData.getCreateTime() == null ? null : new Timestamp(dictData.getCreateTime().getTime()));
                ps.setString(++j, dictData.getUpdateBy());
                ps.setTimestamp(++j, dictData.getUpdateTime() == null ? null : new Timestamp(dictData.getUpdateTime().getTime()));
                ps.setString(++j, dictData.getRemark());
            }

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

    @Override
    public void batchUpdate(List<SystemDictData> dictDataList) {
        String sql = "UPDATE SYS_DICT_DATA SET DD_DICT_TYPE=?,DD_SORT=?,DD_LABEL=?,DD_VALUE=?,DD_CSS_CLASS=?,DD_LIST_CLASS=?," +
                "DD_DEFAULT_FLAG=?,DD_STATUS=?,DD_CREATE_BY=?,DD_CREATE_TIME=?,DD_UPDATE_BY=?,DD_UPDATE_TIME=?,DD_REMARK=?" +
                " WHERE DD_ID = ?";
        jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                SystemDictData dictData = dictDataList.get(i);
                int j = 0;
                ps.setString(++j, dictData.getDictType());
                ps.setInt(++j, dictData.getSort());
                ps.setString(++j, dictData.getLabel());
                ps.setString(++j, dictData.getValue());
                ps.setString(++j, dictData.getCssClass());
                ps.setString(++j, dictData.getListClass());
                ps.setInt(++j, dictData.getDefaultFlag());
                ps.setInt(++j, dictData.getStatus());
                ps.setString(++j, dictData.getCreateBy());
                ps.setTimestamp(++j, dictData.getCreateTime() == null ? null : new Timestamp(dictData.getCreateTime().getTime()));
                ps.setString(++j, dictData.getUpdateBy());
                ps.setTimestamp(++j, dictData.getUpdateTime() == null ? null : new Timestamp(dictData.getUpdateTime().getTime()));
                ps.setString(++j, dictData.getRemark());
                ps.setString(++j, dictData.getId());
            }

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

    @Override
    public void softDeleteById(String id) {
        jdbcTemplate.update("UPDATE SYS_DICT_DATA SET DD_STATUS = 2 WHERE DD_ID = ?", id);
    }

    @Override
    public void deleteById(String id) {
        jdbcTemplate.update("DELETE FROM SYS_DICT_DATA WHERE DD_ID = ?", id);
    }

    @Override
    public void softDeleteByDictType(String dictType) {
        jdbcTemplate.update("UPDATE SYS_DICT_DATA SET DD_STATUS = 2 WHERE DD_DICT_TYPE = ?", dictType);
    }

    @Override
    public void deleteByDictType(String dictType) {
        jdbcTemplate.update("DELETE FROM SYS_DICT_DATA WHERE DD_DICT_TYPE = ?", dictType);
    }

    /**
     * 查询条件转换
     *
     * @param baseSql
     * @param criteria
     * @param paramList
     * @return
     */
    private StringBuilder transferCriteria(String baseSql, SystemDictCriteria criteria, List<Object> paramList) {
        StringBuilder sql = new StringBuilder(baseSql);
        if (StringUtils.isNotBlank(criteria.getDictType())) {
            sql.append(" AND DD_DICT_TYPE = ?");
            paramList.add(criteria.getDictType());
        }
        if (StringUtils.isNotBlank(criteria.getLabel())) {
            sql.append(" AND DD_LABEL LIKE ?");
            paramList.add("%" + criteria.getLabel() + "%");
        }
        if (criteria.getStatus() == null) {
            sql.append(" AND DD_STATUS != 2");
        } else {
            sql.append(" AND DD_STATUS = ?");
            paramList.add(criteria.getStatus());
        }
        return sql;
    }

    /**
     * 查询结果集转换
     *
     * @param sqlRowSet
     * @return
     */
    private SystemDictData convert(SqlRowSet sqlRowSet) {
        return new SystemDictData(
                sqlRowSet.getString("DD_ID"),
                sqlRowSet.getString("DD_DICT_TYPE"),
                sqlRowSet.getInt("DD_SORT"),
                sqlRowSet.getString("DD_LABEL"),
                sqlRowSet.getString("DD_VALUE"),
                sqlRowSet.getString("DD_CSS_CLASS"),
                sqlRowSet.getString("DD_LIST_CLASS"),
                sqlRowSet.getInt("DD_DEFAULT_FLAG"),
                sqlRowSet.getInt("DD_STATUS"),
                sqlRowSet.getString("DD_CREATE_BY"),
                sqlRowSet.getTimestamp("DD_CREATE_TIME"),
                sqlRowSet.getString("DD_UPDATE_BY"),
                sqlRowSet.getTimestamp("DD_UPDATE_TIME"),
                sqlRowSet.getString("DD_REMARK")
        );
    }
}
