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

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nantian.cloud.jljc.entity.DictRegion;
import com.nantian.cloud.jljc.entity.TDualcontrolIndexresolve;
import com.nantian.cloud.jljc.entity.TDualcontrolParam;
import com.nantian.cloud.jljc.mapper.TDualcontrolIndexresolveMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nantian.cloud.jljc.service.DictRegionService;
import com.nantian.cloud.jljc.service.TDualcontrolIndexresolveService;
import com.nantian.cloud.jljc.service.TDualcontrolParamService;
import com.nantian.cloud.jljc.vo.dualControl.DualcontrolIndexDataSourceVo;
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.text.SimpleDateFormat;
import java.util.*;

/**
 * 能耗双控-指标分解计算 服务实现类
 */
@Service("tDualcontrolIndexresolveService")
public class TDualcontrolIndexresolveServiceImpl extends ServiceImpl<TDualcontrolIndexresolveMapper, TDualcontrolIndexresolve> implements TDualcontrolIndexresolveService {

    @Autowired
    private TDualcontrolParamService paramService;
    @Autowired
    private DictRegionService regionService;

    @Override
    public  Map<String,Object> initializeIndexData(String type, String planYear, Long versionId) {
        Long tmpVersionId = versionId;
        Map<String,Object> resultMap = new HashMap<>();
        Integer deptId = SecurityUtils.getUser().getDeptId();

        SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy");
        Calendar calendar = Calendar.getInstance();
        String preYear = sdf1.format(calendar.getTime());
        if(!preYear.equals(planYear.split("-")[0])){
            calendar.add(Calendar.YEAR, -1);
            preYear = sdf1.format(calendar.getTime());
        }
        resultMap.put("preYear",preYear);

        TDualcontrolIndexresolve q = new TDualcontrolIndexresolve();
        q.setDeptId(deptId);
        q.setYear(planYear);
        q.setIndexType(type);
        q.setVersionId(versionId);
        List<TDualcontrolIndexresolve> tmpList = baseMapper.selectList(Wrappers.query(q));
        if(tmpList==null || tmpList.size()==0){ //当前版本没有数据，查找上一版本
            //查询历史版本
            QueryWrapper<TDualcontrolParam> q1 = new QueryWrapper<>();
            q1.eq("del_flag","1");
            q1.eq("type","0"); //查询版本信息
            q1.eq("dept_id",deptId);
            q1.eq("year",planYear);
            q1.orderByDesc("update_time");
            List<TDualcontrolParam> version = paramService.list(q1);
            a:for (TDualcontrolParam v : version) {
                q.setVersionId(v.getId());
                tmpList = baseMapper.selectList(Wrappers.query(q));
                if(tmpList!=null && tmpList.size()>0){ //这个版本有数据
                    versionId = v.getId();
                    break a;
                }
            }
        }

        //tmpVersionId 为当前版本，当前版本一定有参数信息
        //versionId 为当前版本或历史版本
        //上一年度统计值与预测值
        Integer num = Integer.parseInt(preYear)%5 == 0 ? 5 : Integer.parseInt(preYear)%5;
        List<DualcontrolIndexDataSourceVo> dataSourceVos = baseMapper.getIndexDataSource(deptId,planYear,preYear,num,versionId,type,tmpVersionId);
        //查询各年度单位GDP能耗降低率
        List<TDualcontrolIndexresolve> indexresolves = baseMapper.getIndexReducerate(deptId,planYear,versionId,type,tmpVersionId);
        //查询指标分解计算结果
        List<TDualcontrolIndexresolve> indexresolvesResult = baseMapper.getIndexResult(deptId,planYear,versionId,type,tmpVersionId);

        //初始化数据
        if(dataSourceVos==null || dataSourceVos.size()==0){
            dataSourceVos = baseMapper.initializeDataSource(deptId,planYear,preYear,versionId,tmpVersionId);
        }
        if(indexresolves==null || indexresolves.size()==0){
            indexresolves = baseMapper.initializeIndexReducerate(deptId,planYear,versionId,tmpVersionId);
        }

        //分档
        List<DualcontrolIndexDataSourceVo> newDataSource = new ArrayList<>();
        List<TDualcontrolIndexresolve> newIndex = new ArrayList<>();
        List<TDualcontrolIndexresolve> newResult = new ArrayList<>();
        if(dataSourceVos!=null && dataSourceVos.size()>0){
            for (int i = 0; i < dataSourceVos.size(); i++) {
                if(i!=0 && !dataSourceVos.get(i).getGearCode().equals(dataSourceVos.get(i-1).getGearCode())){
                    DualcontrolIndexDataSourceVo vo = new DualcontrolIndexDataSourceVo();
                    vo.setGearCode("-1");
                    newDataSource.add(vo); //添加分档线
                }
                newDataSource.add(dataSourceVos.get(i));
            }
        }
        if (indexresolves != null && indexresolves.size() > 0) {
            for (int i = 0; i < indexresolves.size(); i++) {
                if(i!=0 && !indexresolves.get(i).getGearCode().equals(indexresolves.get(i-1).getGearCode())){
                    TDualcontrolIndexresolve vo = new TDualcontrolIndexresolve();
                    vo.setGearCode("-1");
                    newIndex.add(vo); //添加分档线
                }
                if(!tmpVersionId.equals(versionId)){ //取的是历史版本数据
                    indexresolves.get(i).setId(null);
                    indexresolves.get(i).setVersionId(null);
                }
                newIndex.add(indexresolves.get(i));
            }
        }
        if (indexresolvesResult != null && indexresolvesResult.size() > 0) {
            indexresolvesResult.get(0).setItemName(indexresolvesResult.get(0).getItemName()+"（合计值）");
            TDualcontrolIndexresolve vo = new TDualcontrolIndexresolve();
            vo.setGearCode("-1");
            newResult.add(vo); //添加分档线
            for (int i = 0; i < indexresolvesResult.size(); i++) {
                if(i!=0 && !indexresolvesResult.get(i).getGearCode().equals(indexresolvesResult.get(i-1).getGearCode())){
                    newResult.add(vo); //添加分档线
                }
                if(!tmpVersionId.equals(versionId)){ //取的是历史版本数据
                    indexresolvesResult.get(i).setId(null);
                    indexresolvesResult.get(i).setVersionId(null);
                }
                newResult.add(indexresolvesResult.get(i));
            }
        }

        resultMap.put("dataSource",newDataSource);
        resultMap.put("index",newIndex);
        resultMap.put("result",newResult);
        return resultMap;
    }

