package com.nantian.cloud.jljc.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nantian.cloud.jljc.entity.DictRegion;
import com.nantian.cloud.jljc.entity.TDualcontrolIndex;
import com.nantian.cloud.jljc.entity.TDualcontrolProgress;
import com.nantian.cloud.jljc.entity.TDualcontrolProgressLog;
import com.nantian.cloud.jljc.mapper.TDualcontrolProgressMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nantian.cloud.jljc.service.DictRegionService;
import com.nantian.cloud.jljc.service.TDualcontrolIndexService;
import com.nantian.cloud.jljc.service.TDualcontrolProgressLogService;
import com.nantian.cloud.jljc.service.TDualcontrolProgressService;
import com.nantian.cloud.jljc.vo.dualControl.DualcontrolImpactFactorVo;
import com.nantian.cloud.jljc.vo.dualControl.DualcontrolNoDataQuarter;
import com.nantian.cloud.jljc.vo.dualControl.DualcontrolVisualizationVo;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.*;

/**
 * 能耗双控-完成情况填报 服务实现类
 */
@Service("tDualcontrolProgressService")
public class TDualcontrolProgressServiceImpl extends ServiceImpl<TDualcontrolProgressMapper, TDualcontrolProgress> implements TDualcontrolProgressService {

    @Autowired
    private TDualcontrolProgressLogService logService;
    @Autowired
    private TDualcontrolIndexService indexService;
    @Autowired
    private DictRegionService regionService;

    @Override
    public TDualcontrolProgressLog getLogById(Long id) {
        return baseMapper.getLogById(id);
    }

    @Override
    public int saveOrUpdateProgress(TDualcontrolProgress progress, ScUser u, DecimalFormat df) {
        //上个五年计划最后一年数据
        //int num = progress.getYear() % 5;
        //Integer preYear = num==0 ? progress.getYear()-5 : progress.getYear()-num;
        //取出同期数据
        Integer preYear = progress.getYear()-1;
        TDualcontrolProgress q = new TDualcontrolProgress();
        q.setItemCode(progress.getItemCode());
        q.setYear(preYear); //查询上一年数据
        q.setDelFlag("1");
        q.setQuarter("0");
        TDualcontrolProgress pre = baseMapper.selectOne(Wrappers.query(q));

        //计算单位GDP能耗、能耗增长率
        Double preEnergyUnitGdp = 0d, energyUnitGdp = 0d, energyGrowthrate = 0d;
        if (pre != null) {
            if(pre.getEnergyTotal()!=null && pre.getEnergyTotal()!=0){
                energyGrowthrate = (progress.getEnergyTotal()-pre.getEnergyTotal())/pre.getEnergyTotal();
            }
            if (pre.getEnergyTotal() != null && pre.getEnergyTotal() != 0 && pre.getGdpTotal() != null && pre.getGdpTotal() != 0) {
                preEnergyUnitGdp = pre.getEnergyTotal()/pre.getGdpTotal();
            }
        }
        energyUnitGdp = (1-progress.getEnergyUnitGdpReducerate()/100) * preEnergyUnitGdp;
        progress.setEnergyUnitGdp(Double.parseDouble(df.format(energyUnitGdp)));
        progress.setEnergyGrowthrate(Double.parseDouble(df.format(energyGrowthrate)));

        //计算GDP总量
        Double gdpTotal = 0d;
        if(energyUnitGdp!=0){
            gdpTotal = progress.getEnergyTotal() / energyUnitGdp;
        }
        progress.setGdpTotal(Double.parseDouble(df.format(gdpTotal)));

        //计算完成情况 超出目标百分点=单位GDP能耗降低率-单位GDP能耗下降目标
        Double completionBasic=0d, completionInspire=0d;
        TDualcontrolIndex index = indexService.getIndex(progress.getYear().toString(),progress.getItemCode());
        if(index!=null){
            if(index.getEnergyUnitGdpReducerateBasic()!=null && index.getEnergyUnitGdpReducerateBasic()!=0){
                completionBasic = progress.getEnergyUnitGdpReducerate() - index.getEnergyUnitGdpReducerateBasic();
            }
            if(index.getEnergyUnitGdpReducerateInspire()!=null && index.getEnergyUnitGdpReducerateInspire()!=0){
                completionInspire = progress.getEnergyUnitGdpReducerate() - index.getEnergyUnitGdpReducerateInspire();
            }
        }
        progress.setCompletionBasic(Double.parseDouble(df.format(completionBasic)));
        progress.setCompletionInspire(Double.parseDouble(df.format(completionInspire)));

        //更新完成情况数据
        int count = 0;
        progress.setUserid(u.getId());
        progress.setUpdateTime(new Date());
        progress.setUserName(u.getUserRealName());
        if(progress.getId()==null){ //新增数据
            progress.setDelFlag("1");
            //progress.setItemStatus("1"); //项目为填写状态
            //上级可填写下级数据，数据是属于本项目的，数据deptId与项目编码保持一致
            progress.setDeptId(Integer.parseInt(progress.getItemCode()));
            count = baseMapper.insert(progress); //新增完成情况
        }else{ //修改数据，需添加数据修改记录
            TDualcontrolProgressLog log = baseMapper.getLogById(progress.getId());
            log.setUserid(u.getId());
            log.setDeptId(u.getDeptId());
            log.setDelFlag("1");
            log.setUpdateTime(new Date());
            log.setGdpTotal(progress.getGdpTotal());
            log.setEnergyTotal(progress.getEnergyTotal());
            logService.save(log); //保存数据修改记录
            count = baseMapper.updateById(progress); //更新完成情况
        }
        return count;
    }

