package com.njcn.cloud.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.njcn.advance.api.EventWaveAnalysisFeignClient;
import com.njcn.advance.pojo.dto.waveAnalysis.EntityAdvancedData;
import com.njcn.cloud.mapper.AppEventInfoMapper;
import com.njcn.cloud.pojo.dto.AppEventInfo;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.cloud.pojo.vo.EventEigDetailVO;
import com.njcn.cloud.pojo.vo.EventWaveDetailVO;
import com.njcn.cloud.service.IAppEventInfoService;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.common.utils.PubUtils;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.pq.pojo.vo.LineDetailVO;
import com.njcn.event.api.EventDetailFeignClient;
import com.njcn.event.file.component.WaveFileComponent;
import com.njcn.event.file.component.WavePicComponent;
import com.njcn.event.file.pojo.bo.WaveDataDetail;
import com.njcn.event.file.pojo.dto.WaveDataDTO;
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
import com.njcn.event.file.utils.WaveUtil;
import com.njcn.event.pojo.po.RmpEventDetailPO;
import com.njcn.oss.constant.GeneralConstant;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 暂态消息详情 服务实现类
 * </p>
 *
 * @author wr
 * @since 2023-11-01
 */
@Service
@RequiredArgsConstructor
public class AppEventInfoServiceImpl extends ServiceImpl<AppEventInfoMapper, AppEventInfo> implements IAppEventInfoService {

    private final EventWaveAnalysisFeignClient eventWaveAnalysisFeignClient;
    private final FileStorageUtil fileStorageUtil;
    private final WaveFileComponent waveFileComponent;
    private final WavePicComponent wavePicComponent;
    private final EventDetailFeignClient eventDetailFeignClient;
    private final LineFeignClient lineFeignClient;




