package com.mvc.recognition.predict;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.github.pagehelper.PageHelper;
import com.mvc.dao.TAireadMapper;
import com.mvc.entity.TAiread;
import com.mvc.entity.TAireadExample;
import com.mvc.entity.TDataPredict;
import com.mvc.model.TAireadModel;
import com.mvc.model.aihcxd.DataPredictInModel;
import com.mvc.netty.dealconstant.ResourceTag;
import com.mvc.service.aihcxd.TDataPredictService;
import com.mvc.utils.DateUtil;
import com.mvc.utils.HttpUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Component
public class DataPredict {
    private static Logger log = LoggerFactory.getLogger(DataPredict.class);
    //测试期间先这么写
    private final static String API_DATA_PREDICT = "/DataPredictController/getPredictValue";
    //private final static String URL_DATA_PREDICT = "http://localhost:6080/DataPredictController/getPredictValue";

    @Resource
    private TAireadMapper aireadMapper;

    @Resource
    private TDataPredictService dataPredictService;

    @Resource
    private Environment env;

    public void handleDataPredict(TAireadModel aireadModel, Double numberUnit) {
        //暂时关闭,中北的服务经常关闭,导致接口不通,全是错误日志 2024-07-05 guozhao
        if(true){
            return;
        }

        DataPredictInModel inModel = getDataPredictInModelByAireadModel(aireadModel);
        if (inModel == null) {
            return;
        }
        inModel.setSaveLenth(numberUnit == null || numberUnit == 0 ? 1.0 : numberUnit);
        String url = env.getProperty(ResourceTag.NoConfigServerUrlTag.getTag()) + API_DATA_PREDICT;

        String response = HttpUtil.postData(url, inModel);
        if (StringUtils.isEmpty(response)) {
            return;
        }

        try {
            Map<String, Object> map = JSON.parseObject(response, new TypeReference<>() {
            });

            if (map == null || !map.containsKey("res")) {
                return;
            }
            if (map.get("res") == null) {
                return;
            }
            Object obj = map.get("res");
            BigDecimal resValue = null;
            if (obj instanceof Integer) {
                Integer intValue = (Integer) obj;
                resValue = BigDecimal.valueOf(intValue);
            } else if (obj instanceof BigDecimal) {
                resValue = (BigDecimal) obj;
            }

            if(resValue != null){
                TDataPredict dataPredict = new TDataPredict();
                dataPredict.setAireadId(aireadModel.getId());
                dataPredict.setIdentValue(aireadModel.getIdentValue());

                dataPredict.setPredictValue(resValue);
                dataPredictService.saveTDataPredict(dataPredict);
            }

        }catch (Exception ex){
            String err = "数据预测异常:" + response;
            log.error(err, ex);
        }

        //下面代码经常出现以下异常,在本地又未能复现,因此改为上面代码进行观察 2024-06-15 guozhao
        //java.lang.ClassCastException: class java.lang.Integer cannot be cast to class java.math.BigDecimal
        // (java.lang.Integer and java.math.BigDecimal are in module java.base of loader 'bootstrap')
        /*try {
            ResultMap<BigDecimal> resultMap = JSON.parseObject(response, new TypeReference<>() {
            });
            if (resultMap != null && resultMap.getRes() != null) {
                TDataPredict dataPredict = new TDataPredict();
                dataPredict.setAireadId(aireadModel.getId());
                dataPredict.setIdentValue(aireadModel.getIdentValue());
                //dataPredict.setPredictValue(resultMap.getRes());
                // 这里尝试将 resultMap.getRes() 转换为 String，然后构造 BigDecimal，以应对可能的类型不匹配
                String resStr = resultMap.getRes().toString();
                BigDecimal resValue;

                //resValue = new BigDecimal(resStr);
                resValue = BigDecimal.valueOf(Double.parseDouble(resStr));

                dataPredict.setPredictValue(resValue);
                dataPredictService.saveTDataPredict(dataPredict);
            }
        } catch (Exception ex) {

        }*/
    }

    /**
     * 根据当前读数对象获取数据预测输入对象
     *
     * @param aireadModel
     * @return
     */
    private DataPredictInModel getDataPredictInModelByAireadModel(TAireadModel aireadModel) {
        DataPredictInModel inModel = new DataPredictInModel();
        TAireadExample example = new TAireadExample();
        TAireadExample.Criteria criteria = example.createCriteria();
        criteria.andStationCodeEqualTo(aireadModel.getStationCode());
        criteria.andSampleTimeLessThan(aireadModel.getSampleTime());
        Date lastYear = DateUtil.getOtherDateByYear(aireadModel.getSampleTime(), -1);
        criteria.andSampleTimeGreaterThanOrEqualTo(lastYear);
        criteria.andResultValueIsNotNull();
        example.setOrderByClause("sample_time desc");
        //近一年的数据,最多一千条
        PageHelper.startPage(1, 1000);
        List<TAiread> list = aireadMapper.selectByExample(example);
        //数据量太小,无预测意义
        if (list == null || list.size() < 10) {
            return null;
        }
        List<String> dateList = new ArrayList<>();
        List<Double> valueList = new ArrayList<>();
        String date = "";
        BigDecimal firstValue = list.get(list.size() - 1).getResultValue();
        int num = 0;
        for (int i = list.size() - 1; i > -1; i--) {
            date = DateUtil.formateDate(list.get(i).getSampleTime(), "yyyy/MM/dd HH:mm:ss");
            if (dateList.contains(date)) {
                continue;
            }
            dateList.add(date);
            valueList.add(list.get(i).getResultValue().doubleValue());
            if (firstValue.compareTo(list.get(i).getResultValue()) == 0) {
                num++;
            }
        }
        //起因:数据预测算法不支持全部是相同数据的预测,会异常(矩阵不可逆) 2024-05-28 guozhao
        if (num == dateList.size()) {
            return null;
        }

        inModel.setDateList(dateList);
        inModel.setValueList(valueList);
        return inModel;
    }
}
