package com.jiayue.insu.inclientqn.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
//import com.jiayue.insu.inclientqn.ElectricFieldTypeEnum;
import com.jiayue.insu.inclientqn.constant.ConnectConstant;
import com.jiayue.insu.inclientqn.constant.DataTypeConstant;
import com.jiayue.insu.inclientqn.constant.StatusConstant;
import com.jiayue.insu.inclientqn.entity.CorrforeSt;
import com.jiayue.insu.inclientqn.entity.TokenInfo;
import com.jiayue.insu.inclientqn.model.RequestVo;
import com.jiayue.insu.inclientqn.model.ResponseVo;
import com.jiayue.insu.inclientqn.model.TokenVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: yuanhao
 * @createDate: 2021/9/27
 * @version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ForecastPowerTermCorrectService {
    @Autowired
    InTokenService inTokenService;
    @Autowired
    TokenInfoService tokenInfoService;

    @Value("${stationCode}")
    private String stationCode;

    public String[] pullCorrectData() {
        String[] status = new String[2];
        // 获取清能一体化token
        TokenVo tokenVo = inTokenService.getToken();

        if (tokenVo != null) {
            long startTimeT = DateUtil.beginOfDay(new Date()).getTime();
            long endTimeT = DateUtil.offsetDay(new Date(startTimeT), 1).getTime() - 1;
            //请求当日预测数据
            String todayforeStatus = corrforeData(tokenVo, DataTypeConstant.CORRFORE_TYPE, startTimeT, endTimeT, 97);
            status[0] = todayforeStatus;
//            long startTimeC = DateUtil.beginOfDay(DateUtil.tomorrow()).getTime();
//            long endTimeC = DateUtil.offsetDay(new Date(startTimeC), 9).getTime();
//            //请求未来9天预测数据
//            String corrforeStatus = corrforeData(tokenVo, DataTypeConstant.CORRFORE_TYPE, startTimeC, endTimeC, 865);
//            status[1] = corrforeStatus;
        } else {
            log.error(stationCode + " ========== 一体化:下载短期修正数据失败  无token ==========");
        }
        return status;
    }


    public String corrforeData(TokenVo tokenVo, String type, long startTime, long endTime, int count) {
        String response = "";
        String status = "";
        boolean result = false;
        List<CorrforeSt> list = new ArrayList<>();
        try {

            DateTime dateTime = DateUtil.parse(DateUtil.today());
            RequestVo requestVo = RequestVo.builder()
                    .transferType(ConnectConstant.TRANSFER_TYPE_CORRECT)
                    .date(dateTime.toString("yyyyMMdd"))
                    .dataType(type)
                    .build();

            JSONObject json = JSONUtil.parseObj(requestVo, true);
            String body = json.toString();
            List<TokenInfo> tokenInfoList = tokenInfoService.queryTokenInfo();
            String downloadurl = "";
            if (!tokenInfoList.isEmpty()) {
                TokenInfo tokenInfo = tokenInfoList.get(0);
                downloadurl = tokenInfo.getDownloadurl();
                HttpRequest httpRequest = HttpRequest.post(downloadurl)
                        .header("Content-Type", "application/json")
                        .header("Authorization", tokenVo.getTokenInfo());
                httpRequest.setGlobalTimeout(20000);
                response = httpRequest
                        .body(body)
                        .execute().body();

                if (StringUtils.isNotEmpty(response)) {
                    boolean isJson = JSONUtil.isJsonObj(response);
                    if (isJson) {
                        ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                        status = responseVo.getRetCode();
                        if (status.equals(StatusConstant.REQUEST_SUCCESS)) {

                            List<CorrforeSt> aList = new ArrayList<>();
                            log.info("请求短期修正数据返回内容:{}", response);

                            String dataContent = responseVo.getData();
                            if (!dataContent.contains("NULL") && !dataContent.contains("null")) {
                                try {
//                                    if (ElectricFieldTypeEnum.E1.toString().equals(tokenInfo.getStationType())) {
//                                        list = correctPhotovoltaicData(responseVo.getData());
//                                    } else {
////                                        list = correctWindData(responseVo.getData());
//                                    }

                                    /**************检测解析数据完整性*******************/
//                                    if (list.size() < count) {
//                                        status = StatusConstant.Correct_STATUS_DATA_LACK;
//                                        log.warn(el.getStationCode() + " 请求短期修正数据缺数: " + list.size());
//                                    } else {
//                                        result = true;
//                                        long amendTime = new Date().getTime();
//                                        for (CorrforeSt a : aList) {
//                                            List<CorrforeSt> collect = list.stream().filter(n -> n.getForecastTime().longValue() == a.getForecastTime().longValue()).collect(Collectors.toList());
//                                            if (CollectionUtil.isNotEmpty(collect)) {
//                                                AioForecastPowerShortTerm correct = collect.get(0);
//                                                a.setAmendTime(amendTime);
//                                                a.setFpValueAmend(correct.getFpValueAmend());
//                                                a.setSwrAmend(correct.getSwrAmend());
//                                                a.setDirectRadiationAmend(correct.getDirectRadiationAmend());
//                                                a.setDiffuseRadiationAmend(correct.getDiffuseRadiationAmend());
//                                                a.setWindspeedAmend(correct.getWindspeedAmend());
//                                                a.setWindDirAmend(correct.getWindDirAmend());
//                                                a.setTemperatureAmend(correct.getTemperatureAmend());
//                                                a.setHumidityAmend(correct.getHumidityAmend());
//                                                a.setPressureAmend(correct.getPressureAmend());
//
//                                            } else {
//                                                result = false;
//                                                status = StatusConstant.Correct_STATUS_DATA_LACK;
//                                                log.warn("请求短期修正数据缺数");
//                                                break;
//                                            }
//                                        }
//                                    }
                                    /**************检测解析数据完整性*******************/

                                } catch (Exception e) {
                                    status = StatusConstant.Correct_STATUS_DATA_FAIL;
//                                    log.info("========== 一体化: {} 解析期修正数据失败 {}  ==========", el.getStationCode(), type);
                                }
                            } else {
                                status = StatusConstant.Correct_STATUS_DATA_FAIL;
//                                log.info("========== 一体化: {} 解析期修正数据为完成 含NULL {}  ==========", el.getStationCode(), type);
                            }
                            if (result) {
//                                log.info("========== 一体化: {} 下载短期修正数据成功 {} ==========", el.getStationCode(), type);
//                                aioForecastPowerShortTermService.saveAll(aList);
                            }
                        } else {
                            log.error("========== 一体化: {} 下载短期修正数据失败 接收retCode响应码非成功标识T200 {} ==========", stationCode, type);
                            log.error("========== 一体化: {} {} 下载短期修正数据失败 接收retCode响应码非成功标识T200 标识为{} ==========", stationCode, type, status);
                            log.error("========== 一体化: {} {} 下载短期修正数据失败 接收retCode响应码非成功标识T200 失败原因为{} ==========", stationCode, type, responseVo.getRetMsg());
                            if (status.equals(StatusConstant.TOKEN_EXPIRE)) {
                                log.error("========== 一体化: {} 下载短期修正数据失败 token过期 已重新请求token ==========", stationCode);
                            }
                            if (status.equals(StatusConstant.TOKEN_INVALID)) {
                                log.error("========== 一体化: {} 上下载短期修正数据失败 token失效 已重新请求token ==========", stationCode);
                            }
                            if (status.equals(StatusConstant.AUTOGRAPH_FAIL)) {
                                log.error("========== 一体化: {} 下载短期修正数据失败 签名失败 已重新请求token ==========", stationCode);
                            }
                            if (responseVo.getRetCode().equals(StatusConstant.LOGIN_NOT)) {
                                log.error("========== 一体化: {} 下载短期修正数据失败 用户未登录 已重新请求token ==========", stationCode);
                            }
                        }
                    } else {
                        status = StatusConstant.RESPONSE_ERROR1;
                        log.error("========== 一体化:下载短期修正数据失败 接收响应字符串非json格式 " + response + " ==========");
                    }
                } else {
                    status = StatusConstant.RESPONSE_ERROR2;
                    log.error("========== 一体化:下载短期修正数据失败 返回响应内容为空 ==========");
                }
            }
        } catch (Exception e) {
            status = StatusConstant.RESPONSE_ERROR3;
            log.error("========== 一体化:下载短期修正数据失败 连接断开或请求超时 ==========");
            e.printStackTrace();

        }
        return status;
    }


    /**
     * 光伏数据解析
     *
     * @param data 待解析数据
     * @return
     * @throws Exception
     */
    public List<CorrforeSt> correctPhotovoltaicData(String data) throws Exception {
        String[] content = data.split("\n");
//        String dateStr = content[0].split("'")[1];
        List<CorrforeSt> list = new ArrayList<>();
        Date genDate = new Date();
        for (int i = 3; i < content.length - 1; i++) {
            CorrforeSt inForecastPowerShortTerm = new CorrforeSt();
            String column = content[i];
            String[] datas = column.split(ConnectConstant.SPACE1_CONSTANT);
            inForecastPowerShortTerm.setForecastTime(DateUtil.parse(datas[2], "yyyy-MM-dd HH:mm:ss").toTimestamp());
            inForecastPowerShortTerm.setFpValue(new BigDecimal(datas[3]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setGlobalR(new BigDecimal(datas[4]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setDirectR(new BigDecimal(datas[5]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setDiffuseR(new BigDecimal(datas[6]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setT(new BigDecimal(datas[7]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setRh(new BigDecimal(datas[8]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setP(new BigDecimal(datas[9]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setWs(new BigDecimal(datas[10]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setWd(new BigDecimal(datas[11]).setScale(2, BigDecimal.ROUND_DOWN));
            inForecastPowerShortTerm.setCreateTime(new Timestamp(genDate.getTime()));
            list.add(inForecastPowerShortTerm);
        }
        return list;
    }

//    /**
//     * 风电数据解析
//     *
//     * @param data 待解析数据
//     * @return 解析数据
//     * @throws Exception
//     */
//    public List<AioForecastPowerShortTerm> correctWindData(String data) throws Exception {
//
//        String[] content = data.split("\n");
//
//
//        String dateStr = content[0].split("'")[1];
//
//        List<AioForecastPowerShortTerm> list = new ArrayList<>();
//
//        Date genDate = new Date();
//
//        if (content[1].contains("CorrectForecast")) {
//
//
//            for (int i = 3; i < content.length - 1; i++) {
//
//                AioForecastPowerShortTerm inForecastPowerShortTerm = new AioForecastPowerShortTerm();
//                String column = content[i];
//
//                String[] datas = column.split(ConnectConstant.SPACE1_CONSTANT);
//
//                inForecastPowerShortTerm.setForecastTime(DateUtil.parse(datas[2], "yyyyMMddHHmmss").getTime());
//
//                inForecastPowerShortTerm.setFpValue(isNumber(datas[3]));
//
//                inForecastPowerShortTerm.setWindspeed(isNumber(datas[4]));
//
//                inForecastPowerShortTerm.setWindDir(isNumber(datas[5]));
//
//                inForecastPowerShortTerm.setTemperature(isNumber(datas[6]));
//
//                inForecastPowerShortTerm.setHumidity(isNumber(datas[7]));
//
//                inForecastPowerShortTerm.setPressure(isNumber(datas[8]));
//
//                inForecastPowerShortTerm.setAmendTime(genDate.getTime());
//
//                list.add(inForecastPowerShortTerm);
//            }
//        } else {
//            log.error("解析一体化修正短期异常:{}", "标识错误不为<CorrectForecast>");
//
//        }
//
//
//        return list;
//
//    }

    /**
     * 判断是否是数值
     *
     * @param data
     * @return
     */
    public BigDecimal isNumber(String data) {
        BigDecimal bigDecimal = null;
        Pattern pattern = Pattern.compile("-[0-9]+(.[0-9]+)?|[0-9]+(.[0-9]+)?");
        Matcher isNum = pattern.matcher(data);
        try {
            if (isNum.matches()) {
                bigDecimal = new BigDecimal(data).setScale(2, BigDecimal.ROUND_DOWN);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return bigDecimal;
    }

}
