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

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiayue.insu.inclientqn.constant.CommonStant;
import com.jiayue.insu.inclientqn.entity.*;
import com.jiayue.insu.inclientqn.inenum.StatusEnum;
import com.jiayue.insu.inclientqn.mapper.SHKJLNCorrforeMapper;
import com.jiayue.insu.inclientqn.pulldata.IPullInitForecastDataSH;
import com.jiayue.insu.inclientqn.service.RecordService;
import com.jiayue.insu.inclientqn.util.SystermUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 飔合科技（辽宁）下载修正短期预测数据from 一体化云
 * @description:
 * @author: yuanhao
 * @createDate: 2021/9/27
 * @version: 1.0
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class SHKJCorrforeService extends ServiceImpl<SHKJLNCorrforeMapper, SHKJLNCorrfore> {

    private final RecordService recordService;
    private final VelocityEngine velocityEngine;
    private final IPullInitForecastDataSH iPullInitForecastDataSH;

    /**
     * 飔合科技（辽宁）下载修正短期预测数据from 一体化云
     *
     * @param station
     * @return
     */
    public boolean downLoadCorrforeData(Station station) {
        // 初始化操作记录
        Record record = new Record();
        record.setType(CommonStant.RECORD_TYPE_PULL_CDQ_CORRECT);
        record.setStationCode(station.getStationCode());
        LocalDateTime localDateTime = LocalDateTimeUtil.beginOfDay(LocalDateTime.now());
        record.setTime(localDateTime);
        record.setCreateTime(LocalDateTime.now());

        boolean result = false;
        boolean isUpload = false;
        List<CorrforeSt> listMinio = new ArrayList<>();
        try {
            try {
                // 如果修正后短期数据不为0
                listMinio = iPullInitForecastDataSH.pullDQData(station);
                // 生成短期修正后文件
                if (genFile(station, listMinio)) {
                    result = true;
                    // 存入记录文件已经生成过
                    record.setState(CommonStant.RECORD_TYPE_PULL_CDQ_CORRECT);
                    record.setStateContent(StatusEnum.SUCCESS.getCode());
                }
            } catch (Exception e) {
                e.printStackTrace();
                record.setState(StatusEnum.CONNECT_RESPONSE_FORMAT_ERROR.getSign());
                record.setStateContent("解析短期或生成文件失败");
                log.error("========== 解析短期或生成文件失败 ");
            }

            if (result) {
                log.info("========== 拉取短期修正数据成功！ ==========");
                record.setState(StatusEnum.SUCCESS.getSign());
                record.setStateContent(String.valueOf(listMinio.size()));
            }

        } catch (
                Exception e) {
            record.setState(StatusEnum.CONNECT_ERROR.getSign());
            record.setStateContent(StatusEnum.CONNECT_ERROR.getMsg());
            log.error("========== 请求短期修正数据失败 连接断开或请求超时 ==========");
            e.printStackTrace();

        }
        recordService.save(record);
        return isUpload;
    }


    /**
     * 生成修正后的短期文件(飔合科技（辽宁）)
     *
     * @param station
     * @param list
     * @return
     */
    public boolean genFile(Station station, List<CorrforeSt> list) {
        boolean result = true;
        // 初始化模板
        String vmsPath = SystermUtils.getResourceBasePath() + "/vms/DQ.vm";
        File file;
        Template template = this.velocityEngine.getTemplate(vmsPath);
        // 如果模板不为空
        if (template != null) {
            VelocityContext velocityContext;
            StringWriter writer;
            // 将修正后的短期数据按照预测时间排序
            list.sort(Comparator.comparing(CorrforeSt::getForecastTime));
            // 根据修正后的数据，拼接需要的数据
            List<Map<String, Object>> vList = new ArrayList<>();
            for (CorrforeSt a : list) {
                Map<String, Object> map = new HashMap<>();
                map.put("id", a.getId());
                map.put("stationName", station.getName());
                map.put("forecastTime", DateUtil.format(new Date(a.getForecastTime()), "yyyy-MM-dd HH:mm:ss"));
                map.put("fpValue", a.getFpValue() == null ? "-99" : a.getFpValue());
                vList.add(map);
            }
            // 格式化模板数据
            writer = new StringWriter();
            velocityContext = new VelocityContext();
            velocityContext.put("stationName", station.getName());
            velocityContext.put("date", DateUtil.format(new Date(), "yyyy-MM-dd"));
            velocityContext.put("vList", vList);
            template.merge(velocityContext, writer);

            String filePath = station.getLocalFilePath();
            // 获取文件路径
            File fileUrl = new File(filePath);
            // 判断目录是否存在
            if (!fileUrl.exists()) {
                fileUrl.mkdirs();
            }
            // 获取文件名
            String fileName = "DQ_" + DateUtil.format(DateUtil.beginOfDay(new Date()), "yyyyMMddHHmmss") + "0.RB";
            file = new File(filePath + File.separatorChar + fileName);
            // 写入文件
            result = writeFile(file, station, writer, fileName, filePath);
        }
        return result;
    }


    /**
     * 写入文件
     *
     * @param file
     * @param station
     * @param writer
     * @param fileName
     * @param filePath
     * @return
     */
    private boolean writeFile(File file, Station station, StringWriter writer, String fileName, String filePath) {
        boolean result = true;
        // 获取文件路径
        File fileUrl = new File(filePath);
        // 判断目录是否存在
        if (!fileUrl.exists()) {
            fileUrl.mkdirs();
        }
        // 检查文件是否存在
        File existingFile = new File(filePath + File.separator + fileName);
        if (existingFile.exists()) {
            // 如果存在同名文件，尝试删除
            boolean deleted = existingFile.delete();
            if (!deleted) {
                // 如果无法删除，记录警告并返回false
                log.warn("无法删除文件：" + fileName);
                return false;
            }
        }

        // 创建流
        FileOutputStream os = null;
        try {
            boolean res = file.createNewFile();
            // 如果创建成功
            if (res) {
                os = new FileOutputStream(file);
                // 采用UTF-8字符集
                os.write(writer.toString().getBytes("UTF-8"));
                os.flush();
                // 创建文件失败
            } else {
                result = false;
                log.warn(station.getStationCode() + "文件名：" + fileName + " 生成失败");
            }
        } catch (IOException e) {
            e.printStackTrace();
            result = false;
            log.warn(station.getStationCode() + " 创建" + "文件名：" + fileName + "失败");
        } finally {
            // 如果流不为空，关闭流
            if (os != null) {
                try {
                    os.close();
                } catch (IOException e) {
                    log.error("文件生成关闭流失败", e);
                }
            }
            log.info("执行生成文件完毕：" + filePath + File.separatorChar + fileName);
            return result;
        }
    }
}
