package com.cpp.web.controller.regulation;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cpp.common.core.domain.R;
import com.cpp.common.utils.DateUtils;
import com.cpp.web.domain.station.ElectricField;
import com.cpp.web.domain.station.ForecastPowerShortTermRegulation;
import com.cpp.web.domain.station.PowerStationStatusData;
import com.cpp.web.domain.station.WeatherStationStatusData;
import com.cpp.web.dto.DqHistoryContrastDto;
import com.cpp.web.dto.TableColumn;
import com.cpp.web.service.station.ElectricFieldService;
import com.cpp.web.service.station.ForecastPowerShortTermRegulationService;
import com.cpp.web.service.station.PowerStationStatusDataService;
import com.cpp.web.service.station.WeatherStationStatusDataService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 短期历史对比
 *
 * @author whc
 * @date 2022-03-18 15:49:50
 */
@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("/dqHistoryContrastController")
public class DqHistoryContrastController {
    @Autowired
    ElectricFieldService electricFieldService;
    @Autowired
    PowerStationStatusDataService powerStationStatusDataService;
    @Autowired
    ForecastPowerShortTermRegulationService forecastPowerShortTermRegulationService;

    private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

    @ApiOperation(value = "根据条件查询", notes = "分页查询")
    @GetMapping("/queryTableData")
    public R queryTableData(String stationCode, Long startTime, Long endTime) {
        Map map = new HashMap();
        ElectricField electricField = electricFieldService.findByStationCode(stationCode);
        String stationName = electricField.getName();
        // 查询实际功率
        QueryWrapper<PowerStationStatusData> powerStationStatusDataWrapper = new QueryWrapper<>();
        powerStationStatusDataWrapper.between("time", new Date(startTime), new Date(endTime));
        powerStationStatusDataWrapper.eq("station_code", stationCode);
        List<PowerStationStatusData> powerStationStatusDataList = powerStationStatusDataService.list(powerStationStatusDataWrapper);
        Map<Long, PowerStationStatusData> sjMap = new HashMap<>();
        for (PowerStationStatusData powerStationStatusData : powerStationStatusDataList) {
            sjMap.put(powerStationStatusData.getTime().getTime(), powerStationStatusData);
        }
        // 查询上报短期
        List<ForecastPowerShortTermRegulation> forecastPowerShortTermRegulationList = forecastPowerShortTermRegulationService.findByForecastTimeBetweenAndForecastHowLongAgoAndStationCode(startTime, endTime, 1, stationCode);
        Map<Long, ForecastPowerShortTermRegulation> dqsbMap = new HashMap<>();
        for (ForecastPowerShortTermRegulation forecastPowerShortTermRegulation : forecastPowerShortTermRegulationList) {
            dqsbMap.put(forecastPowerShortTermRegulation.getTime().getTime(), forecastPowerShortTermRegulation);
        }
        // 整合页面列表字段
        Long momentTime = 15 * 60 * 1000L;
        List<DqHistoryContrastDto> tableList = new ArrayList();
        // 定义x轴底部时间
        List<String> xAxisBottomList = new ArrayList<>();
        // 定义短期偏差曲线数组
        List<Object> dqpcLineList = new ArrayList<>();
        // 定义短期偏差比曲线数组
        List<Object> ratioLineList = new ArrayList<>();


        for (Long tempTime = startTime; tempTime <= endTime; tempTime = tempTime + momentTime) {
            xAxisBottomList.add(DateUtils.parseDateToStr("MM-dd HH:mm", new Date(tempTime)));
            DqHistoryContrastDto dqHistoryContrastDto = new DqHistoryContrastDto();
            dqHistoryContrastDto.setStationName(stationName);
            // 设置时间
            String time = DateUtils.parseDateToStr("yyyy-MM-dd HH:mm", new Date(tempTime));
            dqHistoryContrastDto.setTime(time);
            if (sjMap.get(tempTime) != null) {
                PowerStationStatusData powerStationStatusData = sjMap.get(tempTime);
                dqHistoryContrastDto.setOpenCapacity(powerStationStatusData.getOpenCapacity().toString());
                dqHistoryContrastDto.setRealValue(powerStationStatusData.getRealValue().toString());
            }
            if (dqsbMap.get(tempTime) != null) {
                ForecastPowerShortTermRegulation forecastPowerShortTermRegulation = dqsbMap.get(tempTime);
                dqHistoryContrastDto.setDqValue(forecastPowerShortTermRegulation.getFpValue().toString());
            }
            // 计算短期与实际功率偏差及偏差比
            if (StrUtil.isNotBlank(dqHistoryContrastDto.getDqValue()) && StrUtil.isNotBlank(dqHistoryContrastDto.getRealValue())) {
                // 偏差（短期-实际功率）
                BigDecimal dqValue = new BigDecimal(dqHistoryContrastDto.getDqValue());
                BigDecimal realValue = new BigDecimal(dqHistoryContrastDto.getRealValue());
                dqHistoryContrastDto.setDqDeviation(dqValue.subtract(realValue).toString());
                // 先判断实际功率是否为0，为0则偏差比为空
                BigDecimal ratio = null;
                String ratioStr = "";
                if (realValue.compareTo(new BigDecimal("0")) == 0) {
                } else {
                    ratio = dqValue.subtract(realValue).divide(realValue, 3, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal("100")).stripTrailingZeros();
                    if (ratio.compareTo(new BigDecimal("0")) >= 0) {
                        ratioStr = "+" + ratio.toPlainString() + "%";
                    } else {
                        ratioStr = ratio.toPlainString() + "%";
                    }
                }
                dqHistoryContrastDto.setDqDeviationRatio(ratioStr);
                dqpcLineList.add(dqHistoryContrastDto.getDqDeviation());
                ratioLineList.add(ratio);
            } else {
                dqpcLineList.add("");
                ratioLineList.add("");
                dqHistoryContrastDto.setDqDeviation("");
                dqHistoryContrastDto.setDqDeviationRatio("");
            }
            tableList.add(dqHistoryContrastDto);
        }
        map.put("tableList", tableList);
        map.put("dqpcLineList", dqpcLineList);
        map.put("ratioLineList", ratioLineList);
        map.put("xAxisBottomList", xAxisBottomList);

        return R.ok(map);

    }

