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

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiayue.ipp.common.data.entity.Nwp;
import com.jiayue.ipp.common.data.entity.NwpHis;
import com.jiayue.ipp.common.data.entity.an.ParsingInfo;
import com.jiayue.ipp.common.data.entity.an.ParsingNwpInfo;
import com.jiayue.ipp.common.data.entity.an.ParsingUrl;
import com.jiayue.ipp.common.data.enums.FileTypeEnum;
import com.jiayue.ipp.idp.config.Constant;
import com.jiayue.ipp.idp.dto.FileParsingConfig;
import com.jiayue.ipp.idp.dto.ParsingConstant;
import com.jiayue.ipp.idp.mapper.an.ParsingNwpInfoMapper;
import com.jiayue.ipp.idp.service.NwpHisService;
import com.jiayue.ipp.idp.service.NwpService;
import com.jiayue.ipp.idp.service.an.ParsingInterface;
import com.jiayue.ipp.idp.service.an.ParsingNwpInfoService;
import com.jiayue.ipp.idp.util.FieldUtil;
import com.jiayue.ipp.idp.util.FileUtil;
import com.jiayue.ipp.idp.util.PUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;

/**
 * 测风塔解析业务层实现类
 *
 * @author tl
 * @date 2022-05-11 18:07:03
 */
@Service
@AllArgsConstructor
@Slf4j
@Transactional
public class ParsingNwpInfoServiceImpl extends ServiceImpl<ParsingNwpInfoMapper, ParsingNwpInfo> implements ParsingNwpInfoService, ParsingInterface {

    private final NwpHisService nwpHisService;

    private final NwpService nwpService;


    @Override
    public boolean save(ParsingInfo parsingInfo) {
        return save((ParsingNwpInfo) parsingInfo);
    }

    @Override
    public boolean deleteById(String id) {
        return removeById(id);
    }

