package com.jiayue.ipp.idp.service.an;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.jiayue.ipfcst.common.core.util.DateMomentUtil;
import com.jiayue.ipfcst.common.core.util.DateTimeUtil;
import com.jiayue.ipp.common.data.entity.ForecastPowerShortTerm;
import com.jiayue.ipp.common.data.entity.ForecastPowerShortTermHis;
import com.jiayue.ipp.common.data.entity.an.ParsingChannel;
import com.jiayue.ipp.common.data.entity.an.ParsingLog;
import com.jiayue.ipp.common.data.entity.an.ParsingUrl;
import com.jiayue.ipp.idp.dto.ParsingConstant;
import com.jiayue.ipp.idp.service.ForecastPowerShortTermHisService;
import com.jiayue.ipp.idp.service.ForecastPowerShortTermService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * ftp通信业务层
 *
 * @author tl
 * @date 2022-05-11 09:51:21
 */
@AllArgsConstructor
@Slf4j
@Service
@Transactional
public class DownloadService {

    private final ParsingUrlService parsingUrlService;

    private final ParsingFileService parsingFileService;

    private final ParsingLogService parsingLogService;

    private final ForecastPowerShortTermHisService forecastPowerShortTermHisService;

    private final ForecastPowerShortTermService forecastPowerShortTermService;

