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

import com.infoepoch.pms.dispatchassistant.common.exception.ValidationException;
import com.infoepoch.pms.dispatchassistant.common.utils.DateTool;
import com.infoepoch.pms.dispatchassistant.common.utils.OracleUtils;
import com.infoepoch.pms.dispatchassistant.common.utils.StringUtils;
import com.infoepoch.pms.dispatchassistant.domain.system.moaLog.*;
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;

/**
 * MOA日志记录表仓储实现
 */
@Repository
public class MoaLogRepository implements IMoaLogRepository {

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

    /**
     * 新增
     */
    @Override
    public boolean insert(MoaLog entity) {
        String sql = "INSERT INTO SYS_MOA_LOG(ML_ID, ML_TYPE, ML_BUSINESS_MODULE, ML_URL, ML_ACTION_FLAG, ML_CREATE_TIME, ML_USER_ID, ML_USER_NAME,ML_DOMAIN_ID,ML_STAGE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getId(), entity.getType(), entity.getBusinessModule(), entity.getUrl(),
                    entity.getActionFlag(), entity.getCreateTime(), entity.getUserId(), entity.getUserName(), entity.getDomainId(),
                    entity.getStage());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("新增 MOA日志记录表 失败。");
        }
        return result > 0;
    }

    /**
     * 更新
     */
    @Override
    public boolean update(MoaLog entity) {
        String sql = "UPDATE SYS_MOA_LOG SET ML_TYPE = ?, ML_BUSINESS_MODULE = ?, ML_URL = ?, ML_ACTION_FLAG = ?, ML_CREATE_TIME = ?, ML_USER_ID = ?, ML_USER_NAME = ?, ML_DOMAIN_ID = ?, ML_STAGE = ? WHERE ML_ID = ?";
        int result;
        try {
            result = jdbcTemplate.update(sql, entity.getType(), entity.getBusinessModule(), entity.getUrl(), entity.getActionFlag(),
                    entity.getCreateTime(), entity.getUserId(), entity.getUserName(), entity.getDomainId(), entity.getStage(),
                    entity.getId());
        } catch (Exception e) {
            logger.info(e.getMessage());
            throw new ValidationException("更新 MOA日志记录表 失败。");
        }
        return result >= 0;
    }

    /**
     * 批量新增
     */
    public int[] batchInsert(List<MoaLog> list) {
        String sql = "INSERT INTO SYS_MOA_LOG(ML_ID, ML_TYPE, ML_BUSINESS_MODULE, ML_URL, ML_ACTION_FLAG, ML_CREATE_TIME, ML_USER_ID, ML_USER_NAME,ML_DOMAIN_ID,ML_STAGE) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                MoaLog item = list.get(i);
                ps.setString(++j, item.getId());
                ps.setString(++j, item.getType());
                ps.setString(++j, item.getBusinessModule());
                ps.setString(++j, item.getUrl());
                ps.setBoolean(++j, item.getActionFlag());
                ps.setTimestamp(++j, item.getCreateTime() != null ? new Timestamp(item.getCreateTime().getTime()) : null);
                ps.setString(++j, item.getUserId());
                ps.setString(++j, item.getUserName());
                ps.setString(++j, item.getDomainId());
                ps.setString(++j, item.getStage());
            }

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

    /**
     * 批量更新
     */
    public int[] batchUpdate(List<MoaLog> list) {
        String sql = "UPDATE SYS_MOA_LOG SET ML_TYPE = ?, ML_BUSINESS_MODULE = ?, ML_URL = ?, ML_ACTION_FLAG = ?, ML_CREATE_TIME = ?, ML_USER_ID = ?, ML_USER_NAME = ?, ML_DOMAIN_ID = ?, ML_STAGE = ? WHERE ML_ID = ?";
        int[] result = jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
            @Override
            public void setValues(PreparedStatement ps, int i) throws SQLException {
                int j = 0;
                MoaLog item = list.get(i);
                ps.setString(++j, item.getType());
                ps.setString(++j, item.getBusinessModule());
                ps.setString(++j, item.getUrl());
                ps.setBoolean(++j, item.getActionFlag());
                ps.setTimestamp(++j, item.getCreateTime() != null ? new Timestamp(item.getCreateTime().getTime()) : null);
                ps.setString(++j, item.getUserId());
                ps.setString(++j, item.getUserName());
                ps.setString(++j, item.getDomainId());
                ps.setString(++j, item.getStage());
                ps.setString(++j, item.getId());
            }

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

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

    /**
     * 根据Id查询
     */
    @Override
    public MoaLog selectById(String id) {
        String sql = "SELECT * FROM SYS_MOA_LOG WHERE ML_ID = ? ";
        try {
            return jdbcTemplate.queryForObject(sql, new MoaLogRowMapper(), id);
        } catch (EmptyResultDataAccessException e) {
            logger.info(e.getMessage());
            return null;
        }
    }

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

    /**
     * 根据查询条件查询对象集合
     */
    @Override
    public List<MoaLog> selectByCriteria(MoaLogCriteria criteria) {
        StringBuffer buffer = new StringBuffer("SELECT * FROM SYS_MOA_LOG ");
        List<Object> list = OracleUtils.combinationSql(buffer, createCriteriaSql(criteria),"ML_CREATE_TIME", true);
        try {
            return jdbcTemplate.query(buffer.toString(), new MoaLogRowMapper(), list.toArray());
        } catch (EmptyResultDataAccessException e) {
            logger.info(e.getMessage());
            return null;
        }
    }

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

    /**
     * 根据条件查询对象总记录数
     */
    @Override
    public int selectCountByCriteria(MoaLogCriteria criteria) {
        StringBuffer buffer = new StringBuffer("SELECT COUNT(*) FROM SYS_MOA_LOG ");
        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 MoaLogRowMapper implements RowMapper<MoaLog> {
        @Override
        public MoaLog mapRow(ResultSet rs, int i) throws SQLException {
            return new MoaLog(
                    rs.getString("ML_ID"),
                    rs.getString("ML_TYPE"),
                    rs.getString("ML_BUSINESS_MODULE"),
                    rs.getString("ML_URL"),
                    rs.getObject("ML_ACTION_FLAG") != null ? rs.getBoolean("ML_ACTION_FLAG") : null,
                    rs.getTimestamp("ML_CREATE_TIME"),
                    rs.getString("ML_USER_ID"),
                    rs.getString("ML_USER_NAME"),
                    rs.getString("ML_DOMAIN_ID"),
                    rs.getString("ML_STAGE")
            );
        }
    }

    /**
     * 创建查询条件
     */
    private Map<String, Object> createCriteriaSql(MoaLogCriteria 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.byType())
            andMap.put(criteria.getType() == null ? " ML_TYPE IS NULL " : " ML_TYPE = ? ", criteria.getType());
        //业务模块
        if (criteria.byBusinessModule())
            andMap.put(criteria.getBusinessModule() == null ? " ML_BUSINESS_MODULE IS NULL " : " ML_BUSINESS_MODULE = ? ", criteria.getBusinessModule());
        //业务模块（LIKE）
        if (criteria.byBusinessModuleContain())
            andMap.put(" ML_BUSINESS_MODULE LIKE ? ", "%" + criteria.getBusinessModuleContain() + "%");
        //url地址（LIKE）
        if (criteria.byUrlContain())
            andMap.put(" ML_URL LIKE ? ", "%" + criteria.getUrlContain() + "%");
        //处理标识：1-处理成功 0-处理失败
        if (criteria.byActionFlag())
            andMap.put(criteria.getActionFlag() == null ? " ML_ACTION_FLAG IS NULL " : " ML_ACTION_FLAG = ? ", criteria.getActionFlag());
        //当前登录用户ID
        if (criteria.byUserId())
            andMap.put(criteria.getUserId() == null ? " ML_USER_ID IS NULL " : " ML_USER_ID = ? ", criteria.getUserId());
        //当前登录用户名称
        if (criteria.byUserName())
            andMap.put(criteria.getUserName() == null ? " ML_USER_NAME IS NULL " : " ML_USER_NAME = ? ", criteria.getUserName());
        //当前登录用户名称（LIKE）
        if (criteria.byUserNameContain())
            andMap.put(" ML_USER_NAME LIKE ? ", "%" + criteria.getUserNameContain() + "%");
        // domainId
        if (StringUtils.isNotBlank(criteria.getDomainId())) {
            andMap.put(" ML_DOMAIN_ID = ? ", criteria.getDomainId());
        }
        // 流程步骤
        if (StringUtils.isNotBlank(criteria.getStage())) {
            andMap.put(" ML_STAGE = ?", criteria.getStage());
        }
        // 创建时间
        if(criteria.getCreateTime() != null) {
            andMap.put(" TO_CHAR(ML_CREATE_TIME, 'YYYY-MM-DD') = ? ", DateTool.formatDate(criteria.getCreateTime()));
        }
        return andMap;
    }

}
