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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cpp.web.domain.datafactory.BaseParsing;
import com.cpp.web.domain.datafactory.ParsingNbq;
import com.cpp.web.domain.datafactory.dto.ParsingResultDto;
import com.cpp.web.domain.datafactory.enums.FileTypeEnum;
import com.cpp.web.domain.station.InverterInfo;
import com.cpp.web.domain.station.InverterStatusData;
import com.cpp.web.domain.station.WindTurbineStatusData;
import com.cpp.web.mapper.datafactory.ParsingNbqMapper;
import com.cpp.web.service.datafactory.ParsingInterface;
import com.cpp.web.service.datafactory.ParsingNbqService;
import com.cpp.web.service.station.InverterInfoService;
import com.cpp.web.service.station.InverterStatusDataService;
import com.cpp.web.utils.ParsingFieldUtil;
import com.cpp.web.utils.ParsingFileUtil;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
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("nbqParsing")
@RequiredArgsConstructor
@Slf4j
@Transactional
public class ParsingNbqServiceImpl extends ServiceImpl<ParsingNbqMapper, ParsingNbq> implements ParsingNbqService, ParsingInterface {

    private final InverterStatusDataService inverterStatusDataService;

    private final InverterInfoService inverterInfoService;

    private List<ParsingNbq> parsingNbqs = new ArrayList<>();

    private List<InverterInfo> inverterInfos = new ArrayList<>();

    @Override
    public boolean save(BaseParsing parsingInfo) {
        return save((ParsingNbq) 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.nbq.name());
        try {
            //查询符合该场站的nbq配置信息
            if (!this.parsingNbqs.isEmpty()) {
                ParsingNbq parsingNbqInfo = this.parsingNbqs.get(0);
                //解析文件内容以行为单位的 List<String>
                List<String> fileContent = ParsingFileUtil.getFileContent(file);
                //查询对应该场站路径下的逆变器信息
                //因为有可能该场站有多种解析配置，例如多个逆变器数据情况，需要循环解析信息
                //判断数据类型是单行还是多行
                if (parsingNbqInfo.getDataType().equals(ParsingFieldUtil.SINGLE)) {
                    /**
                     * 逆变器和风机id  需要解析名称找出对应设备存入id
                     * 单机类文件特殊，需要设备名称配多行，数据配单行即可
                     */
                    List<String> nbqNames = parsingNames(parsingNbqInfo.getEquipmentName(), fileContent);
                    Date time = parsingTime(parsingNbqInfo.getTime(), fileContent);
                    if (nbqNames.size() > 0) {
                        if (time != null) {
                            List<InverterStatusData> inverterStatusDataList = new ArrayList<>();
                            int number = Integer.parseInt(parsingNbqInfo.getEquipmentName().split("-")[0]);
                            String replace1 = parsingNbqInfo.getActivePower().split("<=>")[0] + "<=>";
                            List<InverterInfo> inverterInfoList = inverterInfos.stream().filter(i -> i.getStationCode().equals(stationCode)).collect(Collectors.toList());

                            for (String nbqName : nbqNames) {
                                List<InverterInfo> filterInverterInfos = inverterInfoList.stream().filter(i -> i.getName().equals(nbqName)).collect(Collectors.toList());
                                if (filterInverterInfos.size() > 0) {
                                    Long eqId = filterInverterInfos.get(0).getId();
                                    String replace2 = number + "<=>";
                                    InverterStatusData inverterStatusData = new InverterStatusData();
                                    inverterStatusData.setTime(time);
                                    inverterStatusData.setActivePower(parsingValue(parsingNbqInfo.getActivePower().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setCumulativeGeneratedEnergy(parsingValue(parsingNbqInfo.getCumulativeGeneratedEnergy().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setDayGridConnectedHours(parsingValue(parsingNbqInfo.getDayGridConnectedHours().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setDayElectricQuantity(parsingValue(parsingNbqInfo.getDayElectricQuantity().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setElectricalCurrent(parsingValue(parsingNbqInfo.getElectricalCurrent().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setReactivePower(parsingValue(parsingNbqInfo.getReactivePower().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setPowerFactor(parsingValue(parsingNbqInfo.getPowerFactor().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setVoltage(parsingValue(parsingNbqInfo.getVoltage().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setStatus(parsingStatus(parsingNbqInfo.getStatus().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setIsSample(parsingStatus(parsingNbqInfo.getIsSample().replace(replace1, replace2), fileContent));
                                    inverterStatusData.setEquipmentId(eqId);
                                    inverterStatusData.setStationCode(stationCode);
                                    inverterStatusDataList.add(inverterStatusData);
                                    parsingResultDto.setStatus("success");
                                } else {
                                    parsingResultDto.setStatus("0");
                                    parsingResultDto.setMessage("未找到对应逆变器：" + nbqName);
                                    log.error("[" + stationCode + "]未找到对应逆变器：{}", nbqName);
                                    break;
                                }
                                number++;
                            }
                            if (inverterStatusDataList.size() > 0) {
                                log.info("解析NBQ文件：{} 成功！ O(∩_∩)O", file.getName());
                                inverterStatusDataService.remove(
                                        new QueryWrapper<InverterStatusData>()
                                                .eq("time", time)
                                                .eq("station_code", stationCode));
                                inverterStatusDataService.saveBatch(inverterStatusDataList);
                            }
                        } else {
                            parsingResultDto.setStatus("0");
                            parsingResultDto.setMessage("解析逆变器数据时间失败：" + file.getName());
                            log.error("[" + stationCode + "]解析逆变器数据时间失败，fileName：{}", file.getName());
                        }
                    } else {
                        parsingResultDto.setStatus("0");
                        parsingResultDto.setMessage("解析逆变器名称失败：" + file.getName());
                        log.error("[" + stationCode + "]解析逆变器名称失败，fileName：{}", file.getName());
                    }
                } else {
                    parsingResultDto.setMessage("逆变器暂无多行解析方式");
                    log.error("[" + stationCode + "]逆变器数据暂无多行解析方式，fileName：{}", file.getName());
                }
            }
        } catch (Exception e) {
            parsingResultDto.setMessage("解析逆变器数据失败！");
            log.error("[" + stationCode + "]解析逆变器数据失败！ /(ㄒoㄒ)/~~，fileName：{}", file.getName(), e);
        } finally {
            return parsingResultDto;
        }
    }

    @Override
    public boolean activationParsingConf() {
        this.parsingNbqs = list();
        this.inverterInfos = inverterInfoService.list();
        return true;
    }
}
