package com.jiayue.insu.inclientqn.pushData;

import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.insu.inclientqn.constant.CommonStant;
import com.jiayue.insu.inclientqn.entity.BackForeUsForecastData;
import com.jiayue.insu.inclientqn.entity.BackStatData;
import com.jiayue.insu.inclientqn.entity.Record;
import com.jiayue.insu.inclientqn.entity.Station;
import com.jiayue.insu.inclientqn.inenum.QNHLEnum;
import com.jiayue.insu.inclientqn.inenum.StatusEnum;
import com.jiayue.insu.inclientqn.model.ResponseVo;
import com.jiayue.insu.inclientqn.service.BackForeUsForecastDataService;
import com.jiayue.insu.inclientqn.service.BackStatDataService;
import com.jiayue.insu.inclientqn.service.RecordService;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.time.*;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

@Slf4j
@RefreshScope
@Component
public class PushRealValueData implements IPushRealValueData {

    @Autowired
    private RecordService recordService;
    @Autowired
    private BackForeUsForecastDataService backForeUsForecastDataService;
    @Autowired
    private BackStatDataService backStatDataService;

    /**
     * 推送原始超短期数据给一体化云端
     *
     * @return
     */
    @Override
    public boolean pushRealValueForJy(Station station, LocalDateTime signTime) {

        // 获取场站编号
        String stationCode = station.getStationCode();
        Record record = new Record();
        record.setStationCode(station.getStationCode());
        record.setTime(signTime);
        record.setCreateTime(LocalDateTime.now());
        record.setType(CommonStant.RECORD_TYPE_REAL_VALUE_FOR_JY);
        record.setContent(QNHLEnum.DATA_REALVALUE_TYPE.getCode());
        log.info("开始给一体化云端推送昨日实际功率数据 --> {}" + station.getStationCode());
        // 如果场站编号为空，则返回
        if (stationCode == null || "".equals(stationCode)) {
            record.setState(StatusEnum.STATION_CODE_NULL.getSign());
            record.setStateContent(StatusEnum.STATION_CODE_NULL.getMsg());
            recordService.save(record);
            return false;
        }


        // 获取昨天的日期
        LocalDate yesterday = LocalDate.now().minusDays(1);

        // 获取今天的00:00:00作为昨天的开始时间
        LocalDateTime startOfYesterday = LocalDateTime.of(yesterday, LocalTime.MIDNIGHT);

        LocalDateTime endOfYesterday = LocalDateTime.of(yesterday, LocalTime.MAX);

        // 指定时区，例如系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();

        // 将 LocalDateTime 转换为 ZonedDateTime
        ZonedDateTime zonedDateTime = signTime.atZone(zoneId);

        // 将 ZonedDateTime 转换为 Instant，Instant 可以获取到时间戳
        Instant instant = zonedDateTime.toInstant();

        // 获取时间戳（毫秒）
        long timestamp = instant.toEpochMilli();

        List<DataPointDTO> list = new ArrayList<>();
        // 查询所需回传实际功率
        List<BackStatData> backStatDataList = backStatDataService.findBySignTimeBetween(startOfYesterday, endOfYesterday);
        if (backStatDataList.size() > 0) {
            for (BackStatData backStatData : backStatDataList) {
                DataPointDTO dto = new DataPointDTO();
                if (null != backStatData.getSignTime()){
                    zonedDateTime = backStatData.getSignTime().atZone(ZoneId.systemDefault());
                    // 将ZonedDateTime转换为Instant
                    instant = zonedDateTime.toInstant();
                    // 获取时间戳（毫秒）
                    Long forecastTime = instant.toEpochMilli();
                    dto.setForecastTime(forecastTime.toString() == null ? String.valueOf(new Date().getTime()) : forecastTime.toString());
                    dto.setFpValue(backStatData.getRealPower() == null ? BigDecimal.ZERO.toString() : backStatData.getRealPower().toString());
                    list.add(dto);
                }
            }
        }
//        if (list.size() < 288) {
//            log.error("实际功率：{}条，条数不符合要求，不进行上送", list.size());
//            return false;
//        }
        String jyUrl = "http://49.4.68.219:8801/pfserver/putRealValueData";
        BackRealValueDto backRealValueDto = new BackRealValueDto(stationCode, String.valueOf(timestamp), list);
        JSONObject json = JSONUtil.parseObj(backRealValueDto, false);
        String body = json.toString();
        try {
            String credentials = station.getUsername() + ":" + station.getPassword();
            // Base64编码
            String encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes());
            String response;
            HttpRequest httpRequest = HttpRequest.post(jyUrl)
                    .header("Content-Type", "application/json")
                    .header("Authorization", "Basic " + encodedCredentials);
            httpRequest.setGlobalTimeout(20000);
            response = httpRequest.body(body).execute().body();

            ResponseVo responseVo = JSONUtil.toBean(response, ResponseVo.class);
            if (responseVo.getRetCode().equals("200")) {
                record.setState(StatusEnum.SUCCESS.getSign());
                record.setStateContent("嘉越云" + responseVo.getRetMsg());
                log.info("=========={}:{} ==>上送实际功率数据成功  {}条==========", station.getName(), station.getStationCode(), list.size());
                log.info("{} 原始数据:{}", stationCode, body);
                recordService.save(record);
                return true;
            } else {
                log.error("=========={}:{} ==>上送数据失败 失败标识:{} ,失败原因：{} ==========", station.getName(), station.getStationCode(), responseVo.getRetCode(), responseVo.getRetMsg());
                log.info("{} 原始数据:{}", stationCode, body);
                record.setState(StatusEnum.FILE_NULL.getSign());
                record.setStateContent(responseVo.getRetMsg());
                recordService.save(record);
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }


    @Data
    public class BackRealValueDto {

        public BackRealValueDto(String stationIds, String genDate, List<DataPointDTO> data) {
            this.stationIds = stationIds;
            this.genDate = genDate;
            this.data = data;
        }

        /**
         * id
         */
        private String stationIds;
        /**
         * 生成日期
         */
        private String genDate;

        /**
         * 预测时间和数据
         */
        private List<DataPointDTO> data;

    }

    @Data
    public static class DataPointDTO {
        private String fpValue;
        private String forecastTime;
    }
}