package com.nantian.cloud.jljc.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nantian.cloud.jljc.entity.*;
import com.nantian.cloud.jljc.service.*;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

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


/**
 * 企业能耗准确性分析
 *
 * @author
 * @date 2018-09-27 15:20:44
 */
@RestController
@AllArgsConstructor
@RequestMapping("/epcEnergyAccuracyAnalysis")
@Api(value = "epcEnergyAccuracyAnalysis", tags = "企业能耗准确性分析")
@CrossOrigin
public class EpcEnergyAccuracyAnalysisController {
    private final EpcEnergyAccuracyAnalysisService epcEnergyAccuracyAnalysisService;

    //报表1-1
    final private TReportEnterpriseService tReportEnterpriseService;
    final private TReportFinancialService tReportFinancialService;
    final private TReportProductService tReportProductService;
    //报表信息
    final private TReportService tReportService;
    //报表1-2
    final private TReportEnergysTructureeController tructureeController;
    final private TReportEnergysTructureService tructureService;
    final private TReportEnergyOutController outController;
    final private TReportEnergyOutService outService;
    //企业信息
    final private EnterpriseInfoService enterpriseInfoService;
    final private EnergyLevelService energyLevelService;


    /**
     * 分页查询
     *
     * @param page                      分页对象
     * @param epcEnergyAccuracyAnalysis
     * @return
     */
    @GetMapping("/page")
    @SysLog("分页获取企业能耗准确性分析")
    @ApiOperation(value = "分页获取企业能耗准确性分析", notes = "分页获取企业能耗准确性分析")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "epcEnergyAccuracyAnalysis", value = "企业能耗准确性分析对象（查询条件：企业名称epcName、年份year、验收结果checkResult）", required = false, dataType = "json", paramType = "path")
    })
    public R getEpcEnergyAccuracyAnalysisPage(Page page, EpcEnergyAccuracyAnalysis epcEnergyAccuracyAnalysis) {
        //return R.ok(epcEnergyAccuracyAnalysisService.page(page, Wrappers.query(epcEnergyAccuracyAnalysis)));
        epcEnergyAccuracyAnalysis.setDelFlag("1"); //筛选未删除项
        return R.ok(epcEnergyAccuracyAnalysisService.getPageScope(page, epcEnergyAccuracyAnalysis));
    }


    /**
     * 信息
     *
     * @param epcEnergyAccuracyAnalysisId
     * @return R
     */
    @GetMapping("/{epcEnergyAccuracyAnalysisId}")
    @SysLog("根据id获取企业能耗准确性分析")
    @ApiOperation(value = "根据id获取企业能耗准确性分析", notes = "根据id获取企业能耗准确性分析")
    @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "int", paramType = "path")
    public R getById(@PathVariable("epcEnergyAccuracyAnalysisId") Integer epcEnergyAccuracyAnalysisId) {
        return R.ok(epcEnergyAccuracyAnalysisService.getById(epcEnergyAccuracyAnalysisId));
    }

    /**
     * 保存
     *
     * @param epcEnergyAccuracyAnalysis
     * @return R
     */
    @PostMapping
    @SysLog("新增企业能耗准确性分析")
    @ApiOperation(value = "新增企业能耗准确性分析", notes = "新增企业能耗准确性分析")
    @ApiImplicitParam(name = "epcEnergyAccuracyAnalysis", value = "企业能耗准确性分析对象", required = true, dataType = "json", paramType = "path")
    public R save(@RequestBody EpcEnergyAccuracyAnalysis epcEnergyAccuracyAnalysis) {
        ScUser u = SecurityUtils.getUser();
        epcEnergyAccuracyAnalysis.setUserid(u.getId());
        epcEnergyAccuracyAnalysis.setDeptId(u.getDeptId());
        epcEnergyAccuracyAnalysis.setUpdateTime(new Date());
        epcEnergyAccuracyAnalysis.setDelFlag("1");
        return R.ok(epcEnergyAccuracyAnalysisService.save(epcEnergyAccuracyAnalysis));
    }

    /**
     * 修改
     *
     * @param epcEnergyAccuracyAnalysis
     * @return R
     */
    @PutMapping
    @SysLog("修改企业能耗准确性分析")
    @ApiOperation(value = "修改企业能耗准确性分析", notes = "修改企业能耗准确性分析")
    @ApiImplicitParam(name = "epcEnergyAccuracyAnalysis", value = "企业能耗准确性分析对象", required = true, dataType = "json", paramType = "path")
    public R updateById(@RequestBody EpcEnergyAccuracyAnalysis epcEnergyAccuracyAnalysis) {
        ScUser u = SecurityUtils.getUser();
        epcEnergyAccuracyAnalysis.setUserid(u.getId());
        epcEnergyAccuracyAnalysis.setUpdateTime(new Date());
        return R.ok(epcEnergyAccuracyAnalysisService.updateById(epcEnergyAccuracyAnalysis));
    }

    /**
     * 删除
     *
     * @param epcEnergyAccuracyAnalysisId
     * @return R
     */
    @DeleteMapping("/{epcEnergyAccuracyAnalysisId}")
    @SysLog("删除企业能耗准确性分析")
    @ApiOperation(value = "删除企业能耗准确性分析", notes = "删除企业能耗准确性分析")
    @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "int", paramType = "path")
    public R removeById(@PathVariable Integer epcEnergyAccuracyAnalysisId) {
        EpcEnergyAccuracyAnalysis epcEnergyAccuracyAnalysis = epcEnergyAccuracyAnalysisService.getById(epcEnergyAccuracyAnalysisId);
        ScUser u = SecurityUtils.getUser();
        epcEnergyAccuracyAnalysis.setUserid(u.getId());
        epcEnergyAccuracyAnalysis.setUpdateTime(new Date());
        epcEnergyAccuracyAnalysis.setDelFlag("4");
        return R.ok(epcEnergyAccuracyAnalysisService.updateById(epcEnergyAccuracyAnalysis));
    }


    /**
     * 企业能耗准确性分析，企业综合能源消费量（历史财务数据精确性分析）
     */
    //@GetMapping("/upEnergyConsumption")
    public R upEnergyConsumption() {

        QueryWrapper<TReportFinancial> t1 = Wrappers.query();
        t1.ge("report_id","14378");
        t1.eq("del_flag","1");
        List<TReportFinancial> financials = tReportFinancialService.list(t1);

        DecimalFormat df = new DecimalFormat(".00"); //保留两位小数
        for (TReportFinancial financial : financials) {
            double energyConsumption = financial.getEnergyConsumption() != null && financial.getEnergyConsumption() != 0 ? financial.getEnergyConsumption() * 10000 : 0; //综合能源消费量

            //本年报表信息
            TReport r = tReportService.getById(financial.getReportId());
            if (r != null) {
                //获取企业基本信息
                EnterpriseInfo enterpriseInfo = enterpriseInfoService.getInfoNameByCode(r.getEnterpriseCode());

                EpcEnergyAccuracyAnalysis q = new EpcEnergyAccuracyAnalysis();
                q.setEpc(r.getEnterpriseCode());
                q.setYear(r.getYear().toString());
                q.setDelFlag("1");
                EpcEnergyAccuracyAnalysis old = epcEnergyAccuracyAnalysisService.getOne(Wrappers.query(q));

                EpcEnergyAccuracyAnalysis analysis = new EpcEnergyAccuracyAnalysis();
                if (old != null) { //有历史数据为修改
                    analysis.setId(old.getId());
                } else {
                    analysis.setDelFlag("1");
                    analysis.setEpc(r.getEnterpriseCode());
                    analysis.setYear(r.getYear().toString());
                    analysis.setReport1Id(r.getId().toString());
                    //analysis.setTotalEnergy(Float.parseFloat(df.format(energyConsumption)) + "");
                    String energyConsumptionStr = big(Float.parseFloat(df.format(energyConsumption)));
                    analysis.setTotalEnergy(energyConsumptionStr);
                    if (enterpriseInfo != null) {
                        analysis.setDeptId(Integer.parseInt(enterpriseInfo.getRegionCode()));
                        analysis.setEpcName(enterpriseInfo.getCmpName());
                        analysis.setArea2(enterpriseInfo.getRegionName());
                        analysis.setTradeNum2(enterpriseInfo.getIndustryName());
                        analysis.setEpcType(enterpriseInfo.getCompanyTypeName());
                        analysis.setEnergyRegion(enterpriseInfo.getEnergyConsumeLevelName());
                    }
                }
                ScUser u = SecurityUtils.getUser();
                analysis.setUserid(u.getId());
                analysis.setUpdateTime(new Date());

                EnergyLevel level = energyLevelService.getById(enterpriseInfo != null ? enterpriseInfo.getEnergyConsumeLevel() : 0);
                if (level != null) {
                    if (energyConsumption > Float.valueOf(level.getUpperLimit())) { //超出上限
                        analysis.setCheckResult("1"); //异常
                    } else {
                        analysis.setCheckResult("2"); //正常
                    }
                    analysis.setDifference(df.format((energyConsumption - Float.valueOf(level.getUpperLimit()))) + ""); //变化值
                }
                epcEnergyAccuracyAnalysisService.saveOrUpdate(analysis);
            }

        }
        return R.ok();
    }

    private static String big(double d) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        return nf.format(d);
    }


    /**
     * 企业能耗准确性分析，预览报表1-1
     */
    @GetMapping("/previewReport1")
    @SysLog("企业能耗准确性分析，预览报表1-1")
    @ApiOperation(value = "企业能耗准确性分析，预览报表1-1", notes = "企业能耗准确性分析，预览报表1-1")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业编码", required = false, dataType = "json", paramType = "path")
    })
    public R previewReport1(String year, String enterpriseCode) {

        if (year == null || "".equals(year)) {
            return R.failed("预览报表信息失败，年度不能为空");
        }
        if (enterpriseCode == null || "".equals(enterpriseCode)) {
            return R.failed("预览报表信息失败，企业社会信用编码不能为空");
        }

        //获取能源报表信息
        TReport report = tReportService.getInfoByType(enterpriseCode, year, "1");
        if (report == null) {
            return R.ok();
        }

        //获取报表设置企业信息
        TReportEnterprise enterprise = tReportEnterpriseService.getEnterpriseByReportId(report.getId());
        if (enterprise != null) {
            enterprise = tReportEnterpriseService.getNameByEnterprise(enterprise);
        }

        //获取当前年度财务信息
        TReportFinancial financial = tReportFinancialService.getFinancialsByReportId(report.getId());
        //获取本年 企业是否为加工转换
        int jgzh = getEnterpriseJgzh(report);

        //获取上年度财务信息
        Integer prevYear = Integer.parseInt(year) - 1;
        TReport prevReport = tReportService.getInfoByType(enterpriseCode, prevYear + "", "1");
        TReportFinancial prevFinancial = tReportFinancialService.getFinancialsByReportId(prevReport.getId() != null ? prevReport.getId() : 0);
        //获取上年 企业是否为加工转换
        int prevJgzh = getEnterpriseJgzh(prevReport);


        DecimalFormat df = new DecimalFormat(".00"); //保留2位小数
        //综合能源消费量等价值(吨标准煤)
        double energyConsumptionEqu = getEnergyConsumption(year, enterpriseCode, jgzh);
        double prevEnergyConsumptionEqu = getEnergyConsumption(prevYear + "", enterpriseCode, prevJgzh);
        double energyConsumptionRateEqu = 0;
        if (energyConsumptionEqu != 0 && prevEnergyConsumptionEqu != 0) {
            energyConsumptionRateEqu = (energyConsumptionEqu / prevEnergyConsumptionEqu - 1) * 100;
        }
        financial.setEnergyConsumptionEqu(energyConsumptionEqu);
        financial.setEnergyConsumptionRateEqu(Double.parseDouble(df.format(energyConsumptionRateEqu)));
        prevFinancial.setEnergyConsumptionEqu(prevEnergyConsumptionEqu);
        //综合能源消费量当量值(吨标准煤)
        if (financial.getEnergyConsumption() != null && financial.getEnergyConsumption() != 0) {
            financial.setEnergyConsumption(financial.getEnergyConsumption() * 10000);
        }
        if (prevFinancial.getEnergyConsumption() != null && prevFinancial.getEnergyConsumption() != 0) {
            prevFinancial.setEnergyConsumption(prevFinancial.getEnergyConsumption() * 10000);
        }


        //工业总产值现价值（万元）
        double yieldNow = getIndustrialYieldByReport2(year, enterpriseCode);
        double prevYieldNow = getIndustrialYieldByReport2(prevYear + "", enterpriseCode);
        double yieldRateNow = 0;
        if (yieldNow != 0 && prevYieldNow != 0) {
            yieldRateNow = (yieldNow / prevYieldNow - 1) * 100;
        }
        financial.setIndustrialYieldNow(yieldNow);
        financial.setIndustrialYieldRateNow(Double.parseDouble(df.format(yieldRateNow)));
        prevFinancial.setIndustrialYieldNow(prevYieldNow);

        //产值能耗等价值(吨标准煤/万元)
        double unitEnergyConsumptionEqu = 0, prevUnitEnergyConsumptionEqu = 0, unitEnergyConsumptionRateEqu = 0;
        if (financial.getIndustrialYield() != null && financial.getIndustrialYield() != 0 && energyConsumptionEqu != 0) {
            unitEnergyConsumptionEqu = energyConsumptionEqu / financial.getIndustrialYield();
        }
        if (prevFinancial.getIndustrialYield() != null && prevFinancial.getIndustrialYield() != 0 && prevEnergyConsumptionEqu != 0) {
            prevUnitEnergyConsumptionEqu = prevEnergyConsumptionEqu / prevFinancial.getIndustrialYield();
        }
        if (unitEnergyConsumptionEqu != 0 && prevUnitEnergyConsumptionEqu != 0) {
            unitEnergyConsumptionRateEqu = (unitEnergyConsumptionEqu / prevUnitEnergyConsumptionEqu - 1) * 100;
        }
        financial.setUnitEnergyConsumptionEqu(Double.parseDouble(df.format(unitEnergyConsumptionEqu)));
        financial.setUnitEnergyConsumptionRateEqu(Double.parseDouble(df.format(unitEnergyConsumptionRateEqu)));
        prevFinancial.setUnitEnergyConsumptionEqu(Double.parseDouble(df.format(prevUnitEnergyConsumptionEqu)));

        //能源消费成本（变化率）
        if(financial.getEnergyConsumptionCostRate()==null){
            double energyConsumptionCostRate = 0;
            if (financial.getEnergyConsumptionCost() != null && financial.getEnergyConsumptionCost() != 0
                    && prevFinancial.getEnergyConsumptionCost() != null && prevFinancial.getEnergyConsumptionCost() != 0) {
                energyConsumptionCostRate = Float.parseFloat(df.format((financial.getEnergyConsumptionCost()/prevFinancial.getEnergyConsumptionCost()-1)*100));
            }
            financial.setEnergyConsumptionCostRate(energyConsumptionCostRate);
        }

        //获取主要产品信息
        List<TReportProduct> products = tReportProductService.getProductsByReportId(report.getId());
        List<TReportProduct> newProducts = new ArrayList<>();
        for (TReportProduct product : products) {
            //product.setUnitEnergyConsumptionEqu();
            product.setUnitEnergyConsumptionUnitEqu(product.getUnitEnergyConsumptionUnit());
            newProducts.add(product);
        }

        Map<String, Object> map = new HashMap();
        map.put("enterprise", enterprise);
        map.put("products", newProducts);
        map.put("financial", financial);
        map.put("prevFinancial", prevFinancial);
        map.put("report", report);

        return R.ok(map);
    }

    /**
     * 获取财务信息的工业总产值(按现价计算)
     */
    private float getIndustrialYieldByReport2(String year, String enterpriseCode) {
        DecimalFormat df = new DecimalFormat(".0000"); //保留4位小数
        double industrialYieldByReport2 = 0;
        //获取财务信息的工业总产值(按现价计算)
        TReport reportTructure = tReportService.getInfoByType(enterpriseCode, year, "2");
        if (reportTructure != null) {
            //获取能源消费表合计信息
            List<TReportEnergysTructure> tructureListSum = tructureService.getTructureByReportIdAndName(reportTructure.getId(), "合计等价值");
            TReportEnergysTructure sumEquInfo = tructureListSum.size() > 0 ? tructureListSum.get(0) : null;
            if (sumEquInfo != null) {
                industrialYieldByReport2 = (sumEquInfo.getProductionSum() != null ? sumEquInfo.getProductionSum() : 0);
            } else {
                //历史数据，没有合计值，从能源消费列表中获取
                TReportEnergysTructure tructure = new TReportEnergysTructure();
                tructure.setReportId(reportTructure.getId());
                tructure.setDelFlag("1");
                List<TReportEnergysTructure> tructureList = tructureService.list(Wrappers.query(tructure));
                for (TReportEnergysTructure tReportEnergysTructure : tructureList) {
                    if (tReportEnergysTructure.getProductionSum() != null) {
                        industrialYieldByReport2 = tReportEnergysTructure.getProductionSum();
                        break;
                    }
                }
            }
        }
        return Float.parseFloat(df.format(industrialYieldByReport2));
    }

    /**
     * 获取财务信息的综合能源消费量等价值
     */
    private double getEnergyConsumption(String year, String enterpriseCode, int jgzh) {
        DecimalFormat df2 = new DecimalFormat(".00"); //保留2位小数
        double energyConsumption = 0;
        //获取财务信息  综合能源消费量等价值（吨标准煤）
        if (jgzh == 1) { //是加工转换企业
            TReport reportOut = tReportService.getInfoByType(enterpriseCode, year, "2-1");
            if (reportOut != null) {
                //获取能源合计信息等价值
                TReportEnergyOut sumEquInfo = outService.getOutByReportIdAndName(reportOut.getId(), "合计等价值");
                if (sumEquInfo == null) {
                    TReportEnergyOut out = new TReportEnergyOut();
                    out.setReportId(reportOut.getId());
                    out.setDelFlag("1");
                    List<TReportEnergyOut> outList = outService.list(Wrappers.query(out));
                    //返回集合，下标  0：sumInfo合计当量值  1：sumEquInfo合计等价值
                    List<TReportEnergyOut> sumList = outController.getSum(outList, reportOut.getId());
                    sumEquInfo = (sumList.size() >= 2 ? sumList.get(1) : new TReportEnergyOut());
                }
                //获取报表1 财务信息 综合能源消费量（吨标准煤） = (报表2-1 工业生产消费的能源折标量合计 -能源加工转换产出折标量合计-回收利用折标量合计) 回显
                energyConsumption = (sumEquInfo.getProductionConsumption() != null ? sumEquInfo.getProductionConsumption() : 0)
                        - (sumEquInfo.getConversionOutputRef() != null ? sumEquInfo.getConversionOutputRef() : 0)
                        - (sumEquInfo.getRecycling() != null ? sumEquInfo.getRecycling() : 0);
                energyConsumption = Float.parseFloat(df2.format(energyConsumption));
            }
        } else {
            TReport reportTructure = tReportService.getInfoByType(enterpriseCode, year, "2");
            if (reportTructure != null) {
                //获取能源消费表合计信息
                List<TReportEnergysTructure> tructureListSum = tructureService.getTructureByReportIdAndName(reportTructure.getId(), "合计等价值");
                //根据报表id和名称为“合计等价值”，能获取唯一一条数据
                TReportEnergysTructure sumEquInfo = tructureListSum.size() > 0 ? tructureListSum.get(0) : null;
                if (sumEquInfo == null) {
                    TReportEnergysTructure tructure = new TReportEnergysTructure();
                    tructure.setReportId(reportTructure.getId());
                    tructure.setDelFlag("1");
                    List<TReportEnergysTructure> tructureList = tructureService.list(Wrappers.query(tructure));
                    //返回集合，下标  0：sumInfo合计当量值  1：sumEquInfo合计等价值
                    List<TReportEnergysTructure> sumList = tructureeController.getSum(tructureList, reportTructure.getId(), 0d);
                    sumEquInfo = (sumList.size() >= 2 ? sumList.get(1) : new TReportEnergysTructure());
                }
                //获取报表1 财务信息 综合能源消费量（吨标准煤） = 报表2 工业生产消费的能源折标量合计   回显
                energyConsumption = (sumEquInfo.getConsumeIndustry() != null && sumEquInfo.getConsumeIndustry() != 0) ? sumEquInfo.getConsumeIndustry() : 0;
                energyConsumption = Double.parseDouble(df2.format(energyConsumption));
            }
        }
        return energyConsumption;
    }

    /**
     * 判断企业是否为加工转换企业
     */
    private int getEnterpriseJgzh(TReport report) {
        int jgzh = 0; //不是加工转换企业
        //获取报表设置企业信息
        TReportEnterprise enterprise = tReportEnterpriseService.getEnterpriseByReportId(report.getId() != null ? report.getId() : 0);
        if (enterprise != null) {
            enterprise = tReportEnterpriseService.getNameByEnterprise(enterprise);
            //ProcessingLink 是否为加工转换企业取值，2不是，1是
            if ("1".equals(enterprise.getProcessingLink())) { //该企业是加工转换企业
                jgzh = 1;
            }
        } else {
            //没有进行报表设置的企业，需从企业信息表中获取是否为加工转换企业
            EnterpriseInfo enterpriseInfo = enterpriseInfoService.getInfoByCode(report.getEnterpriseCode() != null ? report.getEnterpriseCode() : "");
            if (enterpriseInfo != null) {
                //Jgzh 是否为加工转换企业取值，0不是，1是
                if ("1".equals(enterpriseInfo.getJgzh())) { //该企业是加工转换企业
                    jgzh = 1;
                }
            }
        }
        return jgzh;
    }

}