    @Override
    public TDualcontrolProgress getProgressByQuarter(TDualcontrolProgress progress) {
        return baseMapper.getProgressByQuarter(progress);
    }

    @Override
    public List<TDualcontrolProgress> listByIndex(TDualcontrolProgress progress) {
        return baseMapper.listByIndex(progress);
    }

    @Override
    public TDualcontrolProgress sumByIndex(TDualcontrolProgress progress) {
        return baseMapper.sumByIndex(progress);
    }

    public static List<DualcontrolVisualizationVo> voTmpList = new ArrayList<>(); //可视化待展示数据的州市或省合计值
    public static DualcontrolVisualizationVo voTmp = new DualcontrolVisualizationVo(); //州市或省合计数据
    public static Map<String,Object> resultMap = new HashMap<>(); //可视化返回结果

    @Override
    public Map<String,Object> visualizationList(String type, String planYear, String year, String quarter, String region) throws InterruptedException {
        //可视化界面只展示提交的数据。
        //季度和年度拿上一年度计算gdp能耗降低率等数据
        //五年计划数据拿上个五年计划最后一年数据，与本次五年计划最新年度数据计算gdp能耗降低率等数据
        //初始化查询参数
        Integer tmpYear = 0; //可视化查询年份周期
        Integer startYear = 0, endYear = 0; //未送数据年份
        Integer preYear = 0; //数据比较年份
        String regionSum = ""; //合计值所属地区
        if("1".equals(type)){ //type1 按五年计划查询
            startYear = Integer.parseInt(planYear.split("-")[0]);
            endYear = Integer.parseInt(planYear.split("-")[1]);
            List<String> yearList = baseMapper.getYearByPlan(startYear, endYear);//获取五年计划，有数据的年度
            if(yearList!=null&&yearList.size()>0){
                tmpYear = Integer.parseInt(yearList.get(0)); //取五年计划最新年度数据
            }else{
                tmpYear = startYear;  //取五年计划第一年数据
            }
            quarter = "0"; //取年度数据
            preYear = startYear - 1; //比较年，上个五年计划最后一年
        }else{ //年度或季度查询
            planYear = year; //指标年
            tmpYear = startYear = endYear = Integer.parseInt(year); //数据年
            if("2".equals(type)){ //type2 按年度查询
               quarter = "0"; //取年度数据
            }
            int num = startYear % 5;
            preYear = startYear - 1; //比较年，上一年
        }
        if (region==null || "".equals(region)) { //初始化地区为用户deptId
            region = SecurityUtils.getUser().getDeptId().toString();
        }
        if(!region.contains("00")){ //区县，合计值地区为州市
            regionSum = region.substring(4)+"00";
        }else{
            regionSum = region;
        }

        //查询待展示数据中间数据（省看州市，州市看区县，区县看本部门）
        voTmpList = baseMapper.getVisualizationVoTmp(planYear,preYear,tmpYear,tmpYear,quarter,region);
        //查询省或州市合计值中间数据
        voTmp = baseMapper.getVisualizationSumVoTmp(planYear,preYear,tmpYear,tmpYear,quarter,regionSum);
        if(voTmpList==null || voTmpList.size()<=0){
            resultMap.put("barometerFlag",true); //没有数据
        }else{
            resultMap.put("barometerFlag",false); //有数据
        }

        resultMap.put("indexYear",planYear); //指标年份
        resultMap.put("preYear",preYear); //比较年份
        resultMap.put("year",tmpYear); //数据年份

        //未送数据季度功能取消
        //getNoDataQuarterResult(quarter, region, startYear, endYear);

        //查询各地区完成情况百分点
        getCompletionResult(tmpYear,quarter,region);

        //多线程计算
        Thread th0 = new Thread(barometer); //晴雨表
        Thread th1 = new Thread(barometerRate); //晴雨表预警占比
        Thread th2 = new Thread(impactFactor); //影响因素查询
        Thread th3 = new Thread(reducerate); //gdp能耗降低率
        th0.start();
        th1.start();
        th2.start();
        th3.start();
        //等待线程执行完成
        th0.join();
        th1.join();
        th2.join();
        th3.join();
        return resultMap;
    }