    @Override
    public EventEigDetailVO.Detail eventDetailEigenvalue(String eventDetailIndex) {
        EventEigDetailVO.Detail detail=new EventEigDetailVO.Detail();

        List<EventEigDetailVO> eventInfoDetails = new ArrayList<>();
        EntityAdvancedData entityAdvancedData = eventWaveAnalysisFeignClient.analysis(eventDetailIndex).getData();
        //根据事件获取监测点接线方式
        Integer ptType=null;
        List<RmpEventDetailPO> eventDetail = eventDetailFeignClient.getEventDetailByIdsList(Arrays.asList(eventDetailIndex)).getData();
        List<String> linedIds = eventDetail.stream().map(RmpEventDetailPO::getLineId).distinct().collect(Collectors.toList());
        if(CollUtil.isNotEmpty(linedIds)) {
            List<LineDetailVO.Detail> lineDetail = lineFeignClient.getLineDetailByIds(linedIds).getData();
            ptType=lineDetail.get(0).getPtType();
        }
        if (entityAdvancedData.backNumber != -1) {
            detail.setBackNumber( entityAdvancedData.backNumber);
            for (int i = 0; i < entityAdvancedData.backNumber; i++) {
                EventEigDetailVO eventEigDetail = new EventEigDetailVO();
                eventEigDetail.setHold_time_dq(entityAdvancedData.evt_buf[i].hold_time_dq * 1000);
                eventEigDetail.setPow_a(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_a));
                eventEigDetail.setPow_b(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_b));
                eventEigDetail.setPow_c(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].POW_c));

                eventEigDetail.setVoltagechange_Va(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Va / 1000));
                eventEigDetail.setVoltagechange_Vb(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Vb / 1000));
                eventEigDetail.setVoltagechange_Vc(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].Voltagechange_Vc / 1000));


                eventEigDetail.setUa_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ua_min[0]));
                eventEigDetail.setUb_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ub_min[0]));
                eventEigDetail.setUc_min(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].ua_min[0]));

                eventEigDetail.setAngle_diff_ap(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_ap[0]));
                eventEigDetail.setAngle_diff_bp(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_bp[0]));
                eventEigDetail.setAngle_diff_cp(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].angle_diff_cp[0]));

                eventEigDetail.setBph_max_value(PubUtils.floatRound(2, entityAdvancedData.evt_buf[i].bph_max_value[0]));
                eventEigDetail.setSagReason(entityAdvancedData.sagReason[0]);//暂降原因，暂降原因都一样
                eventEigDetail.setSagType(entityAdvancedData.sagType[i]);//暂降类型
                eventInfoDetails.add(eventEigDetail);
                eventEigDetail.setPttype(ptType);
            }
        } else {
            detail.setBackNumber(0);
        }
        detail.setList(eventInfoDetails);
        return detail;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public EventWaveDetailVO eventDetailWave(String eventDetailIndex) {
        EventWaveDetailVO vo =new EventWaveDetailVO();
        AppEventInfo byId = this.getById(eventDetailIndex);
        vo.setEventDetailIndex(byId.getEventdetailIndex());
        if(StrUtil.isBlank(byId.getInstantwavePath())){
            //获取波形数据。然后绘图
            WaveDataDTO waveDataDTO = this.analyseWave(eventDetailIndex, 2);
            //数据筛选,如果是双路电压的话，会存在2个波形数据
            List<WaveDataDetail> waveDataDetails = WaveUtil.filterWaveData(waveDataDTO);
            String instantPath = wavePicComponent.generateImageShun(waveDataDTO,waveDataDetails);
            byId.setInstantwavePath(instantPath);
            if (StrUtil.isBlank(byId.getRmswavePath())) {
                String rmsPath = wavePicComponent.generateImageRms(waveDataDTO,waveDataDetails);
                byId.setRmswavePath(rmsPath);
            }
            this.updateById(byId);
        }
        vo.setInstantWaveUrl(byId.getInstantwavePath());
        vo.setRmsWaveUrl(byId.getRmswavePath());
        return vo;
    }

    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean eventDetailEvaluate(String eventDetailIndex, Integer evaluate, String userId) {
        boolean fly = this.update(new LambdaUpdateWrapper<AppEventInfo>()
                .set(AppEventInfo::getEvaluate, evaluate)
                .set(AppEventInfo::getUserIndex, userId)
                .eq(AppEventInfo::getEventdetailIndex, eventDetailIndex)
        );
        return fly;
    }

    /**
     * @Description: 获取波形数据
     * @return: com.njcn.event.file.pojo.dto.WaveDataDTO
     * @Author: wr
     * @Date: 2023/11/1 15:51
     */
    @Override
    public WaveDataDTO analyseWave(String eventId, int iType) {
        WaveDataDTO waveDataDTO;
        List<RmpEventDetailPO> eventDetails = eventDetailFeignClient.getEventDetailByIdsList(Arrays.asList(eventId)).getData();
        List<String> linedIds = eventDetails.stream().map(RmpEventDetailPO::getLineId).distinct().collect(Collectors.toList());
        List<LineDetailVO.Detail> lineDetail = lineFeignClient.getLineDetailByIds(linedIds).getData();
        RmpEventDetailPO detail = eventDetails.get(0);
        LineDetailVO.Detail line = lineDetail.get(0);
        String waveName = detail.getWavePath();
        if (StrUtil.isBlank(waveName)) {
            throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
        }
        try (
                InputStream cfgStream = fileStorageUtil.getFileStream(OssPath.WAVE_DIR + line.getIp() + StrUtil.SLASH + waveName + GeneralConstant.CFG);
                InputStream datStream = fileStorageUtil.getFileStream(OssPath.WAVE_DIR + line.getIp() + StrUtil.SLASH + waveName + GeneralConstant.DAT)
        ) {
            if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) {
                throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
            }
            waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, iType);
        } catch (Exception e) {
            throw new BusinessException(WaveFileResponseEnum.WAVE_DATA_INVALID);
        }
        waveDataDTO = waveFileComponent.getValidData(waveDataDTO);
        waveDataDTO.setPtType(line.getPtType());
        waveDataDTO.setPt(line.getPT1()/line.getPT2());
        waveDataDTO.setCt(line.getCT1()/line.getCT2());
        waveDataDTO.setMonitorName(line.getLineName());
        return waveDataDTO;
    }
}
