package com.cpp.web.controller.accuracy;

import com.cpp.common.core.domain.R;
import com.cpp.web.domain.accuracy.AccuracyPassRate;
import com.cpp.web.domain.enums.DataSourcesEnum;
import com.cpp.web.domain.enums.ForecastTypeEnum;
import com.cpp.web.dto.TableColumn;
import com.cpp.web.service.accuracy.AccuracyPassRateService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

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

@RestController
@RequiredArgsConstructor
@Slf4j
@RequestMapping("accuracyPassRate")
public class AccuracyPassRateController {
    private final AccuracyPassRateService accuracyPassRateService;

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

    @GetMapping("/getByTimeBetweenAndForecastTypeAndDataSourcesAndForecastModelAndStationCode")
    public R getByTimeBetweenAndForecastTypeAndDataSourcesAndForecastModelAndStationCode(Long startTime, Long endTime, ForecastTypeEnum forecastType, DataSourcesEnum dataSources, Integer ago, String forecastModel, String stationCode) {
        List<AccuracyPassRate> accuracyPassRateList = accuracyPassRateService.findByTimeBetweenAndForecastTypeAndDataSourcesAndAgoAndForecastModelAndStationCode(new Date(startTime), new Date(endTime), forecastType, dataSources, ago, forecastModel, stationCode);
        return R.ok(accuracyPassRateList);
    }

    @GetMapping("/getByMonthBetweenAndForecastTypeAndStationCode")
    public R getByMonthBetweenAndForecastTypeAndStationCode(Long startTime, Long endTime, ForecastTypeEnum forecastType, DataSourcesEnum dataSources, String stationCode) {
        Map<String, Double> map = accuracyPassRateService.findByMonthBetweenAndForecastTypeAndStationCode(startTime, endTime, forecastType, dataSources, stationCode);
        return R.ok(map);
    }

    @GetMapping("/getBySingleMonthBetweenAndForecastTypeAndStationCode")
    public R getBySingleMonthBetweenAndForecastTypeAndStationCode(Long startTime, Long endTime, ForecastTypeEnum forecastType, DataSourcesEnum dataSources, String stationCode, String stationName, String uploadDataSources) {
        List<Map<String, String>> accuracyPassRateList = accuracyPassRateService.finfBySingleMonthBetweenAndForecastTypeAndStationCode(startTime, endTime, forecastType, dataSources, stationCode, stationName, uploadDataSources);
        return R.ok(accuracyPassRateList);
    }

    @GetMapping("/export")
    public void export(Long startTime, Long endTime, ForecastTypeEnum forecastType, DataSourcesEnum dataSources, String stationCode, String stationName, String uploadDataSources, HttpServletResponse response) {

        BufferedOutputStream bos = null;
        List<Map<String, String>> mapList = new ArrayList<>();
        try {

            StringBuilder templateContent = new StringBuilder();
            response.setCharacterEncoding("UTF-8");
            mapList = accuracyPassRateService.finfBySingleMonthBetweenAndForecastTypeAndStationCode(startTime, endTime, forecastType, dataSources, stationCode, stationName, uploadDataSources);

            List<TableColumn> tableColumns = getTableColumn();

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

            for (TableColumn tableColumn : tableColumns) {
                header += "\"" + tableColumn.getTitle() + "\",";
            }
            for (Map<String, String> tableData : mapList) {
                for (TableColumn tableColumn : tableColumns) {
                    if (tableColumn.getField().equals("month")){
                        content.append("\t"+tableData.get(tableColumn.getField()) + ",");
                    }else {
                        content.append(tableData.get(tableColumn.getField()) + ",");
                    }

                }
                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("station", "场站"));
        tableColumns.add(new TableColumn("month", "月份"));
        tableColumns.add(new TableColumn("preModels", "预测模型"));
        tableColumns.add(new TableColumn("shortAccuracy", "短期准确率(%)"));
        tableColumns.add(new TableColumn("uploadShortAccuracy", "上报文件短期准确率(%)"));
        tableColumns.add(new TableColumn("accuracyRanking", "准确率排名"));
        return tableColumns;
    }

}