    //查询各地区完成情况
    private void getCompletionResult (Integer tmpYear, String quarter, String region){
        List<TDualcontrolProgress> completionList = new ArrayList<>();
        completionList = baseMapper.getCompletionList(tmpYear.toString(),quarter,region);
        List<String[]> completionArr = new ArrayList<>();
        completionArr.add(new String[]{"product","基准值","激励值"});
        boolean completionFlag = true; //没有数据
        if(completionList!=null && completionList.size()>0){
            for (TDualcontrolProgress completion: completionList) {
                if(completion.getCompletionBasic()!=null && completion.getCompletionBasic()!=0)  completionFlag = false;
                if(completion.getCompletionInspire()!=null && completion.getCompletionInspire()!=0)  completionFlag = false;
                completionArr.add(new String[]{completion.getItemName(),completion.getCompletionBasic().toString(),completion.getCompletionInspire().toString()});
            }
        }
        resultMap.put("completionFlag",completionFlag);
        resultMap.put("completion",completionArr);
        String completionRemark = "";
        if(region.contains("00")){
            completionRemark = "云南省各州市完成情况(%)";
        }else{
            DictRegion dictRegion = regionService.getById(region.substring(0,4)+"00");
            completionRemark = (dictRegion!=null ? dictRegion.getMeaning2() : "")+"各区县完成情况(%)";
        }
        resultMap.put("completionRemark",completionRemark);
    }

    //查询未送数据季度
    private void getNoDataQuarterResult(String quarter, String region, Integer startYear, Integer endYear) {
        if(quarter.equals("0")){
            quarter = "1,2,3,4";
        }
        String[] quarterArr = quarter.split(","); //可视化查询季度
        List<DualcontrolNoDataQuarter> list = new ArrayList<>();
        for(; endYear>=startYear; endYear--){
            List<DualcontrolNoDataQuarter> tmp = baseMapper.getNoDataQuarter(endYear,quarterArr,region);
            /*for (int i = 0; i < tmp.size(); i++) {
                String quarterTmp = tmp.get(i).getQuarter().replaceAll("、、、","、").replaceAll("、、","、");
                if(quarterTmp.startsWith("、")){
                    quarterTmp = quarterTmp.substring(1); //去掉第一个字符
                }
                if(quarterTmp.endsWith("、")){
                    quarterTmp = quarterTmp.substring(0,quarterTmp.length()-1); //去掉最后一个字符
                }
                tmp.get(i).setQuarter(quarterTmp);
            }*/
            for (int i = 0; i < tmp.size(); i++) {
                tmp.get(i).setQuarterRemark();
            }
            list.addAll(tmp);
        }
        resultMap.put("noDataQuarter",list); //未送数据季度
    }


    //晴雨表预警占比
    private static Runnable barometer = new Runnable() {

        @Override
        public void run() {
            DecimalFormat df = new DecimalFormat(".00"); //保留2位小数
            for (DualcontrolVisualizationVo vo : voTmpList) {
                if(vo.getEnergyTotal()!=null&&vo.getEnergyTotal()!=0&&vo.getEnergyTotalBasic()!=null&&vo.getEnergyTotalBasic()!=0){
                    vo.setBasicLevel1(Double.parseDouble(df.format(100*vo.getEnergyTotal()/vo.getEnergyTotalBasic())));
                }
                if(vo.getEnergyTotal()!=null&&vo.getEnergyTotal()!=0&&vo.getEnergyTotalInspire()!=null&&vo.getEnergyTotalInspire()!=0){
                    vo.setInspireLevel1(Double.parseDouble(df.format(100*vo.getEnergyTotal()/vo.getEnergyTotalInspire())));
                }
            }
            resultMap.put("barometer",voTmpList); //晴雨表数据
        }
    };

