package com.infoepoch.pms.dispatchassistant.infractructure.oa;

import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.common.utils.OracleUtils;
import com.infoepoch.pms.dispatchassistant.domain.oa.user.*;
import org.apache.commons.collections4.CollectionUtils;
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.stereotype.Repository;

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

/**
 * OA用户PMS仓储实现
 */
@Repository
public class UserPmsRepository implements IUserPmsRepository {

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

    /**
     * 新增
     */
    @Override
    public boolean insert(UserPms entity) {
        String sql = "INSERT INTO OA_USER_PMS(OU_ID, EMPLOYEE_NUMBER, FULL_NAME, SEX, RETIRE_STATUS, EMPLOYEE_TYPE, MOBILE_NUMBER, EMAIL, IS_PRIMARY_ACCOUNT, HR_ORG_CODE, OA_ORG_CODE, DUTY, DISPLAY_ORDER, REFERENCE1, REFERENCE2, REFERENCE3, REFERENCE4, REFERENCE5, REFERENCE6, REFERENCE7, REFERENCE8, REFERENCE9, REFERENCE10, REFERENCE11, REFERENCE12, REFERENCE13, REFERENCE14, REFERENCE15, UPDATETYPE, UPDATETIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getOuId(), entity.getEmployeeNumber(), entity.getFullName(), entity.getSex(), entity.getRetireStatus(), entity.getEmployeeType(), entity.getMobileNumber(), entity.getEmail(), entity.getIsPrimaryAccount(), entity.getHrOrgCode(), entity.getOaOrgCode(), entity.getDuty(), entity.getDisplayOrder(), entity.getReference1(), entity.getReference2(), entity.getReference3(), entity.getReference4(), entity.getReference5(), entity.getReference6(), entity.getReference7(), entity.getReference8(), entity.getReference9(), entity.getReference10(), entity.getReference11(), entity.getReference12(), entity.getReference13(), entity.getReference14(), entity.getReference15(), entity.getUpdatetype(), entity.getUpdatetime());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("新增 OA用户PMS 失败。");
        }
        return result > 0;
    }

    /**
     * 更新
     */
    @Override
    public boolean update(UserPms entity) {
        String sql = "UPDATE OA_USER_PMS SET EMPLOYEE_NUMBER = ?, FULL_NAME = ?, SEX = ?, RETIRE_STATUS = ?, EMPLOYEE_TYPE = ?, MOBILE_NUMBER = ?, EMAIL = ?, IS_PRIMARY_ACCOUNT = ?, HR_ORG_CODE = ?, OA_ORG_CODE = ?, DUTY = ?, DISPLAY_ORDER = ?, REFERENCE1 = ?, REFERENCE2 = ?, REFERENCE3 = ?, REFERENCE4 = ?, REFERENCE5 = ?, REFERENCE6 = ?, REFERENCE7 = ?, REFERENCE8 = ?, REFERENCE9 = ?, REFERENCE10 = ?, REFERENCE11 = ?, REFERENCE12 = ?, REFERENCE13 = ?, REFERENCE14 = ?, REFERENCE15 = ?, UPDATETYPE = ?, UPDATETIME = ? WHERE OU_ID = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getEmployeeNumber(), entity.getFullName(), entity.getSex(), entity.getRetireStatus(), entity.getEmployeeType(), entity.getMobileNumber(), entity.getEmail(), entity.getIsPrimaryAccount(), entity.getHrOrgCode(), entity.getOaOrgCode(), entity.getDuty(), entity.getDisplayOrder(), entity.getReference1(), entity.getReference2(), entity.getReference3(), entity.getReference4(), entity.getReference5(), entity.getReference6(), entity.getReference7(), entity.getReference8(), entity.getReference9(), entity.getReference10(), entity.getReference11(), entity.getReference12(), entity.getReference13(), entity.getReference14(), entity.getReference15(), entity.getUpdatetype(), entity.getUpdatetime(), entity.getOuId());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("更新 OA用户PMS 失败。");
        }
        return result >= 0;
    }

    /**
     * 批量新增
     */
    public int[] batchInsert(List<UserPms> list) {
        String sql = "INSERT INTO OA_USER_PMS(OU_ID, EMPLOYEE_NUMBER, FULL_NAME, SEX, RETIRE_STATUS, EMPLOYEE_TYPE, MOBILE_NUMBER, EMAIL, IS_PRIMARY_ACCOUNT, HR_ORG_CODE, OA_ORG_CODE, DUTY, DISPLAY_ORDER, REFERENCE1, REFERENCE2, REFERENCE3, REFERENCE4, REFERENCE5, REFERENCE6, REFERENCE7, REFERENCE8, REFERENCE9, REFERENCE10, REFERENCE11, REFERENCE12, REFERENCE13, REFERENCE14, REFERENCE15, UPDATETYPE, UPDATETIME) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                UserPms item = list.get(i);
                ps.setObject(++j, item.getOuId());
                ps.setString(++j, item.getEmployeeNumber());
                ps.setString(++j, item.getFullName());
                ps.setString(++j, item.getSex());
                ps.setString(++j, item.getRetireStatus());
                ps.setString(++j, item.getEmployeeType());
                ps.setString(++j, item.getMobileNumber());
                ps.setString(++j, item.getEmail());
                ps.setString(++j, item.getIsPrimaryAccount());
                ps.setString(++j, item.getHrOrgCode());
                ps.setString(++j, item.getOaOrgCode());
                ps.setString(++j, item.getDuty());
                ps.setString(++j, item.getDisplayOrder());
                ps.setTimestamp(++j, item.getReference1() != null ? new Timestamp(item.getReference1().getTime()) : null);
                ps.setString(++j, item.getReference2());
                ps.setString(++j, item.getReference3());
                ps.setString(++j, item.getReference4());
                ps.setString(++j, item.getReference5());
                ps.setString(++j, item.getReference6());
                ps.setString(++j, item.getReference7());
                ps.setString(++j, item.getReference8());
                ps.setString(++j, item.getReference9());
                ps.setString(++j, item.getReference10());
                ps.setString(++j, item.getReference11());
                ps.setString(++j, item.getReference12());
                ps.setString(++j, item.getReference13());
                ps.setString(++j, item.getReference14());
                ps.setString(++j, item.getReference15());
                ps.setObject(++j, item.getUpdatetype());
                ps.setTimestamp(++j, item.getUpdatetime() != null ? new Timestamp(item.getUpdatetime().getTime()) : null);
            }

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

    /**
     * 批量更新
     */
    public int[] batchUpdate(List<UserPms> list) {
        String sql = "UPDATE OA_USER_PMS SET EMPLOYEE_NUMBER = ?, FULL_NAME = ?, SEX = ?, RETIRE_STATUS = ?, EMPLOYEE_TYPE = ?, MOBILE_NUMBER = ?, EMAIL = ?, IS_PRIMARY_ACCOUNT = ?, HR_ORG_CODE = ?, OA_ORG_CODE = ?, DUTY = ?, DISPLAY_ORDER = ?, REFERENCE1 = ?, REFERENCE2 = ?, REFERENCE3 = ?, REFERENCE4 = ?, REFERENCE5 = ?, REFERENCE6 = ?, REFERENCE7 = ?, REFERENCE8 = ?, REFERENCE9 = ?, REFERENCE10 = ?, REFERENCE11 = ?, REFERENCE12 = ?, REFERENCE13 = ?, REFERENCE14 = ?, REFERENCE15 = ?, UPDATETYPE = ?, UPDATETIME = ? WHERE OU_ID = ? ";
            int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                UserPms item = list.get(i);
                ps.setString(++j, item.getEmployeeNumber());
                ps.setString(++j, item.getFullName());
                ps.setString(++j, item.getSex());
                ps.setString(++j, item.getRetireStatus());
                ps.setString(++j, item.getEmployeeType());
                ps.setString(++j, item.getMobileNumber());
                ps.setString(++j, item.getEmail());
                ps.setString(++j, item.getIsPrimaryAccount());
                ps.setString(++j, item.getHrOrgCode());
                ps.setString(++j, item.getOaOrgCode());
                ps.setString(++j, item.getDuty());
                ps.setString(++j, item.getDisplayOrder());
                ps.setTimestamp(++j, item.getReference1() != null ? new Timestamp(item.getReference1().getTime()) : null);
                ps.setString(++j, item.getReference2());
                ps.setString(++j, item.getReference3());
                ps.setString(++j, item.getReference4());
                ps.setString(++j, item.getReference5());
                ps.setString(++j, item.getReference6());
                ps.setString(++j, item.getReference7());
                ps.setString(++j, item.getReference8());
                ps.setString(++j, item.getReference9());
                ps.setString(++j, item.getReference10());
                ps.setString(++j, item.getReference11());
                ps.setString(++j, item.getReference12());
                ps.setString(++j, item.getReference13());
                ps.setString(++j, item.getReference14());
                ps.setString(++j, item.getReference15());
                ps.setObject(++j, item.getUpdatetype());
                ps.setTimestamp(++j, item.getUpdatetime() != null ? new Timestamp(item.getUpdatetime().getTime()) : null);
                ps.setObject(++j, item.getOuId());
            }

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

    /**
     * 删除
     */
    @Override
    public boolean delete(String id) {
        String sql = "DELETE FROM OA_USER_PMS WHERE OU_ID = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, id);
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("删除 OA用户PMS 失败。");
        }
        return result > 0;
    }

    @Override
    public boolean deleteByEmployeeNumber(String employeeNumber) {
        String sql = "DELETE FROM OA_USER_PMS WHERE EMPLOYEE_NUMBER = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, employeeNumber);
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("根据 用户编码 删除 OA用户PMS 失败。");
        }
        return result > 0;
    }

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

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

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

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

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

    @Override
    public List<UserPms> selectByReference2(String reference2) {
        String sql = "select * from OA_USER_PMS where REFERENCE2 = ? ";
        try {
            return jdbcTemplate.query(sql, new UserPmsRowMapper(), reference2);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    @Override
    public List<UserPms> selectByReference3(String reference3) {
        String sql = "select * from OA_USER_PMS where REFERENCE3 = ? ";
        try {
            return jdbcTemplate.query(sql, new UserPmsRowMapper(), reference3);
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

    /**
     * RowMapper
     */
    static class UserPmsRowMapper implements RowMapper<UserPms> {
        @Override
        public UserPms mapRow(ResultSet rs, int i) throws SQLException {
            return new UserPms(
                    rs.getObject("OU_ID") != null ? rs.getLong("OU_ID") : null,
                    rs.getString("EMPLOYEE_NUMBER"),
                    rs.getString("FULL_NAME"),
                    rs.getString("SEX"),
                    rs.getString("RETIRE_STATUS"),
                    rs.getString("EMPLOYEE_TYPE"),
                    rs.getString("MOBILE_NUMBER"),
                    rs.getString("EMAIL"),
                    rs.getString("IS_PRIMARY_ACCOUNT"),
                    rs.getString("HR_ORG_CODE"),
                    rs.getString("OA_ORG_CODE"),
                    rs.getString("DUTY"),
                    rs.getString("DISPLAY_ORDER"),
                    rs.getTimestamp("REFERENCE1"),
                    rs.getString("REFERENCE2"),
                    rs.getString("REFERENCE3"),
                    rs.getString("REFERENCE4"),
                    rs.getString("REFERENCE5"),
                    rs.getString("REFERENCE6"),
                    rs.getString("REFERENCE7"),
                    rs.getString("REFERENCE8"),
                    rs.getString("REFERENCE9"),
                    rs.getString("REFERENCE10"),
                    rs.getString("REFERENCE11"),
                    rs.getString("REFERENCE12"),
                    rs.getString("REFERENCE13"),
                    rs.getString("REFERENCE14"),
                    rs.getString("REFERENCE15"),
                    rs.getObject("UPDATETYPE") != null ? rs.getInt("UPDATETYPE") : null,
                    rs.getTimestamp("UPDATETIME")
            );
        }
    }

    /**
     * 创建查询条件
     */
    private Map<String, Object> createCriteriaSql(UserPmsCriteria 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());

        //员工编号
        if (criteria.byEmployeeNumber())
            andMap.put(criteria.getEmployeeNumber() == null ? " EMPLOYEE_NUMBER IS NULL " : " EMPLOYEE_NUMBER = ? ", criteria.getEmployeeNumber());
        //是否领导Y:N
        if (criteria.byReference5())
            andMap.put(criteria.getReference5() == null ? " REFERENCE5 IS NULL " : " REFERENCE5 = ? ", criteria.getReference5());
        //变更类型（1：新增；0：修改）
        if (criteria.byUpdatetype())
            andMap.put(criteria.getUpdatetype() == null ? " UPDATETYPE IS NULL " : " UPDATETYPE = ? ", criteria.getUpdatetype());
        // 员工编号列表
        if(CollectionUtils.isNotEmpty(criteria.getEmployeeNumberList())) {
            andMap.put(OracleUtils.placeholderIn("EMPLOYEE_NUMBER", criteria.getEmployeeNumberList()), criteria.getEmployeeNumberList());
        }
        // reference3列表
        if(CollectionUtils.isNotEmpty(criteria.getReference3List())) {
            andMap.put(OracleUtils.placeholderIn("REFERENCE3", criteria.getReference3List()), criteria.getReference3List());
        }
        return andMap;
    }

}
