package com.rongwei.sfcommon.sys.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.hash.Hash32;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.rongwe.scentity.domian.WarnLevelDo;
import com.rongwei.rwcommon.utils.JdbcUtil;
import com.rongwei.rwcommon.utils.SecurityUtil;
import com.rongwei.rwcommon.vo.JdbcConnectVo;
import com.rongwei.rwcommon.vo.SqlColumn;
import com.rongwei.sfcommon.sys.dao.AccidentDao;
import com.rongwei.sfcommon.sys.dao.DataXApiDao;
import com.rongwei.sfcommon.sys.service.DataXApiService;
import com.rongwei.sfcommon.sys.service.WarnLevelService;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class DataXApiServiceImpl implements DataXApiService {

    @Autowired
    private AccidentDao accidentDao;
    @Autowired
    private WarnLevelService warnLevelService;
    @Autowired
    private DataXApiDao dataXApiDao;

    /**
     * 大屏预警灯显示接口
     *
     * @return
     */
    @Override
    public Integer getWarnLevel() {
        /**
         * 以下指标都有4个预警等级
         * green:绿色 1
         * orange:橙色 2
         * yellow:黄色 3
         * red:红色 4
         */
        // 最终预警灯等级
        Integer warnLevel = 1;
        // 告警指标数
        List<Integer> warnQuato = new ArrayList<>();
        // 本年度任务整改率
        setTaskQuato(warnQuato);
        // 安全培训完成率
        setTrainRateLevel(warnQuato);
        // 应急演练
        setEmergencyLevel(warnQuato);
        // 月累计安全事故指标
        setAccidentCountLevel(warnQuato);
        // 点检完成率
        setCheckRateLevel(warnQuato);

        // 汇总计算总告警等级
        // 预警指标大于等于3时显示预警指示灯
        if (warnQuato.size() >= 3) {
            warnLevel = 2;
            // 查询是否有同等级个数大于等于3的等级
            boolean hasThreeLevel = false;
            List<List<Integer>> t = CollUtil.group(warnQuato, new Hash32<Integer>() {
                @Override
                public int hash32(Integer integer) {
                    return integer;
                }
            });
            if (t != null && t.size() > 0) {
                for (List<Integer> v : t) {
                    if (v != null && v.size() >= 3 && warnLevel < v.get(0)) {
                        hasThreeLevel = true;
                        warnLevel = v.get(0);
                    }
                }
            }
            // 没有相同等级个数大于等于3的则去最小等级
            if (!hasThreeLevel) {
                Integer minLevel = CollUtil.min(warnQuato);
                if (minLevel > warnLevel) {
                    warnLevel = minLevel;
                }
            }
        }
        // 最终结果保存到数据库
        LambdaUpdateWrapper<WarnLevelDo> updateEmpWrapper = new LambdaUpdateWrapper<>();
        updateEmpWrapper.eq(WarnLevelDo::getIslast, "Y").setSql("islast='N'");
        warnLevelService.update(updateEmpWrapper);
        WarnLevelDo insertDo = new WarnLevelDo();
        insertDo.setId(SecurityUtil.getUUID());
        insertDo.setIslast("Y");
        insertDo.setWarnlevel(warnLevel);
        warnLevelService.save(insertDo);
        return warnLevel;
    }

    /**
     * 本年度任务整改率
     *
     * @param warnQuato
     */
    private void setTaskQuato(List<Integer> warnQuato) {
        Integer taskQuato = 1;
        Map<String, Object> taskMap = accidentDao.getDataXTaskQuato();
        if (taskMap != null) {
            Long zdcount = (Long) taskMap.get("ZDCOUNT");//重大任务总数
            BigDecimal rerate = (BigDecimal) taskMap.get("RERATE");//任务及时整改率
            if (rerate != null && rerate.doubleValue() < 0.7) {
                taskQuato = 4;
            } else if (rerate != null && rerate.doubleValue() < 0.8) {
                taskQuato = 3;
            } else if ((rerate != null && rerate.doubleValue() < 0.9) || (zdcount != null && zdcount > 0)) {
                taskQuato = 2;
            }
            if (taskQuato > 1) {
                warnQuato.add(taskQuato);
            }
        }
    }

    /**
     * 安全培训完成率
     *
     * @param warnQuato
     */
    private void setTrainRateLevel(List<Integer> warnQuato) {
        Integer trainRateLevel = 1;
        Map<String, BigDecimal> trainMap = accidentDao.getDataXtrainRate();
        if (trainMap != null) {
            BigDecimal trainrate = trainMap.get("TRAINRATE");//安全培训完成率
            if (trainrate != null && trainrate.doubleValue() < 0.7) {
                trainRateLevel = 4;
            } else if (trainrate != null && trainrate.doubleValue() < 0.8) {
                trainRateLevel = 3;
            } else if (trainrate != null && trainrate.doubleValue() < 0.9) {
                trainRateLevel = 2;
            }
            if (trainRateLevel > 1) {
                warnQuato.add(trainRateLevel);
            }
        }
    }

    /**
     * 应急演练
     *
     * @param warnQuato
     */
    private void setEmergencyLevel(List<Integer> warnQuato) {
        Integer emergencyLevel = 1;
        List<Map<String, Object>> emeMaps = accidentDao.getDataXEmergency();
        if (emeMaps != null && emeMaps.size() > 0) {
            for (Map<String, Object> v : emeMaps) {
                if (v != null) {
                    Date date = (Date) v.get("PLANNEDENDTIME");
                    Date now = new Date();
                    if (DateUtil.compare(date, now) < 0) {
                        if (DateUtil.betweenMonth(date, now, false) > 2) {
                            emergencyLevel = 4;
                        } else if (DateUtil.betweenMonth(date, now, false) > 1) {
                            if (emergencyLevel < 4) {
                                emergencyLevel = 3;
                            }
                        } else if (DateUtil.betweenMonth(date, now, false) > 0) {
                            if (emergencyLevel < 3) {
                                emergencyLevel = 2;
                            }
                        }
                    }
                }
            }
        }
        if (emergencyLevel > 1) {
            warnQuato.add(emergencyLevel);
        }
    }

    /**
     * 月累计安全事故指标
     *
     * @param warnQuato
     */
    private void setAccidentCountLevel(List<Integer> warnQuato) {
        Integer accidentCountLevel = 1;
        // 可记录事故
        Map<String, Long> kjlAccidentMaps = accidentDao.getDataXKjlAccident("'3','4','5'");
        Long kjlaccidentcount = 0L;
        if (kjlAccidentMaps != null) {
            kjlaccidentcount = kjlAccidentMaps.get("ACCIDENTCOUNT");
        }
        // 总数
        Map<String, Long> totalAccidentMaps = accidentDao.getDataXKjlAccident(null);
        Long totalaccidentcount = 0L;
        if (totalAccidentMaps != null) {
            totalaccidentcount = totalAccidentMaps.get("ACCIDENTCOUNT");
        }
        if ((kjlaccidentcount != null && kjlaccidentcount > 3) || (totalaccidentcount != null && totalaccidentcount > 8)) {
            accidentCountLevel = 4;
        } else if ((kjlaccidentcount != null && kjlaccidentcount > 2) || (totalaccidentcount != null && totalaccidentcount > 6)) {
            accidentCountLevel = 3;
        } else if ((kjlaccidentcount != null && kjlaccidentcount > 1) || (totalaccidentcount != null && totalaccidentcount > 5)) {
            accidentCountLevel = 2;
        }
        if (accidentCountLevel > 1) {
            warnQuato.add(accidentCountLevel);
        }
    }

    /**
     * 点检完成率
     *
     * @param warnQuato
     */
    private void setCheckRateLevel(List<Integer> warnQuato) {
        Integer checkRateLevel = 1;
        Map<String, Double> checkMaps = accidentDao.getDataXPointCheck();
        if (checkMaps != null) {
            Double haschecknum = checkMaps.get("HASCHECKNUM");
            if (haschecknum != null) {
                if (haschecknum < 0.7) {
                    checkRateLevel = 4;
                } else if (haschecknum < 0.8) {
                    checkRateLevel = 3;
                } else if (haschecknum < 0.9) {
                    checkRateLevel = 2;
                }
            }
            if (checkRateLevel > 1) {
                warnQuato.add(checkRateLevel);
            }
        }
    }

    /**
     * 外网数据同步到内网数据
     * 定时增量数据同步,根据修改日期同步昨天数据
     */
    public void outDataSyn() {
        JdbcUtil jdbcUtil = new JdbcUtil();
        List<String> tableNames = new ArrayList<>();
//        tableNames.add("asp_accident");// 测试代码
        if (tableNames != null && tableNames.size() > 0) {
            for (String tableName : tableNames) {
                JdbcConnectVo jdbcConnect = createSqlServerDb();
                jdbcConnect.setJdbcSql("select * from OPENQUERY(TESTING,'select * from " + tableName + "')");
//                jdbcConnect.setJdbcSql("select * from " + tableName);
                ResultSet resultSet = jdbcUtil.getResultSet(jdbcConnect, null);
                ResultSetMetaData rsmd = null;
                try {
                    rsmd = resultSet.getMetaData();
                    while (resultSet.next()) {
                        // 主键值
                        String id = null;
                        //拼接insert语句
                        StringBuilder sbColumn = new StringBuilder("INSERT INTO ");
                        sbColumn.append(tableName).append("(");
                        StringBuilder sbValues = new StringBuilder(" VALUES(");
                        // 拼接update语句
                        StringBuilder updateSb = new StringBuilder("UPDATE ");
                        updateSb.append(tableName).append(" SET ");
                        // 循环拼接SQL语句
                        for (int i = 0; i < rsmd.getColumnCount(); i++) {
                            // sql拼接
                            String columnLabel = rsmd.getColumnLabel(i + 1);
                            Object columnValue = resultSet.getObject(columnLabel);
                            // 取主键值
                            if ("ID".equals(columnLabel)) {
                                id = columnValue.toString();
                            }
                            // insert语句拼接
                            if (i == 0) {
                                sbColumn.append(columnLabel);
                            } else {
                                sbColumn.append(",").append(columnLabel);
                            }

                            if (i > 0) {
                                sbValues.append(",");
                            }
                            if (columnValue == null) {
                                sbValues.append("NULL");
                            } else {
                                sbValues.append("'").append(columnValue.toString()).append("'");
                            }
                            // update语句拼接
                            updateSb.append(columnLabel).append(" = ");
                            if (columnValue == null) {
                                updateSb.append("NULL");
                            } else {
                                updateSb.append("'").append(columnValue).append("'");
                            }
                        }
                        // 新增数据
                        String inserSql = sbColumn.append(")").append(sbValues).append(")").toString();
                        // 更新数据
                        String updateSql = updateSb.append(" WHERE ID = '").append(id).append("'").toString();
                        // 根据ID查询判断数据库是否存在如存在则更新数据
                        String selectSql = "select * from " + tableName + " where ID='" + id + "'";
                        Map<String, Object> seMap = dataXApiDao.selectByTableNameId(selectSql);
                        if (seMap != null && seMap.size() > 0) {
                            // 存在当前数据则更新
                            dataXApiDao.updateDataSyn(updateSql);
                        } else {
                            // 不存在当前数据则新增
                            dataXApiDao.addDataSyn(inserSql);
                        }
                    }
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }

    /**
     * 新增数据同步
     *
     * @param tableName
     */
    private void addDataSyn(String tableName) {

    }

    /**
     * SQLserver驱动连接配置
     *
     * @return
     */
    private JdbcConnectVo createSqlServerDb() {
        JdbcConnectVo jc = new JdbcConnectVo();
        jc.setJdbcDriver("com.microsoft.sqlserver.jdbc.SQLServerDriver");
        jc.setJdbcUrl("jdbc:sqlserver://localhost:1433;DatabaseName=tempdb");
        jc.setJdbcUser("");
        jc.setJdbcPassword("");
        /*jc.setJdbcDriver("com.mysql.jdbc.Driver");
        jc.setJdbcUrl("jdbc:mysql://192.168.0.29:3306/ai_security_platform?useUnicode=true&characterEncoding=UTF8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true");
        jc.setJdbcUser("root");
        jc.setJdbcPassword("rootsasa");*/

        return jc;
    }
}