    //晴雨表预警占比
    private static Runnable barometerRate = new Runnable() {
        //int[] one = new int[6], two = new int[6], three = new int[6];
        int[] one = new int[4], two = new int[4], three = new int[4], four = new int[4];

        private void level( int sub, Double num, Double index){
            if(num==null || index==null){
                four[sub] += 1; //四级预警
            }else if(num>index){
                one[sub] += 1; //一级预警
            } else if (num.equals(index)) {
                two[sub] += 1; //二级预警
            }else{ //num<index
                three[sub] += 1; //三级预警
            }
        }

        private void level2( int sub, Double num, Double index){
            if(num==null || index==null){
                four[sub] += 1; //四级预警
            }else if(num<index){
                one[sub] += 1; //一级预警
            } else if (num.equals(index)) {
                two[sub] += 1; //二级预警
            }else{ //num>index
                three[sub] += 1; //三级预警
            }
        }

        @Override
        public void run() {
            one = new int[4];
            two = new int[4];
            three = new int[4];
            four = new int[4];
            for (DualcontrolVisualizationVo vo : voTmpList) {
                //level(0, vo.getEnergyTotal(), vo.getEnergyTotalBasic()); //总量基准
                //level(1, vo.getEnergyTotal(), vo.getEnergyTotalInspire()); //总量激励
                level(0, vo.getEnergyUnitGdp(), vo.getEnergyUnitGdpBasic()); //强度基准
                level(1, vo.getEnergyUnitGdp(), vo.getEnergyUnitGdpInspire()); //强度激励
                level2(2, vo.getEnergyUnitGdpReducerate(), vo.getEnergyUnitGdpReducerateBasic()); //进度基准
                level2(3, vo.getEnergyUnitGdpReducerate(), vo.getEnergyUnitGdpReducerateInspire()); //进度激励
            }
            Map<String,Object> map = new HashMap<>();
            map.put("one",one);
            map.put("two",two);
            map.put("three",three);
            map.put("four",four);
            resultMap.put("barometerRate",map); //晴雨表预警占比
        }
    };