    @Override
    public List<TDualcontrolIndexresolve> calculateIndex(String str) {
        JSONObject json = JSONObject.parseObject(str);
        String preYear = JSONArray.parseObject(json.getString("preYear"), String.class);
        String indexType = JSONArray.parseObject(json.getString("indexType"), String.class); //指标类型，1基准值 2激励值
        String dataType = JSONArray.parseObject(json.getString("dataType"), String.class); //数据类型，1预测值 2统计值
        TDualcontrolParam version = JSONArray.parseObject(json.getString("version"), TDualcontrolParam.class);
        List<TDualcontrolIndexresolve> dataList = (List<TDualcontrolIndexresolve>) JSONArray.parseArray(json.getString("data"), TDualcontrolIndexresolve.class);
        List<DualcontrolIndexDataSourceVo> dataSourceList = (List<DualcontrolIndexDataSourceVo>) JSONArray.parseArray(json.getString("dataSource"), DualcontrolIndexDataSourceVo.class);

        //保留2位小数
        DecimalFormat df = new DecimalFormat(".00"); //保留2位小数
        //获取用户部门
        Integer deptId = SecurityUtils.getUser().getDeptId();
        //取出本部门数据
        TDualcontrolIndexresolve indexAccont = dataList.get(0);
        if(!indexAccont.getItemCode().equals(deptId.toString())){
            a:for (TDualcontrolIndexresolve data : dataList) {
                if(data.getItemCode().equals(deptId.toString())){
                    data.setItemName(data.getItemName()+"（合计值）");
                    indexAccont = data;
                    break a;
                }
            }
        }else{
            dataList.get(0).setItemName(dataList.get(0).getItemName()+"（合计值）");
        }
        //选择数据源的年度
        Integer num = Integer.parseInt(preYear)%5 == 0 ? 5 : Integer.parseInt(preYear)%5;
        //各档位指标
        Map<String,Double> gearData = new HashMap<>();
        //求和验算
        Double preGdpTotalSum=0d, preEnergyTotalSum=0d, preEnergyUnitGdpSum=0d, gdpTotalProportionSum=0d, energyTotalProportionSum=0d, comprehensiveWeightSum=0d;
        Double gdpTotal1Sum=0d, energyTotal1Sum=0d, energyUnitGdp1Sum=0d;
        Double gdpTotal2Sum=0d, energyTotal2Sum=0d, energyUnitGdp2Sum=0d;
        Double gdpTotal3Sum=0d, energyTotal3Sum=0d, energyUnitGdp3Sum=0d;
        Double gdpTotal4Sum=0d, energyTotal4Sum=0d, energyUnitGdp4Sum=0d;
        Double gdpTotal5Sum=0d, energyTotal5Sum=0d, energyUnitGdp5Sum=0d;
        Double amountGdpTotalSum=0d, amountEnergyTotalSum=0d, amountEnergyUnitGdpSum=0d, amountEnergyUnitGdpReducerateSum=0d;

        for (int i = 0; i < dataList.size(); i++) {
            //各地区指标计算
            Double energyUnitGdpReducerate1=0d, energyGrowthrate1=0d, gdpTotal1=0d, energyTotal1=0d, energyUnitGdp1=0d;
            Double energyUnitGdpReducerate2=0d, energyGrowthrate2=0d, gdpTotal2=0d, energyTotal2=0d, energyUnitGdp2=0d;
            Double energyUnitGdpReducerate3=0d, energyGrowthrate3=0d, gdpTotal3=0d, energyTotal3=0d, energyUnitGdp3=0d;
            Double energyUnitGdpReducerate4=0d, energyGrowthrate4=0d, gdpTotal4=0d, energyTotal4=0d, energyUnitGdp4=0d;
            Double energyUnitGdpReducerate5=0d, energyGrowthrate5=0d, gdpTotal5=0d, energyTotal5=0d, energyUnitGdp5=0d;
            Double amountGdpTotal=0d, amountEnergyTotal=0d, amountEnergyUnitGdp=0d, amountEnergyUnitGdpReducerate=0d;

            TDualcontrolIndexresolve data = dataList.get(i);
            DualcontrolIndexDataSourceVo dataSource = dataSourceList.get(i);
            if(!"-1".equals(data.getGearCode())){ //分档线不参与计算

                if("2".equals(dataType)){ //用统计值
                    if(num==1){
                        energyUnitGdpReducerate1 = dataSource.getEnergyUnitGdpReducerate2()/100;
                        energyGrowthrate1 = dataSource.getEnergyGrowthrate2()/100;
                        gdpTotal1 = dataSource.getGdpTotal2();
                        energyTotal1 = dataSource.getGdpTotal2();
                    }else if(num==2){
                        energyUnitGdpReducerate2 = dataSource.getEnergyUnitGdpReducerate2()/100;
                        energyGrowthrate2 = dataSource.getEnergyGrowthrate2()/100;
                        gdpTotal2 = dataSource.getGdpTotal2();
                        energyTotal2 = dataSource.getGdpTotal2();
                    }else if(num==3){
                        energyUnitGdpReducerate3 = dataSource.getEnergyUnitGdpReducerate2()/100;
                        energyGrowthrate3 = dataSource.getEnergyGrowthrate2()/100;
                        gdpTotal3 = dataSource.getGdpTotal2();
                        energyTotal3 = dataSource.getGdpTotal2();
                    }else if(num==4){
                        energyUnitGdpReducerate4 = dataSource.getEnergyUnitGdpReducerate2()/100;
                        energyGrowthrate4 = dataSource.getEnergyGrowthrate2()/100;
                        gdpTotal4 = dataSource.getGdpTotal2();
                        energyTotal4 = dataSource.getGdpTotal2();
                    }else if(num==5){
                        energyUnitGdpReducerate5 = dataSource.getEnergyUnitGdpReducerate2()/100;
                        energyGrowthrate5 = dataSource.getEnergyGrowthrate2()/100;
                        gdpTotal5= dataSource.getGdpTotal2();
                        energyTotal5 = dataSource.getGdpTotal2();
                    }
                }

                //第1年指标计算
                if(energyUnitGdpReducerate1==0d){
                    energyGrowthrate1 =  (1+data.getAverageGrowthrate()/100)*(1-data.getEnergyUnitGdpReducerate1()/100)-1;
                    gdpTotal1 = data.getPreGdpTotal()*Math.pow((1+data.getAverageGrowthrate()/100),1);
                    energyTotal1 = data.getPreEnergyTotal()*(1+energyGrowthrate1);
                }
                energyUnitGdp1 = energyTotal1/gdpTotal1;

                //第2年指标计算
                if(energyUnitGdpReducerate2==0d){
                    energyGrowthrate2 =  (1+data.getAverageGrowthrate()/100)*(1-data.getEnergyUnitGdpReducerate2()/100)-1;
                    gdpTotal2 = data.getPreGdpTotal()*Math.pow((1+data.getAverageGrowthrate()/100),2);
                    energyTotal2 = data.getPreEnergyTotal()*(1+energyGrowthrate1)*(1+energyGrowthrate2);
                }
                energyUnitGdp2 = energyTotal2/gdpTotal2;

                //第3年指标计算
                if(energyUnitGdpReducerate3==0d){
                    energyGrowthrate3 =  (1+data.getAverageGrowthrate()/100)*(1-data.getEnergyUnitGdpReducerate3()/100)-1;
                    gdpTotal3 = data.getPreGdpTotal()*Math.pow((1+data.getAverageGrowthrate()/100),3);
                    energyTotal3 = data.getPreEnergyTotal()*(1+energyGrowthrate1)*(1+energyGrowthrate2)*(1+energyGrowthrate3);
                }
                energyUnitGdp3 = energyTotal3/gdpTotal3;

                //第4年指标计算
                if(energyUnitGdpReducerate4==0d){
                    energyGrowthrate4 =  (1+data.getAverageGrowthrate()/100)*(1-data.getEnergyUnitGdpReducerate4()/100)-1;
                    gdpTotal4 = data.getPreGdpTotal()*Math.pow((1+data.getAverageGrowthrate()/100),4);
                    energyTotal4 = data.getPreEnergyTotal()*(1+energyGrowthrate1)*(1+energyGrowthrate2)*(1+energyGrowthrate3)*(1+energyGrowthrate4);
                }
                energyUnitGdp4 = energyTotal4/gdpTotal4;

                //第5年指标计算
                if(energyUnitGdpReducerate5==0d){
                    energyGrowthrate5 =  (1+data.getAverageGrowthrate()/100)*(1-data.getEnergyUnitGdpReducerate5()/100)-1;
                    gdpTotal5 = data.getPreGdpTotal()*Math.pow((1+data.getAverageGrowthrate()/100),5);
                    energyTotal5 = data.getPreEnergyTotal()*(1+energyGrowthrate1)*(1+energyGrowthrate2)*(1+energyGrowthrate3)*(1+energyGrowthrate4)*(1+energyGrowthrate5);
                }
                energyUnitGdp5 = energyTotal5/gdpTotal5;

                //累计五年值
                amountGdpTotal = gdpTotal1+gdpTotal2+gdpTotal3+gdpTotal4+gdpTotal5;
                amountEnergyTotal = energyTotal1+energyTotal2+energyTotal3+energyTotal4+energyTotal5;
                amountEnergyUnitGdp = amountEnergyTotal/amountGdpTotal;
                amountEnergyUnitGdpReducerate =((data.getPreEnergyTotal()/data.getPreGdpTotal())-energyUnitGdp5) / (data.getPreEnergyTotal()/data.getPreGdpTotal());

                //更新数据
                data.setIndexCalculation(energyGrowthrate1, gdpTotal1, energyTotal1, energyUnitGdp1, energyGrowthrate2, gdpTotal2, energyTotal2, energyUnitGdp2,
                                         energyGrowthrate3, gdpTotal3, energyTotal3, energyUnitGdp3, energyGrowthrate4, gdpTotal4, energyTotal4, energyUnitGdp4,
                                         energyGrowthrate5, gdpTotal5, energyTotal5, energyUnitGdp5, amountGdpTotal, amountEnergyTotal, amountEnergyUnitGdp, amountEnergyUnitGdpReducerate, version.getId(), indexType, version.getYear());

                //记录档位 五年指标值
                Double tmpGear = gearData.getOrDefault(data.getGearCode(), 0D);
                if(tmpGear<amountEnergyUnitGdpReducerate*100){ //取各档位最大值
                    Double tmp =0d;
                    if((amountEnergyUnitGdpReducerate*100)%1>0.5){ //余数大于0.5，向上取整
                        tmp = Math.ceil(amountEnergyUnitGdpReducerate*100);
                    }else{ //余数小于等于0.5，向下取整 小数为0.5
                        tmp = Math.floor(amountEnergyUnitGdpReducerate*100)+0.5;
                    }
                    gearData.put(data.getGearCode(),tmp);
                }

                //求和验算，本地区不在范围内
                if(!data.getItemCode().equals(deptId.toString())){
                    preGdpTotalSum += data.getPreGdpTotal();
                    preEnergyTotalSum += data.getPreEnergyTotal();
                    gdpTotal1Sum+=gdpTotal1;
                    energyTotal1Sum+=energyTotal1;
                    gdpTotal2Sum+=gdpTotal2;
                    energyTotal2Sum+=energyTotal2;
                    gdpTotal3Sum+=gdpTotal3;
                    energyTotal3Sum+=energyTotal3;
                    gdpTotal4Sum+=gdpTotal4;
                    energyTotal4Sum+=energyTotal4;
                    gdpTotal5Sum+=gdpTotal5;
                    energyTotal5Sum+=energyTotal5;
                }
            }
        }

        //求和验算
        preEnergyUnitGdpSum = preEnergyTotalSum/preGdpTotalSum;
        gdpTotalProportionSum = 100*(preGdpTotalSum/indexAccont.getPreGdpTotal());
        energyTotalProportionSum = 100*(preEnergyTotalSum/indexAccont.getPreEnergyTotal());
        comprehensiveWeightSum = 0.5*(gdpTotalProportionSum+energyTotalProportionSum);
        energyUnitGdp1Sum=energyTotal1Sum/gdpTotal1Sum;
        energyUnitGdp2Sum=energyTotal2Sum/gdpTotal2Sum;
        energyUnitGdp3Sum=energyTotal3Sum/gdpTotal3Sum;
        energyUnitGdp4Sum=energyTotal4Sum/gdpTotal4Sum;
        energyUnitGdp5Sum=energyTotal5Sum/gdpTotal5Sum;
        amountGdpTotalSum = gdpTotal1Sum+gdpTotal2Sum+gdpTotal3Sum+gdpTotal4Sum+gdpTotal5Sum;
        amountEnergyTotalSum = energyTotal1Sum+energyTotal2Sum+energyTotal3Sum+energyTotal4Sum+energyTotal5Sum;
        amountEnergyUnitGdpSum = amountEnergyTotalSum/amountGdpTotalSum;
        amountEnergyUnitGdpReducerateSum =100*(((preEnergyTotalSum/preGdpTotalSum)-energyUnitGdp5Sum) / (preEnergyTotalSum/preGdpTotalSum));
        //合计值
        TDualcontrolIndexresolve indexSum = new TDualcontrolIndexresolve("0", "求和验算", preGdpTotalSum, preEnergyTotalSum, preEnergyUnitGdpSum, gdpTotalProportionSum, energyTotalProportionSum, comprehensiveWeightSum,
                gdpTotal1Sum, energyTotal1Sum, energyUnitGdp1Sum, gdpTotal2Sum, energyTotal2Sum, energyUnitGdp2Sum, gdpTotal3Sum, energyTotal3Sum, energyUnitGdp3Sum,
                gdpTotal4Sum, energyTotal4Sum, energyUnitGdp4Sum, gdpTotal5Sum, energyTotal5Sum, energyUnitGdp5Sum, amountGdpTotalSum, amountEnergyTotalSum, amountEnergyUnitGdpSum, amountEnergyUnitGdpReducerateSum, version.getId(), indexType, version.getYear());

        //求差额
        Double preGdpTotalDiff = preGdpTotalSum - indexAccont.getPreGdpTotal();
        Double preEnergyTotalDiff = preEnergyTotalSum - indexAccont.getPreEnergyTotal();
        Double gdpTotal1Diff = gdpTotal1Sum - indexAccont.getGdpTotal1();
        Double energyTotal1Diff = energyTotal1Sum - indexAccont.getEnergyTotal1();
        Double energyUnitGdp1Diff = energyUnitGdp1Sum - indexAccont.getEnergyUnitGdp1();
        Double gdpTotal2Diff = gdpTotal2Sum - indexAccont.getGdpTotal2();
        Double energyTotal2Diff = energyTotal2Sum - indexAccont.getEnergyTotal2();
        Double energyUnitGdp2Diff = energyUnitGdp2Sum - indexAccont.getEnergyUnitGdp2();
        Double gdpTotal3Diff = gdpTotal3Sum - indexAccont.getGdpTotal3();
        Double energyTotal3Diff = energyTotal3Sum - indexAccont.getEnergyTotal3();
        Double energyUnitGdp3Diff = energyUnitGdp3Sum - indexAccont.getEnergyUnitGdp3();
        Double gdpTotal4Diff = gdpTotal4Sum - indexAccont.getGdpTotal4();
        Double energyTotal4Diff = energyTotal4Sum - indexAccont.getEnergyTotal4();
        Double energyUnitGdp4Diff = energyUnitGdp4Sum - indexAccont.getEnergyUnitGdp4();
        Double gdpTotal5Diff = gdpTotal5Sum - indexAccont.getGdpTotal5();
        Double energyTotal5Diff = energyTotal5Sum - indexAccont.getEnergyTotal5();
        Double energyUnitGdp5Diff = energyUnitGdp5Sum - indexAccont.getEnergyUnitGdp5();
        Double amountGdpTotalDiff = gdpTotal1Diff+gdpTotal2Diff+gdpTotal3Diff+gdpTotal4Diff+gdpTotal5Diff;
        Double amountEnergyTotalDiff = energyTotal1Diff+energyTotal2Diff+energyTotal3Diff+energyTotal4Diff+energyTotal5Diff;
        Double amountEnergyUnitGdpReducerateDiff = amountEnergyUnitGdpReducerateSum - indexAccont.getAmountEnergyUnitGdpReducerate();
        //差值
        TDualcontrolIndexresolve indexDiff =new TDualcontrolIndexresolve("0", "差额", preGdpTotalDiff, preEnergyTotalDiff, 0d, 0d, 0d, 0d,
                gdpTotal1Diff, energyTotal1Diff, energyUnitGdp1Diff, gdpTotal2Diff, energyTotal2Diff, energyUnitGdp2Diff, gdpTotal3Diff, energyTotal3Diff, energyUnitGdp3Diff,
                gdpTotal4Diff, energyTotal4Diff, energyUnitGdp4Diff, gdpTotal5Diff, energyTotal5Diff, energyUnitGdp5Diff, amountGdpTotalDiff, amountEnergyTotalDiff, 0d, amountEnergyUnitGdpReducerateDiff, version.getId(), indexType, version.getYear());

        //设置档位指标值
        for (TDualcontrolIndexresolve data : dataList) {
            Double tmp = gearData.get(data.getGearCode());
            if(tmp!=null&&tmp!=0d){
                data.setCheckCalculation(tmp);
            }
        }

        List<TDualcontrolIndexresolve> result = new ArrayList<>();
        TDualcontrolIndexresolve tmp = new TDualcontrolIndexresolve();
        tmp.setGearCode("-1");
        result.add(tmp);
        result.add(indexDiff);
        result.add(indexSum);
        result.addAll(dataList);
        return result;
    }
}