    //文件解析
    /*
     * 解析配置格式规则：
     *
     *   m=>>4-20-4-1=>>3
     *   m：多行标识
     *   4-20：取值在4-20行
     *   -4:代表有层层高
     *   -1：代表取第一种层高
     *   3：第三列
     * */
    @Override
    public String parsing(File file, ParsingUrl parsingUrl) {

        String parsingStatus = ParsingConstant.FAIL;

        try {

            List<ParsingNwpInfo> parsingNwpInfos = baseMapper.selectList(Wrappers.lambdaQuery(ParsingNwpInfo.class).like(ParsingInfo::getStationCode, parsingUrl.getStationCode()));
            if (!parsingNwpInfos.isEmpty()) {
                for (ParsingNwpInfo parsingNwpInfo : parsingNwpInfos) {
                    //判断文件名是否符合配置
                    if (file.getName().contains(parsingNwpInfo.getFileName())) {
                        List<String> fileContent = FileUtil.getFileContent(file);
                        if (parsingNwpInfo.getDataType().equals(FieldUtil.MULTI)) {
                            Long time = parsingTime(parsingNwpInfo.getPreTime(), fileContent);


                            if (time != 0l) {
                                List<BigDecimal> ws10s = parsingNwpValue(parsingNwpInfo.getWs10(), fileContent);
                                List<BigDecimal> wd10s = parsingNwpValue(parsingNwpInfo.getWd10(), fileContent);
                                List<BigDecimal> ws30s = parsingNwpValue(parsingNwpInfo.getWs30(), fileContent);
                                List<BigDecimal> wd30s = parsingNwpValue(parsingNwpInfo.getWd30(), fileContent);
                                List<BigDecimal> ws50s = parsingNwpValue(parsingNwpInfo.getWs50(), fileContent);
                                List<BigDecimal> wd50s = parsingNwpValue(parsingNwpInfo.getWd50(), fileContent);
                                List<BigDecimal> ws70s = parsingNwpValue(parsingNwpInfo.getWs70(), fileContent);
                                List<BigDecimal> wd70s = parsingNwpValue(parsingNwpInfo.getWd70(), fileContent);
                                List<BigDecimal> ws80s = parsingNwpValue(parsingNwpInfo.getWs80(), fileContent);
                                List<BigDecimal> wd80s = parsingNwpValue(parsingNwpInfo.getWd80(), fileContent);
                                List<BigDecimal> ws90s = parsingNwpValue(parsingNwpInfo.getWs90(), fileContent);
                                List<BigDecimal> wd90s = parsingNwpValue(parsingNwpInfo.getWd90(), fileContent);
                                List<BigDecimal> ws100s = parsingNwpValue(parsingNwpInfo.getWs100(), fileContent);
                                List<BigDecimal> wd100s = parsingNwpValue(parsingNwpInfo.getWd100(), fileContent);
                                List<BigDecimal> ws170s = parsingNwpValue(parsingNwpInfo.getWs170(), fileContent);
                                List<BigDecimal> wd170s = parsingNwpValue(parsingNwpInfo.getWd170(), fileContent);
                                List<BigDecimal> directRadiations = parsingNwpValue(parsingNwpInfo.getDirectRadiation(), fileContent);
                                List<BigDecimal> lwrs = parsingNwpValue(parsingNwpInfo.getLwr(), fileContent);
                                List<BigDecimal> diffuseRadiations = parsingNwpValue(parsingNwpInfo.getDiffuseRadiation(), fileContent);
                                List<BigDecimal> rhs = parsingNwpValue(parsingNwpInfo.getRh(), fileContent);
                                List<BigDecimal> pressures = parsingNwpValue(parsingNwpInfo.getPressure(), fileContent);
                                List<BigDecimal> senfs = parsingNwpValue(parsingNwpInfo.getSenf(), fileContent);
                                List<BigDecimal> swrs = parsingNwpValue(parsingNwpInfo.getSwr(), fileContent);
                                List<BigDecimal> ts = parsingNwpValue(parsingNwpInfo.getT(), fileContent);

                                List<NwpHis> nwpHisList = new ArrayList<>();

                                List<Nwp> nwpList = new ArrayList<>();
                                //以十米风速为基准
                                for (int i = 0; i < ws10s.size(); i++) {
                                    NwpHis nwpHis = new NwpHis();
                                    LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault());
                                    nwpHis.setPreTime(localDateTime);
                                    nwpHis.setPreDate(localDateTime.toLocalDate());
                                    nwpHis.setScDate(LocalDateTime.now().toLocalDate());
                                    nwpHis.setScTime(LocalDateTime.now());
                                    nwpHis.setDirectRadiation(valueSet(directRadiations, i));
                                    nwpHis.setDiffuseRadiation(valueSet(diffuseRadiations, i));
                                    nwpHis.setForecastHowLongAgo(i / 96 + 1);
                                    nwpHis.setLwr(valueSet(lwrs, i));
                                    nwpHis.setPressure(valueSet(pressures, i));
                                    nwpHis.setRh(valueSet(rhs, i));
                                    nwpHis.setSenf(valueSet(senfs, i));
                                    nwpHis.setSwr(valueSet(swrs, i));
                                    nwpHis.setT(valueSet(ts, i));
                                    nwpHis.setWs10(valueSet(ws10s, i));
                                    nwpHis.setWd10(valueSet(wd10s, i));
                                    nwpHis.setWs30(valueSet(ws30s, i));
                                    nwpHis.setWd30(valueSet(wd30s, i));
                                    nwpHis.setWs50(valueSet(ws50s, i));
                                    nwpHis.setWd50(valueSet(wd50s, i));
                                    nwpHis.setWs70(valueSet(ws70s, i));
                                    nwpHis.setWd70(valueSet(wd70s, i));
                                    nwpHis.setWs80(valueSet(ws80s, i));
                                    nwpHis.setWd80(valueSet(wd80s, i));
                                    nwpHis.setWs90(valueSet(ws90s, i));
                                    nwpHis.setWd90(valueSet(wd90s, i));
                                    nwpHis.setWs100(valueSet(ws100s, i));
                                    nwpHis.setWd100(valueSet(wd100s, i));
                                    nwpHis.setWs170(valueSet(ws170s, i));
                                    nwpHis.setWd170(valueSet(wd170s, i));
                                    nwpHis.setForecastManufactor(parsingUrl.getForecastManufactor());
                                    nwpHis.setStationCode(parsingUrl.getStationCode());

                                    nwpHisList.add(nwpHis);



                                    Nwp nwp = new Nwp();
                                    nwp.setPreTime(localDateTime);
                                    nwp.setPreDate(localDateTime.toLocalDate());
                                    nwp.setScDate(LocalDateTime.now().toLocalDate());
                                    nwp.setScTime(LocalDateTime.now());
                                    nwp.setDirectRadiation(valueSet(directRadiations, i));
                                    nwp.setDiffuseRadiation(valueSet(diffuseRadiations, i));
                                    nwp.setLwr(valueSet(lwrs, i));
                                    nwp.setPressure(valueSet(pressures, i));
                                    nwp.setRh(valueSet(rhs, i));
                                    nwp.setSenf(valueSet(senfs, i));
                                    nwp.setSwr(valueSet(swrs, i));
                                    nwp.setT(valueSet(ts, i));
                                    nwp.setWs10(valueSet(ws10s, i));
                                    nwp.setWd10(valueSet(wd10s, i));
                                    nwp.setWs30(valueSet(ws30s, i));
                                    nwp.setWd30(valueSet(wd30s, i));
                                    nwp.setWs50(valueSet(ws50s, i));
                                    nwp.setWd50(valueSet(wd50s, i));
                                    nwp.setWs70(valueSet(ws70s, i));
                                    nwp.setWd70(valueSet(wd70s, i));
                                    nwp.setWs80(valueSet(ws80s, i));
                                    nwp.setWd80(valueSet(wd80s, i));
                                    nwp.setWs90(valueSet(ws90s, i));
                                    nwp.setWd90(valueSet(wd90s, i));
                                    nwp.setWs100(valueSet(ws100s, i));
                                    nwp.setWd100(valueSet(wd100s, i));
                                    nwp.setWs170(valueSet(ws170s, i));
                                    nwp.setWd170(valueSet(wd170s, i));
                                    nwp.setForecastManufactor(parsingUrl.getForecastManufactor());
                                    nwp.setStationCode(parsingUrl.getStationCode());

                                    nwpList.add(nwp);
                                    time += Constant.INTERVALTIME;
                                }



                                LocalDateTime startTime = nwpHisList.get(0).getPreTime();
                                LocalDateTime endTime = nwpHisList.get(nwpHisList.size() - 1).getPreTime();
                                nwpHisService.saveBatch(nwpHisList);
                                LambdaQueryWrapper<Nwp> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                                lambdaQueryWrapper.eq(Nwp::getStationCode, parsingUrl.getStationCode());
                                lambdaQueryWrapper.between(Nwp::getPreTime, startTime, endTime);
                                nwpService.remove(lambdaQueryWrapper);
//
                                nwpService.saveBatch(nwpList);

                                parsingStatus = FileTypeEnum.NWP72.name();
                                log.info("解析Nwp文件：{} 成功！ O(∩_∩)O", file.getName());
                            } else {
                                parsingStatus += "解析Nwp文件时间错误";
                                log.error("解析Nwp文件时间错误");
                            }
                        } else {
                            parsingStatus += "nwp暂无单行解析方式";
                            log.info("nwp暂无单行解析方式");
                        }
                    }
                }
            }
        } catch (Exception e) {
            parsingStatus += "解析Nwp数据失败";
            log.error("解析Nwp数据失败！ /(ㄒoㄒ)/~~", e);
        } finally {
            return parsingStatus;
        }

    }


    protected List<BigDecimal> parsingNwpValue(String sign, List<String> fileContent) {
        List<BigDecimal> fpValues = new ArrayList<>();

        try {
            if (sign != null && !sign.equals("")) {
                FileParsingConfig config = FieldUtil.getConfig(sign);
                String[] lineNumber = config.getLineNumber().split("-");
                if (lineNumber.length > 2) {
                    int startLine = Integer.parseInt(lineNumber[0]) - 1;
                    int endLine = Integer.parseInt(lineNumber[1]) - 1;
                    int size = Integer.parseInt(lineNumber[2]);
                    int no = Integer.parseInt(lineNumber[3]) - 1 ;

                    for (int i = startLine + no; i <= endLine; i += size) {
                        String[] strings = PUtil.splitLineWithSpace(fileContent.get(i));
                        String result = strings[Integer.parseInt(config.getRowNumber()) - 1];

                        fpValues.add(new BigDecimal(result));
                    }

                } else {

                    int startLine = Integer.parseInt(lineNumber[0]) - 1;
                    int endLine = Integer.parseInt(lineNumber[1]) - 1;

                    for (int i = startLine; i <= endLine; i++) {
                        String[] strings = PUtil.splitLineWithSpace(fileContent.get(i));
                        String result = strings[Integer.parseInt(config.getRowNumber()) - 1];

                        fpValues.add(new BigDecimal(result));
                    }
                }
            }

        } catch (RuntimeException e) {
            e.printStackTrace();
        } finally {
            return fpValues;
        }
    }


    private BigDecimal valueSet(List<BigDecimal> list, int i) {
        if (list.size() > i) {
            return list.get(i);
        } else {
            return new BigDecimal(-99);
        }

    }
}
