package com.jiayue.insu.inclientqn.pulldata;

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.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.jiayue.insu.inclientqn.constant.CommonStant;
import com.jiayue.insu.inclientqn.entity.BJZYYJYSDCorrfore;
import com.jiayue.insu.inclientqn.entity.Record;
import com.jiayue.insu.inclientqn.entity.Station;
import com.jiayue.insu.inclientqn.inenum.StatusEnum;
import com.jiayue.insu.inclientqn.model.FileCreateLog;
import com.jiayue.insu.inclientqn.service.ApiService;
import com.jiayue.insu.inclientqn.service.ForecastDataService;
import com.jiayue.insu.inclientqn.service.RecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

import java.io.*;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 拉取原始预测数据业务
 *
 * @author yh
 * @version 1.0
 * @since 2022/5/22 11:29
 */
@Component
@Slf4j
@RefreshScope
public class PullInitData implements IPullInitForecastData {

    @Autowired
    private RecordService recordService;
    @Autowired
    private ForecastDataService forecastDataService;
    @Autowired
    private ApiService apiService;
    @Value("${minio.pull.url}")
    String url;
    @Value("${minio.pull.fileurl}")
    String fileurl;
    @Value("${minio.fileurl}")
    String fileDir;

    /**
     * 拉取短期原始预测数据
     * @param station 场站信息
     */
    @Override
    public List<BJZYYJYSDCorrfore> pullDQData(Station station) {

        Record record = new Record();
        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
        record.setStationCode(station.getStationCode());
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());
        record.setType(CommonStant.RECORD_TYPE_PULL_INIT);
        log.info("下载minio原始RB文件 --> {}" + station.getStationCode());
        List<BJZYYJYSDCorrfore> listNow = new ArrayList<>();
        try {
            HttpRequest httpRequest = HttpRequest.get(url + station.getStationCode());
            httpRequest.setGlobalTimeout(20000);
            String body = httpRequest.execute().body();
            JSONObject json = JSONUtil.parseObj(body);
            String code = json.get("code").toString();
            String data = json.get("data").toString();
            if (code.equals("0") && data.length() > 0) {
                JSONArray array = JSONUtil.parseArray(data);
                List<FileCreateLog> list = array.toList(FileCreateLog.class);
                List<FileCreateLog> dqListNow = new ArrayList<>();
                String dateNow = DateUtil.format(new Date(), "yyyyMMdd");
                if (CollectionUtil.isNotEmpty(list)) {
                    dqListNow = list.stream().filter(f -> f.getFileName().contains("DQ_" + dateNow)).collect(Collectors.toList());
                    if (CollectionUtil.isNotEmpty(dqListNow)) {
                        // 降序
                        dqListNow.sort(Comparator.comparing(FileCreateLog::getFileName).reversed());
                        File dqNowFile = null;
                        String fileSaveUrl = fileDir + File.separatorChar + "init" + File.separatorChar + station.getStationCode();
                        log.info(fileSaveUrl);
                        File dir = new File(fileSaveUrl);
                        // 判断目录是否存在
                        if (!dir.exists()) {
                            dir.mkdirs();
                            log.info("创建目录:" + fileSaveUrl);
                        }

                        try {
                            String dqNowUrl = fileurl + dqListNow.get(0).getId();
                            dqNowFile = HttpUtil.downloadFileFromUrl(dqNowUrl, fileSaveUrl + File.separatorChar + dqListNow.get(0).getFileName());

                            if (dqNowFile != null) {
                                // 回传dq文件状态
                                apiService.postBackMinIoState(station.getStationCode(), dqNowFile.getName(), "down", "是");
                                //解析
                                listNow = fileAnalysis(dqNowFile, station, localDateTime);

                                if (CollectionUtil.isNotEmpty(listNow)) {
//                                    //删除该时间段内数据
//                                    forecastDataService.removeBetweenTimeByStation(station.getStationCode(),listNow.get(0).getForecastTime(),listNow.get(listNow.size() - 1).getForecastTime());
//                                    forecastDataService.saveBatch(listNow);
                                    String fileName = dqNowFile.getName();
                                    record.setContent(fileName);
                                    record.setState(StatusEnum.SUCCESS.getCode());
                                    record.setStateContent(String.valueOf(listNow.size()));
                                    log.info(station.getStationCode() + " 存入初始化数据:" + listNow.size() + "条");
                                } else {
                                    record.setState(StatusEnum.DOWNLOAD_FILE_ERROR.getCode());
                                    log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.DOWNLOAD_FILE_ERROR.getMsg());
                                }

                            } else {
                                record.setState(StatusEnum.DOWNLOAD_FILE_ERROR.getCode());
                                log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.DOWNLOAD_FILE_ERROR.getMsg());
                            }


                        } catch (Exception e) {
                            record.setState(StatusEnum.DOWNLOAD_FILE_FAIL.getCode());
                            log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.DOWNLOAD_FILE_FAIL.getMsg());
                            e.printStackTrace();
                        }

                    } else {

                        record.setState(StatusEnum.FILE_NULL.getCode());
                        log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.FILE_NULL.getMsg());

                    }
                } else {
                    record.setState(StatusEnum.FILE_NULL.getCode());
                    log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.FILE_NULL.getMsg());
                }


            } else {
                record.setState(StatusEnum.RESPONSE_FAIL.getCode());
                log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.RESPONSE_FAIL.getMsg());
            }
        } catch (Exception e) {
            record.setState(StatusEnum.RESPONSE_FAIL.getCode());
            log.error("下载minio原始RB文件 --> {} 失败，失败原因:{}", station.getStationCode(), StatusEnum.RESPONSE_FAIL.getMsg());
            e.printStackTrace();

        }

        recordService.save(record);
        return listNow;
    }


    /**
     * 解析原始dq文件并返回ForecastDataList
     *
     * @param dqFile
     * @param station
     * @param localDateTime
     * @return
     */
    public List<BJZYYJYSDCorrfore> fileAnalysis(File dqFile, Station station, LocalDateTime localDateTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<BJZYYJYSDCorrfore> aioList = new ArrayList<>();
        boolean jx = true;
        if (dqFile.renameTo(dqFile)) {
            InputStreamReader dqRead = null;
            BufferedReader dqBufferedReader = null;
            String stringLine;
            BJZYYJYSDCorrfore stf;
            try {
                dqRead = new InputStreamReader(new FileInputStream(dqFile), "utf-8");
                dqBufferedReader = new BufferedReader(dqRead);
                // 循环解析dq文件并放入aioList
                while ((stringLine = dqBufferedReader.readLine()) != null) {
                    String[] string_arr = stringLine.split("\t");
                    if (string_arr.length == 4 && string_arr[0].startsWith("#")) {
                        if (StrUtil.isNotEmpty(string_arr[2])) {
                            stf = new BJZYYJYSDCorrfore();
                            stf.setFpValue(new BigDecimal(string_arr[3] + ""));
                            stf.setForecastTime(sdf.parse(string_arr[2]).getTime());
                            stf.setStationCode(station.getStationCode());
                            aioList.add(stf);
                        }
                    }
                }
            } catch (Exception e) {
                jx = false;
                log.error(station.getStationCode() + " 解析当天DQ文件错误:", e);
            } finally {
                close(dqBufferedReader, dqRead);
            }
        }

        if (jx) {
            aioList.sort(Comparator.comparing(BJZYYJYSDCorrfore::getForecastTime));
            return aioList;
        } else {
            return null;
        }

    }


    /**
     * 关闭文件流
     *
     * @param bufferedReader 字符数据
     * @param read           字节流
     */
    private void close(BufferedReader bufferedReader, InputStreamReader read) {
        try {
            if (bufferedReader != null) {
                bufferedReader.close();
            }
            if (read != null) {
                read.close();
            }
        } catch (IOException e) {
            log.error("关闭文件流失败:", e);
        }
    }


}