    //影响因素查询
    public static Runnable impactFactor = new Runnable() {

        @Override
        public void run() {
            List<DualcontrolImpactFactorVo> factorVoList = new ArrayList<>();
            //计算全省或州市数据
            Double energyTotalProportionS = 1d, compRateBasicS = 0d, compRateInspireS = 0d;
            //计算完成率
            if(voTmp!=null && voTmp.getEnergyUnitGdpReducerate()!=null && voTmp.getEnergyUnitGdpReducerateBasic()!=null && voTmp.getEnergyUnitGdpReducerateBasic()!=0){
                compRateBasicS = voTmp.getEnergyUnitGdpReducerate() / voTmp.getEnergyUnitGdpReducerateBasic();
            }
            if(voTmp!=null && voTmp.getEnergyUnitGdpReducerate()!=null && voTmp.getEnergyUnitGdpReducerateInspire()!=null && voTmp.getEnergyUnitGdpReducerateInspire()!=0){
                compRateInspireS = voTmp.getEnergyUnitGdpReducerate() / voTmp.getEnergyUnitGdpReducerateInspire();
            }
            boolean impactFactorFlag = true; //没有数据
            for (DualcontrolVisualizationVo vo : voTmpList) {
                Double energyTotalProportion = 0d, compRateBasic = 0d, compRateInspire = 0d, impactCompRateBasic = 0d, impactCompRateInspire = 0d, synthesizeRateBasic = 0d, synthesizeRateInspire = 0d;
                //计算能耗比重
                if(vo.getPreEnergyTotal()!=null && voTmp!=null && voTmp.getPreEnergyTotal()!=null && voTmp.getPreEnergyTotal()!=0d){
                    energyTotalProportion = vo.getPreEnergyTotal()/voTmp.getPreEnergyTotal();
                }
                //计算完成率
                if(vo.getEnergyUnitGdpReducerate()!=null && vo.getEnergyUnitGdpReducerateBasic()!=null && vo.getEnergyUnitGdpReducerateBasic()!=0){
                    compRateBasic = vo.getEnergyUnitGdpReducerate() / vo.getEnergyUnitGdpReducerateBasic();
                }
                if(vo.getEnergyUnitGdpReducerate()!=null && vo.getEnergyUnitGdpReducerateInspire()!=null && vo.getEnergyUnitGdpReducerateInspire()!=0){
                    compRateInspire = vo.getEnergyUnitGdpReducerate() / vo.getEnergyUnitGdpReducerateInspire();
                }
                //计算完成率影响
                if(compRateBasicS!=0){
                    impactCompRateBasic = 100 * (compRateBasic-compRateBasicS) / compRateBasicS;
                }
                if(compRateInspireS!=0){
                    impactCompRateInspire = 100 * (compRateInspire-compRateInspireS) / compRateInspireS;
                }
                //计算综合影响因素
                synthesizeRateBasic = impactCompRateBasic * energyTotalProportion;
                synthesizeRateInspire = impactCompRateInspire * energyTotalProportion;
                if(synthesizeRateBasic!=0 || synthesizeRateInspire!=0){
                    impactFactorFlag = false;
                }
                //factor.add(new String[]{vo.getItemName(),synthesizeRateBasic.toString(),synthesizeRateInspire.toString()});
                factorVoList.add(new DualcontrolImpactFactorVo(vo.getItemCode(),vo.getItemName(),energyTotalProportion,
                        compRateBasic,compRateInspire,impactCompRateBasic,impactCompRateInspire,synthesizeRateBasic,synthesizeRateInspire));
            }

            if (factorVoList.size() > 0) { //结果集大于0，进行排序
                factorVoList.sort(new Comparator<DualcontrolImpactFactorVo>() {
                    @Override
                    public int compare(DualcontrolImpactFactorVo o1, DualcontrolImpactFactorVo o2) {
                        return (int)((o2.getSynthesizeRateBasic()- o1.getSynthesizeRateBasic())*100); //从大到小
                    }
                });
            }

            List<String[]> factor = new ArrayList<>();
            factor.add(new String[]{"product","基准值","激励值"});
            for (DualcontrolImpactFactorVo factorVo : factorVoList) {
                factor.add(new String[]{factorVo.getItemName(),factorVo.getSynthesizeRateBasic().toString(),factorVo.getSynthesizeRateInspire().toString()});
            }
            resultMap.put("impactFactorFlag",impactFactorFlag);
            resultMap.put("impactFactor",factor); //影响因素
        }
    };

    //gdp能耗降低率完成情况
    public static Runnable reducerate = new Runnable() {

        @Override
        public void run() {
            List<Map<String,Object>> value = new ArrayList<>(); //数据
            List<String> head = new ArrayList<>(); //x轴名称
            List<int[]> axis = new ArrayList<>(); //坐标点
            for (int i = 0; i < voTmpList.size(); i++) {
                String item = voTmpList.get(i).getItemName();
                Double re = voTmpList.get(i).getEnergyUnitGdpReducerate();
                Map<String,Object> tmp = new HashMap<>();
                tmp.put("name",item);
                tmp.put("value",re);
                value.add(tmp);
                head.add(item);
                if(re==null || voTmpList.get(i).getEnergyUnitGdpReducerateBasic()==null || voTmpList.get(i).getEnergyUnitGdpReducerateInspire()==null){
                    //axis.add(new int[]{i,0});
                }else if(re<voTmpList.get(i).getEnergyUnitGdpReducerateBasic()){
                    axis.add(new int[]{i,1});
                }else if(re>=voTmpList.get(i).getEnergyUnitGdpReducerateBasic() && re<voTmpList.get(i).getEnergyUnitGdpReducerateInspire()){
                    axis.add(new int[]{i,3});
                }else if(re>=voTmpList.get(i).getEnergyUnitGdpReducerateInspire()){
                    axis.add(new int[]{i,5});
                }
            }
            Map<String,Object> map = new HashMap<>();
            map.put("name",head);
            map.put("axis",axis);
            map.put("value",value);
            resultMap.put("reducerate",map); //gdp能耗降低率完成情况
        }
    };
}
