package com.jiayue.insu.inclientqn.service.client;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.insu.inclientqn.constant.CommonStant;
import com.jiayue.insu.inclientqn.constant.TemplateStant;
import com.jiayue.insu.inclientqn.entity.*;
import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
import com.jiayue.insu.inclientqn.inenum.StatusEnum;
import com.jiayue.insu.inclientqn.model.RequestVo;
import com.jiayue.insu.inclientqn.model.ResponseVo;
import com.jiayue.insu.inclientqn.permisson.com.ComPermisson;
import com.jiayue.insu.inclientqn.service.*;
import com.jiayue.insu.inclientqn.service.client.BackDataGenService;
import com.jiayue.insu.inclientqn.util.RequestUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.stream.Collectors;


/**
 * @description: 回传数据请求
 * @author: yuanhao
 * @createDate: 2022/6/17
 * @version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
@RefreshScope
public class RequestDataService {


    private final BackDataGenService backDataGenService;

    private final BackDataGenBodyService backDataGenBodyService;

    private final StationService stationService;

    private final ComPermisson comPermisson;

    private final RecordService recordService;

    private final BackStatDataService backStatDataService;


    private final BackForeUsForecastDataService backForeUsForecastDataService;

    private final BackForeForecastDataService backForeForecastDataService;


    public void requestBackStat(long signTime) {
        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);

        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_BACK_DATA);
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());
        record.setContent(QNHLEnum.DATA_STAT_ALL.getCode());

        Station station = stationService.findThis();
        StringBuilder stringBuilder = new StringBuilder();
        List<BackStatData> backStatDatas = backStatDataService.findBySignTime(localDateTime);
        if (CollectionUtil.isNotEmpty(backStatDatas)) {
            String header = StrUtil.format(TemplateStant.HEADER_TEMPLATE, station.getSignCode(), DateUtil.parse(DateUtil.now()).toString("yyyy-MM-dd HH:mm:ss"));
            stringBuilder.append(header);

            stringBuilder.append(backDataGenBodyService.genStateRealPowerData(backStatDatas));
            stringBuilder.append(backDataGenBodyService.genStateRealWeatherData(station.getType(), backStatDatas));
            stringBuilder.append(backDataGenBodyService.genStateForecastPowerReport(backStatDatas));
            stringBuilder.append(backDataGenBodyService.genStateUltraShortTermForecastReport(backStatDatas));

            RequestVo requestVo = RequestVo.UPLOAD_STAT(station.getSignCode(), stringBuilder.toString(), signTime);

            //校验请求数据是否为null  和  token是否有效
            if (comPermisson.isToken(station)) {
                JSONObject json = JSONUtil.parseObj(requestVo, true);
                String body = json.toString();
                String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());

                if (RequestUtils.checkResponse(response, record)) {

                    ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                    String code = responseVo.getRetCode();

                    if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {

                        record.setState(StatusEnum.SUCCESS.getSign());
                        record.setStateContent(responseVo.getRetMsg());

                        BackStatData backStatData = backStatDatas.get(0);

                        backStatData.setBackTime(LocalDateTime.now());

                        try {
                            backStatDataService.saveOrUpdate(backStatData);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    } else {
                        record.setState(code);
                        record.setStateContent(responseVo.getRetMsg());
                    }
                }

            } else {
                record.setState(QNHLEnum.PERMISSON_TOKEN_INVALID.getCode());
                record.setStateContent(QNHLEnum.PERMISSON_TOKEN_INVALID.getMsg());
            }


        }else{
            record.setState(StatusEnum.DATA_DEFICIENCY.getCode());
            record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
        }

        recordService.save(record);
    }


    public void requestBackFore(long signTime) {
        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);
        LocalDateTime beginDay = LocalDateTimeUtil.beginOfDay(localDateTime);

        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_BACK_DATA);
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());
        record.setContent(QNHLEnum.DATA_FORE_ALL.getCode());

        Station station = stationService.findThis();
        StringBuilder stringBuilder = new StringBuilder();
        String header = StrUtil.format(TemplateStant.HEADER_TEMPLATE, station.getSignCode(), DateUtil.parse(DateUtil.now()).toString("yyyy-MM-dd HH:mm:ss"));
        stringBuilder.append(header);

        List<BackForeUsForecastData> uList = backForeUsForecastDataService.findBySignTime(localDateTime);

        List<BackForeForecastData> list = backForeForecastDataService.findBySignTime(beginDay);

        String stateContent = "";

        if (CollectionUtil.isNotEmpty(uList)) {
            stringBuilder.append(backDataGenBodyService.genForeUltraShortTermForecast(station.getType(),uList));

            uList.forEach(u->u.setBackTime(LocalDateTime.now()));
            stateContent+="cdq,";
        }

        if (CollectionUtil.isNotEmpty(list)) {
            //当数据有回传记录则不再回传
            List<BackForeForecastData> fList = list.stream().filter(b -> b.getBackTime() == null).collect(Collectors.toList());
            if(CollectionUtil.isNotEmpty(fList)){
                stringBuilder.append(backDataGenBodyService.genForeForecast(list));
                list.forEach(u->u.setBackTime(LocalDateTime.now()));
                stateContent+="dq,";
            }

        }

        RequestVo requestVo = RequestVo.UPLOAD_FORE(station.getSignCode(), stringBuilder.toString(), signTime);
        //校验请求数据是否为null  和  token是否有效
        if ((CollectionUtil.isNotEmpty(uList) || CollectionUtil.isNotEmpty(list)) && comPermisson.isToken(station)) {
            JSONObject json = JSONUtil.parseObj(requestVo, true);
            String body = json.toString();
            String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());

            if (RequestUtils.checkResponse(response, record)) {

                ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                String code = responseVo.getRetCode();

                if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {

                    record.setState(StatusEnum.SUCCESS.getSign());
                    record.setStateContent(stateContent);


                    try {
                        backForeUsForecastDataService.saveOrUpdateBatch(uList);
                        backForeForecastDataService.saveOrUpdateBatch(list);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } else {
                    record.setState(code);
                    record.setStateContent(responseVo.getRetMsg());
                }
            }

        } else {
            record.setState(StatusEnum.DATA_DEFICIENCY.getSign());
            record.setStateContent(StatusEnum.DATA_DEFICIENCY.getMsg());
        }

        recordService.save(record);
    }

    /**
     * 回传统计数据
     *
     * @param qnhlEnum 类型
     * @param signTime 标记时间
     */
    public void requestBackStatData(QNHLEnum qnhlEnum, long signTime) {

        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);

        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_BACK_DATA);
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());
        record.setContent(qnhlEnum.getCode());


        Station station = stationService.findThis();


        List<BackStatData> backStatDatas = backStatDataService.findBySignTime(localDateTime);

        RequestVo requestVo = null;
        try {

            switch (qnhlEnum.getCode()) {
                case "RealPower":
                    requestVo = backDataGenService.genStateRealPowerData(station.getSignCode(), signTime, backStatDatas);
                    break;
                case "RealWeather":
                    requestVo = backDataGenService.genStateRealWeatherData(station.getSignCode(), station.getType(), signTime, backStatDatas);
                    break;
                case "ForecastPowerReport":
                    requestVo = backDataGenService.genStateForecastPowerReport(station.getSignCode(), signTime, backStatDatas);
                    break;
                case "UltraShortTermForecastReport":
                    requestVo = backDataGenService.genStateUltraShortTermForecastReport(station.getSignCode(), signTime, backStatDatas);
                    break;
            }

        } catch (Exception e) {
            e.printStackTrace();
            record.setState(StatusEnum.BACK_DATA_GEN_FAIL.getSign());
            record.setStateContent(StatusEnum.BACK_DATA_GEN_FAIL.getMsg());
        }
        //校验请求数据是否为null  和  token是否有效
        if (requestVo != null && comPermisson.isToken(station)) {
            JSONObject json = JSONUtil.parseObj(requestVo, true);
            String body = json.toString();
            System.out.println("----------------------------------------------------------------------");
            System.out.println(body);
            System.out.println("----------------------------------------------------------------------");
            String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());

            if (RequestUtils.checkResponse(response, record)) {

                ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                String code = responseVo.getRetCode();

                if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {

                    record.setState(StatusEnum.SUCCESS.getSign());
                    record.setStateContent(responseVo.getRetMsg());

                    BackStatData backStatData = backStatDatas.get(0);

                    switch (qnhlEnum.getCode()) {

                        case "RealPower":
                            backStatData.setBackTimeRealPower(LocalDateTime.now());
                            break;
                        case "RealWeather":
                            backStatData.setBackTimeRealWeather(LocalDateTime.now());
                            break;
                        case "ForecastPowerReport":
                            backStatData.setBackTimeForecastReport(LocalDateTime.now());
                            break;
                        case "UltraShortTermForecastReport":
                            backStatData.setBackTimeUsForecastReport(LocalDateTime.now());
                            break;
                    }

                    try {
                        backStatDataService.saveOrUpdate(backStatData);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } else {
                    record.setState(code);
                    record.setStateContent(responseVo.getRetMsg());
                }
            }

        } else {
            record.setState(StatusEnum.BACK_DATA_GEN_FAIL.getSign());
            record.setStateContent("token失效或请求体为null");
        }


        recordService.save(record);
    }

    /**
     * 回传超短期数据
     *
     * @param qnhlEnum 类型
     * @param signTime 标记时间
     */
    public void requestBackForeUsData(QNHLEnum qnhlEnum, long signTime) {

        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);

        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_BACK_DATA);
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());
        record.setContent(qnhlEnum.getCode());


        Station station = stationService.findThis();

        List<BackForeUsForecastData> list = backForeUsForecastDataService.findBySignTime(localDateTime);

        RequestVo requestVo = null;
        try {
            requestVo = backDataGenService.genForeUltraShortTermForecast(station.getSignCode(), station.getType(), signTime, list);

        } catch (Exception e) {
            e.printStackTrace();
        }


        if (requestVo != null && comPermisson.isToken(station)) {
            JSONObject json = JSONUtil.parseObj(requestVo, true);
            String body = json.toString();
            System.out.println("----------------------------------------------------------------------");
            System.out.println(body);
            System.out.println("----------------------------------------------------------------------");
            String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());

            if (RequestUtils.checkResponse(response, record)) {
                ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                String code = responseVo.getRetCode();

                if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {

                    record.setState(StatusEnum.SUCCESS.getSign());
                    record.setStateContent(responseVo.getRetMsg());

                    list.forEach(f -> f.setBackTime(LocalDateTime.now()));

                    try {
                        backForeUsForecastDataService.saveOrUpdateBatch(list);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } else {
                    record.setState(code);
                    record.setStateContent(responseVo.getRetMsg());
                }
            }


        } else {
            record.setState(StatusEnum.BACK_DATA_GEN_FAIL.getSign());
            record.setStateContent("token失效或请求体为null");
        }

        recordService.save(record);
    }


    /**
     * 回传短期数据
     *
     * @param qnhlEnum 类型
     * @param signTime 标记时间
     */

    public void requestBackForeData(QNHLEnum qnhlEnum, long signTime) {

        LocalDateTime localDateTime = LocalDateTimeUtil.of(signTime);
        LocalDateTime beginDay = LocalDateTimeUtil.beginOfDay(localDateTime);
        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_BACK_DATA);
        record.setTime(beginDay);
        record.setCreateTime(LocalDateTime.now());
        record.setContent(qnhlEnum.getCode());


        Station station = stationService.findThis();

        List<BackForeForecastData> list = backForeForecastDataService.findBySignTime(beginDay);

        RequestVo requestVo = null;
        try {
            requestVo = backDataGenService.genForeForecast(station.getSignCode(), signTime, list);

        } catch (Exception e) {
            e.printStackTrace();
        }


        if (requestVo != null && comPermisson.isToken(station)) {
            JSONObject json = JSONUtil.parseObj(requestVo, true);
            String body = json.toString();
            System.out.println("----------------------------------------------------------------------");
            System.out.println(body);
            System.out.println("----------------------------------------------------------------------");
            String response = RequestUtils.post(station.getBackurl(), body, station.getComKey());

            if (RequestUtils.checkResponse(response, record)) {
                ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
                String code = responseVo.getRetCode();

                if (code.equals(QNHLEnum.REQUEST_SUCCESS.getCode())) {

                    record.setState(StatusEnum.SUCCESS.getSign());
                    record.setStateContent(responseVo.getRetMsg());

                    list.forEach(f -> f.setBackTime(LocalDateTime.now()));

                    try {
                        backForeForecastDataService.saveOrUpdateBatch(list);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } else {
                    record.setState(code);
                    record.setStateContent(responseVo.getRetMsg());
                }
            }


        } else {
            record.setState(StatusEnum.BACK_DATA_GEN_FAIL.getSign());
            record.setStateContent("token失效或请求体为null");
        }

        recordService.save(record);
    }


}