    /**
     * 解析
     *
     * @param parsingChannel
     */
    public void parsing(ParsingChannel parsingChannel) {

        //过滤出当前解析通道下在使用的《 解析路径 》
        List<ParsingUrl> parsingUrls = parsingUrlService.list(Wrappers.lambdaQuery(ParsingUrl.class).eq(ParsingUrl::getCId, parsingChannel.getId()).eq(ParsingUrl::getUrlStatus, "1"));
        String dateDir = DateFormatUtils.format(new Date(), "yyyyMMdd");
        String dayStr = new SimpleDateFormat("yyyyMMdd").format(new Date());
        //遍历解析路径，对文件进行解析
        for (ParsingUrl parsingUrl : parsingUrls) {

            String failDir = parsingUrl.getUrl() + File.separator + "fail" + File.separator + dateDir;

            String success = parsingUrl.getUrl() + File.separator + "success" + File.separator + dateDir;

            String path = parsingUrl.getUrl() + File.separator + "new";

            File dirFile = new File(path);

            if (!dirFile.exists()) {
                dirFile.mkdirs();
            }
            File[] files = dirFile.listFiles();
            log.info("扫描路径：{}，文件数：{}", path, files.length);
            //遍历文件
            for (File file : files) {
                String fileName = file.getName();
                ParsingLog parsingLog = new ParsingLog();
                parsingLog.setFileName(fileName);
                parsingLog.setStationCode(parsingUrl.getStationCode());
                parsingLog.setParsingTime(new Date());

                if (!fileName.contains(dayStr)) {
                    file.delete();
                    log.warn(parsingUrl.getStationCode() + "下" + fileName + "云端文件不是当天的文件，删除！");
                    break;
                }

                // 如果是短期文件
                if (file.getName().startsWith("DQ")) {
                    try {
                        // 解析短期文件
                        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        List<ForecastPowerShortTerm> forecastPowerShortTermList = new ArrayList<>();
                        List<ForecastPowerShortTermHis> forecastPowerShortTermHisList = new ArrayList<>();
                        // 当文件未被使用时，进行解析上报
                        if (file.renameTo(file)) {
                            InputStreamReader read = null;
                            BufferedReader bufferedReader = null;
                            String stringLine;
                            ForecastPowerShortTerm stf;
                            try {
                                read = new InputStreamReader(Files.newInputStream(file.toPath()), StandardCharsets.UTF_8);
                                bufferedReader = new BufferedReader(read);
                                Long systemTime = System.currentTimeMillis();
                                // 循环解析文件
                                while ((stringLine = bufferedReader.readLine()) != null) {
                                    String[] string_arr = stringLine.split("\t");
                                    if (string_arr.length == 4 && string_arr[0].startsWith("#")) {
                                        if (StringUtils.isNotEmpty(string_arr[2])) {
                                            // 实时表
                                            stf = new ForecastPowerShortTerm();
                                            stf.setFpValue(new BigDecimal(string_arr[3]));
                                            stf.setForecastTime(sdf.parse(string_arr[2]));
                                            stf.setGenDate(new Date());
                                            stf.setStationCode(parsingUrl.getStationCode());
                                            stf.setForecastManufactor(parsingUrl.getForecastManufactor());
                                            forecastPowerShortTermList.add(stf);

                                            // 历史表
                                            //过滤当天的数据
                                            long secondDayTime = com.jiayue.ipp.idp.util.DateMomentUtil.getDayStartTime(systemTime) + 1000 * 60 * 60 * 24;
                                            if (sdf.parse(string_arr[2]).getTime() >= secondDayTime) {
                                                ForecastPowerShortTermHis forecastPowerShortTermHis = new ForecastPowerShortTermHis();
                                                forecastPowerShortTermHis.setGenDate(new Date());
                                                forecastPowerShortTermHis.setStationCode(parsingUrl.getStationCode());
                                                forecastPowerShortTermHis.setAbleValue(new BigDecimal(string_arr[3]));
                                                forecastPowerShortTermHis.setForecastTime(sdf.parse(string_arr[2]));
                                                forecastPowerShortTermHis.setForecastHowLongAgo(DateMomentUtil.getDaysBetweenTwoDate(systemTime, sdf.parse(string_arr[2]).getTime()));
                                                forecastPowerShortTermHis.setForecastManufactor(parsingUrl.getForecastManufactor());
                                                forecastPowerShortTermHisList.add(forecastPowerShortTermHis);
                                            }
                                        }
                                    }
                                }

                                if (forecastPowerShortTermList.size() > 0 && forecastPowerShortTermHisList.size() > 0) {
                                    // 保存短期实时
                                    Date startTime = forecastPowerShortTermList.get(0).getForecastTime();
                                    Date endTime = forecastPowerShortTermList.get(forecastPowerShortTermList.size() - 1).getForecastTime();
                                    LambdaQueryWrapper<ForecastPowerShortTerm> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                    lambdaQueryWrapper.eq(ForecastPowerShortTerm::getStationCode, parsingUrl.getStationCode());
                                    lambdaQueryWrapper.eq(ForecastPowerShortTerm::getForecastManufactor, parsingUrl.getForecastManufactor());
                                    lambdaQueryWrapper.between(ForecastPowerShortTerm::getForecastTime, startTime, endTime);
                                    forecastPowerShortTermService.remove(lambdaQueryWrapper);
                                    forecastPowerShortTermService.saveBatch(forecastPowerShortTermList);

                                    // 保存短期历史
                                    LambdaQueryWrapper<ForecastPowerShortTermHis> forecastPowerShortTermHisLambdaQueryWrapper = new LambdaQueryWrapper<>();
                                    forecastPowerShortTermHisLambdaQueryWrapper.eq(ForecastPowerShortTermHis::getStationCode, parsingUrl.getStationCode());
                                    forecastPowerShortTermHisLambdaQueryWrapper.eq(ForecastPowerShortTermHis::getForecastManufactor, parsingUrl.getForecastManufactor());
                                    forecastPowerShortTermHisLambdaQueryWrapper.eq(ForecastPowerShortTermHis::getGenDate, DateUtil.format(new Date(), "yyyy-MM-dd"));
                                    forecastPowerShortTermHisService.remove(forecastPowerShortTermHisLambdaQueryWrapper);
                                    forecastPowerShortTermHisService.saveBatch(forecastPowerShortTermHisList);
                                    log.info(parsingUrl.getStationCode() + "下" + fileName + "嘉越云端文件解析成功！");
                                    try {
                                        File file1 = new File(success + File.separator + fileName);
                                        if (file1.exists()) {
                                            file1.delete();
                                        }
                                        FileUtils.moveFile(file, new File(success + File.separator + fileName));
                                    } catch (IOException e) {
                                        e.printStackTrace();
                                    }
                                }
                            } catch (Exception e) {
                                log.error("嘉越云端文件解析失败：", e);
                                try {
                                    File file1 = new File(failDir + File.separator + fileName);
                                    if (file1.exists()) {
                                        file1.delete();
                                    }
                                    FileUtils.moveFile(file, new File(failDir + File.separator + fileName));
                                } catch (IOException ex) {
                                    log.error(parsingUrl.getStationCode() + "下" + fileName + "嘉越云端文件解析失败1", ex);
                                }
                            } finally {
                                close(bufferedReader, read);
                            }
                        }
                    } catch (Exception e) {
                        log.error(parsingUrl.getStationCode() + "下" + fileName + "解析嘉越云端DQ文件失败", e);
                        try {
                            File file1 = new File(failDir + File.separator + fileName);
                            if (file1.exists()) {
                                file1.delete();
                            }
                            FileUtils.moveFile(file, new File(failDir + File.separator + fileName));
                        } catch (IOException ex) {
                            log.error(parsingUrl.getStationCode() + "下" + fileName + "嘉越云端文件解析失败1", ex);
                        }
                    }
                }
            }
        }
        log.info("解析嘉越云端文件定时执行完成");

    }

    /**
     * 关闭文件流
     *
     * @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);
        }
    }
}
