package com.nantian.cloud.jljc.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nantian.cloud.jljc.entity.EcAbnormalVolatility;
import com.nantian.cloud.jljc.entity.EcAbnormalVolatilityInfo;
import com.nantian.cloud.jljc.entity.TReportPara;
import com.nantian.cloud.jljc.service.EcAbnormalVolatilityInfoService;
import com.nantian.sc.cloud.common.security.service.ScUser;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Date;
import java.util.Map;

@Slf4j
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/VolatilityTmp")
@Api(value = "volatilityTmp", tags = "异常波动范围判断")
public class VolatilityTmpController {


    /**
     * 判断单个值是否超出异常波动范围
     */
    public static class VolatilityTmp {
        //能耗异常波动详细信息表 服务类（无法自动装配，需要当做参数传递过来）
        private EcAbnormalVolatilityInfoService ecAbnormalVolatilityInfoService;
        //超出波动范围，且未填写波动说明
        private boolean myResult;
        //用户信息
        private ScUser u;
        //波动标志默认为，false，不波动
        private boolean flage;
        //波动范围
        private TReportPara para;
        //能耗异常波动主表
        private EcAbnormalVolatility volatility;
        //能耗异常波动详细信息
        //private EcAbnormalVolatilityInfo ecAbnormalVolatilityInfo;
        //类型（仅用于区分表一的财务信息和产品信息）
        private String type;
        //数据表
        private String dataTable;
        //保留小数位数
        private DecimalFormat df;
        //错误信息集
        private Map<String, Object> map;
        //本年值
        private Double temp;
        //上年值
        private Double tempFront;
        //变化率
        private Double tempRate;
        //错误信息
        private String msg;
        //数据内容
        private String dataContent;
        //计量单位
        private String unitVal;

        public VolatilityTmp(EcAbnormalVolatilityInfoService ecAbnormalVolatilityInfoService,
                             ScUser u, boolean flage, TReportPara para, EcAbnormalVolatility volatility,
                             DecimalFormat df, Map<String, Object> map, String type, String dataTable,
                             Double temp, Double tempFront, String msg, String dataContent, String unitVal) {
            this.ecAbnormalVolatilityInfoService = ecAbnormalVolatilityInfoService;
            this.u = u;
            this.flage = flage;
            this.para = para;
            this.volatility = volatility;
            //this.ecAbnormalVolatilityInfo = ecAbnormalVolatilityInfo;
            this.df = df;
            this.map = map;
            this.type = type;
            this.dataTable = dataTable;
            this.temp = temp;
            this.tempFront = tempFront;
            //this.tempRate = tempRate;
            this.msg = msg;
            this.dataContent = dataContent;
            this.unitVal = unitVal;
        }

        boolean is() {
            return myResult;
        }

        public boolean isFlage() {
            return flage;
        }

        public VolatilityTmp invoke() {
            final double NEGATIVE_INFINITY = -1.0 / 0.0;
            final double POSITIVE_INFINITY = 1.0 / 0.0;

            //取出本年的异常波动详情表
            EcAbnormalVolatilityInfo ecAbnormalVolatilityInfo = new EcAbnormalVolatilityInfo();
            ecAbnormalVolatilityInfo.setAbnormalVolatilityId(volatility != null ? volatility.getId() : 0);
            ecAbnormalVolatilityInfo.setDelFlag("1");
            ecAbnormalVolatilityInfo.setType(type);
            ecAbnormalVolatilityInfo.setDataTable(dataTable);
            ecAbnormalVolatilityInfo.setDataContent(dataContent);
            EcAbnormalVolatilityInfo volatilityInfo = ecAbnormalVolatilityInfoService.getOne(Wrappers.query(ecAbnormalVolatilityInfo));
            temp = (temp == null ? 0 : temp); //本期数
            tempFront = (tempFront == null ? 0 : Math.abs(tempFront)); //同期数取绝对值
            if (!(temp == 0 && tempFront == 0)) {
                //本年值与上年值都为0（变化率结果存在NaN），就不进行波动分析
                //本年值、上年值其中一个有值，或两个都有值才进行波动分析
                double tempRate = (temp / tempFront - 1) * 100; //波动比率
                double rate = (temp / tempFront) * 100;         //变化率
                if (Double.isInfinite(tempRate) ||  //tempRate为正无穷大 或负无穷大
                        tempRate < Float.parseFloat(para.getDownlimt()) || tempRate > Float.parseFloat(para.getUplimt())) { //超出波动范围
                    flage = true; //超期标志
                    if (volatility == null || volatilityInfo == null) {
                        //map.put("changeRatio", Float.parseFloat(df.format(tempRate)) + "%");
                        if (!(Double.isInfinite(tempRate))) {
                            map.put("changeRatio", Float.parseFloat(df.format(tempRate)) + "%");
                        } else if (tempRate == POSITIVE_INFINITY) {
                            map.put("changeRatio", "+∞");
                        } else {
                            map.put("changeRatio", "-∞");
                        }
                        map.put("msg", msg);
                        map.put("dataContent", dataContent);
                        map.put("unitVal", unitVal);
                        map.put("frontYearData", big(tempFront));
                        map.put("thisYearData", big(temp));
                        map.put("warningRange", para.getDownlimt()+"% ～ "+para.getUplimt()+"%");
                        myResult = true;
                        return this;
                    } else {
                        //更新异常波动详情表的信息
                        volatilityInfo.setThisYearData(big(temp) + "");
                        //volatilityInfo.setChangeRatio(Float.parseFloat(df.format(tempRate)) + "%");
                        if (!(Double.isInfinite(tempRate))) {
                            volatilityInfo.setChangeRatio(Float.parseFloat(df.format(tempRate)) + "%");
                        } else if (tempRate == POSITIVE_INFINITY) {
                            volatilityInfo.setChangeRatio("+∞");
                        } else {
                            volatilityInfo.setChangeRatio("-∞");
                        }
                        volatilityInfo.setUpdateTime(new Date());
                        volatilityInfo.setWarningRange(para.getDownlimt()+"% ～ "+para.getUplimt()+"%");
                        ecAbnormalVolatilityInfoService.updateById(volatilityInfo);
                    }
                } else {
                    if (volatilityInfo != null) {
                        //没有超出波动范围，却有波动记录，需要删除波动记录
                        deleteVolatilityInfo(u, volatilityInfo);
                    }
                }
            }
            myResult = false;
            return this;
        }

        public void deleteVolatilityInfo(ScUser u, EcAbnormalVolatilityInfo volatilityInfo) {
            volatilityInfo.setDelFlag("4");
            volatilityInfo.setUserid(u.getId());
            volatilityInfo.setUpdateTime(new Date());
            boolean delete = ecAbnormalVolatilityInfoService.updateById(volatilityInfo);
        }

        private static String big(double d) {
            NumberFormat nf = NumberFormat.getInstance();
            // 是否以逗号隔开, 默认true以逗号隔开,如[123,456,789.128]
            nf.setGroupingUsed(false);
            // 结果未做任何处理
            return nf.format(d);
        }
    }

}
