package com.cpp.web.service.datafactory.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cpp.web.domain.datafactory.BaseParsing;
import com.cpp.web.domain.datafactory.ParsingNwp;
import com.cpp.web.domain.datafactory.dto.ParsingConfParam;
import com.cpp.web.domain.datafactory.dto.ParsingResultDto;
import com.cpp.web.domain.datafactory.enums.FileTypeEnum;
import com.cpp.web.domain.station.NwpStation;
import com.cpp.web.mapper.datafactory.ParsingNwpMapper;
import com.cpp.web.service.cloud.NwpCloudService;
import com.cpp.web.service.datafactory.ParsingInterface;
import com.cpp.web.service.datafactory.ParsingNwpService;
import com.cpp.web.service.station.NwpStationService;
import com.cpp.web.utils.ParsingFieldUtil;
import com.cpp.web.utils.ParsingFileUtil;
import com.cpp.web.utils.ParsingUtil;
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.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 测风塔解析业务层实现类
 *
 * @author tl
 * @date 2022-05-11 18:07:03
 */
@Service("nwpParsing")
@AllArgsConstructor
@Slf4j
@Transactional
public class ParsingNwpServiceImpl extends ServiceImpl<ParsingNwpMapper, ParsingNwp> implements ParsingNwpService, ParsingInterface {

    private final NwpStationService nwpStationService;

    private final NwpCloudService nwpCloudService;

    private List<ParsingNwp> parsingNwps = new ArrayList<>();

    @Override
    public boolean save(BaseParsing parsingInfo) {
        return save((ParsingNwp) parsingInfo);
    }

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

    @Override
    public ParsingResultDto parsing(File file, String stationCode) {

        ParsingResultDto parsingResultDto = new ParsingResultDto();
        parsingResultDto.setFileName(file.getName());
        parsingResultDto.setFileType(FileTypeEnum.nwp.name());

        try {

            List<ParsingNwp> parsingNwpInfos = selectByStationCode(stationCode);
            if (!parsingNwpInfos.isEmpty()) {
                for (ParsingNwp parsingNwpInfo : parsingNwpInfos) {
                        List<String> fileContent = ParsingFileUtil.getFileContent(file);
                        if (parsingNwpInfo.getDataType().equals(ParsingFieldUtil.MULTI)) {
                            Date forecastTime = parsingTime(parsingNwpInfo.getPreTime(), fileContent);
                            Date time = forecastTime;
                            if (time != null) {
                                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<NwpStation> nwpStationList = new ArrayList<>();
                                //以十米风速为基准
                                for (int i = 0; i < ws10s.size(); i++) {
                                    NwpStation nwpStation = new NwpStation();
                                    nwpStation.setTime(time);
                                    nwpStation.setDirectRadiation(valueSet(directRadiations, i));
                                    nwpStation.setDiffuseRadiation(valueSet(diffuseRadiations, i));
                                    nwpStation.setForecastHowLongAgo(calcHowLongAgo(forecastTime,time));
                                    nwpStation.setLwr(valueSet(lwrs, i));
                                    nwpStation.setPressure(valueSet(pressures, i));
                                    nwpStation.setRh(valueSet(rhs, i));
                                    nwpStation.setSenf(valueSet(senfs, i));
                                    nwpStation.setSwr(valueSet(swrs, i));
                                    nwpStation.setT(valueSet(ts, i));
                                    nwpStation.setWs10(valueSet(ws10s, i));
                                    nwpStation.setWd10(valueSet(wd10s, i));
                                    nwpStation.setWs30(valueSet(ws30s, i));
                                    nwpStation.setWd30(valueSet(wd30s, i));
                                    nwpStation.setWs50(valueSet(ws50s, i));
                                    nwpStation.setWd50(valueSet(wd50s, i));
                                    nwpStation.setWs70(valueSet(ws70s, i));
                                    nwpStation.setWd70(valueSet(wd70s, i));
                                    nwpStation.setWs80(valueSet(ws80s, i));
                                    nwpStation.setWd80(valueSet(wd80s, i));
                                    nwpStation.setWs90(valueSet(ws90s, i));
                                    nwpStation.setWd90(valueSet(wd90s, i));
                                    nwpStation.setWs100(valueSet(ws100s, i));
                                    nwpStation.setWd100(valueSet(wd100s, i));
                                    nwpStation.setWs170(valueSet(ws170s, i));
                                    nwpStation.setWd170(valueSet(wd170s, i));
                                    nwpStation.setStationCode(stationCode);

                                    nwpStationList.add(nwpStation);

                                    time = new Date(time.getTime() + 900000L);
                                }

                                nwpStationService.saveBatch(nwpStationList);

                                parsingResultDto.setStatus("success");
                                log.info("解析Nwp文件：{} 成功！ O(∩_∩)O", file.getName());
                            } else {
                                parsingResultDto.setMessage("解析Nwp文件时间错误");
                                log.error("解析Nwp文件时间错误");
                            }
                        } else {
                            parsingResultDto.setMessage("Nwp暂无单行解析方式");
                            log.error("nwp暂无单行解析方式");
                        }
                    }
                }

        } catch (Exception e) {
            parsingResultDto.setMessage("解析Nwp数据失败");
            log.error("解析Nwp数据失败！ /(ㄒoㄒ)/~~", e);
        } finally {
            return parsingResultDto;
        }


    }

    @Override
    public boolean activationParsingConf() {
        this.parsingNwps = baseMapper.selectList(null);
        return false;
    }

    @Override
    public List selectByStationCode(String stationCode) {
        return this.parsingNwps.stream().filter(p->p.getStationCode().equals(stationCode)).collect(Collectors.toList());
    }



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

        try {
            if (sign != null && !sign.equals("")) {
                ParsingConfParam config = ParsingFieldUtil.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 = ParsingUtil.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 = ParsingUtil.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);
        }

    }


    /**
     * 计算D+x中的x
     *
     * @param baseTime
     * @param time
     */
    public Integer calcHowLongAgo(Date baseTime, Date time) {
        return ((int) (time.getTime() - baseTime.getTime() % 86400000L)) + 1;
    }
}