    @GetMapping("/export")
    public void export(String stationCode, Long startTime, Long endTime, HttpServletResponse response) {
        BufferedOutputStream bos = null;
        Map map = new HashMap();
        try {

            StringBuilder templateContent = new StringBuilder();
            response.setCharacterEncoding("UTF-8");
            map = (Map) queryTableData(stationCode, startTime, endTime).getData();
            List<DqHistoryContrastDto> tableList = (List<DqHistoryContrastDto>) map.get("tableList");
            List<TableColumn> tableColumns = getTableColumn();

            String header = "";
            StringBuilder content = new StringBuilder();

            for (TableColumn tableColumn : tableColumns) {
                header += "\"" + tableColumn.getTitle() + "\",";
            }

            for (DqHistoryContrastDto dqHistoryContrastDto : tableList) {
                for (TableColumn tableColumn : tableColumns) {
                    if ("time".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getTime()+ ",");
                    }
                    if ("stationName".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getStationName() + ",");
                    }
                    if ("openCapacity".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getOpenCapacity() + ",");
                    }
                    if ("realValue".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getRealValue() + ",");
                    }
                    if ("dqValue".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getDqValue() + ",");
                    }
                    if ("dqDeviation".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getDqDeviation() + ",");
                    }
                    if ("dqDeviationRatio".equals(tableColumn.getField())){
                        content.append(dqHistoryContrastDto.getDqDeviationRatio() + ",");
                    }
                }
                content.append("\r\n");
            }

            header += "\r\n";
            templateContent.append(header);

            templateContent.append(content.toString());

            String fileName = "";
            if (sdf.format(startTime).equals(sdf.format(endTime))) {
                fileName = sdf.format(startTime) + "短期历史对比" + ".csv";
            } else {
                fileName = sdf.format(startTime) + "至" + sdf.format(endTime) + "短期历史对比" + ".csv";
            }

            response.setContentType("application/x-msdownload;charset=UTF-8");
            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            byte[] templateContentBytes = templateContent.toString().getBytes("UTF-8");
            bos = new BufferedOutputStream(response.getOutputStream());
            bos.write(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF});
            bos.write(templateContentBytes);
            response.flushBuffer();

        } catch (Exception e) {
            log.error("系统错误：" + e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            if (bos != null) {
                try {
                    bos.close();
                } catch (IOException e) {
                    log.error("系统错误：" + e.getMessage(), e);
                }
            }
        }

    }

    /**
     * 获取表头
     *
     * @return
     */
    public List<TableColumn> getTableColumn() {
        List<TableColumn> tableColumns = new ArrayList<>();
        tableColumns.add(new TableColumn("time", "时间"));
        tableColumns.add(new TableColumn("stationName", "场站名称"));
        tableColumns.add(new TableColumn("openCapacity", "开机容量(MW)"));
        tableColumns.add(new TableColumn("realValue", "实际功率(MW)"));
        tableColumns.add(new TableColumn("dqValue", "短期预测功率(MW)"));
        tableColumns.add(new TableColumn("dqDeviation", "短期预测偏差(MW)"));
        tableColumns.add(new TableColumn("dqDeviationRatio", "短期预测偏差比(%)"));
        return tableColumns;
    }
}
