package com.njcn.advance.event.service.impl;

import cn.hutool.core.util.StrUtil;
import com.njcn.advance.event.cause.jna.QvvrCauseDLL;
import com.njcn.advance.event.cause.model.DataFeature;
import com.njcn.advance.event.type.jna.*;
import com.njcn.advance.pojo.dto.EventAnalysisDTO;
import com.njcn.advance.event.service.IEventAdvanceService;
import com.njcn.common.config.GeneralInfo;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.event.file.component.WaveFileComponent;
import com.njcn.event.file.pojo.dto.WaveDataDTO;
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
import com.njcn.oss.constant.GeneralConstant;
import com.njcn.oss.constant.OssPath;
import com.njcn.oss.utils.FileStorageUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.InputStream;
import java.util.List;
import java.util.Objects;

/**
 * @author hongawen
 * @version 1.0
 * @data 2025/7/30 10:51
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class EventAdvanceServiceImpl implements IEventAdvanceService {

    private final GeneralInfo generalInfo;

    private final WaveFileComponent waveFileComponent;

    private final FileStorageUtil fileStorageUtil;


    @Override
    public EventAnalysisDTO analysisCauseAndType(EventAnalysisDTO eventAnalysis) {
        WaveDataDTO waveDataDTO;
        String waveName = eventAnalysis.getWaveName();
        String cfgPath, datPath, cfgPath2, datPath2;
        String ip = eventAnalysis.getIp();
        if (generalInfo.getBusinessWaveFileStorage() == GeneralConstant.LOCAL_DISK) {
            cfgPath = generalInfo.getBusinessWavePath() + File.separator + ip + File.separator + waveName + GeneralConstant.CFG;
            datPath = generalInfo.getBusinessWavePath() + File.separator + ip + File.separator + waveName + GeneralConstant.DAT;
            log.info("本地磁盘波形文件路径----" + cfgPath);
            InputStream cfgStream = waveFileComponent.getFileInputStreamByFilePath(cfgPath);
            InputStream datStream = waveFileComponent.getFileInputStreamByFilePath(datPath);
            if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) {
                throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
            }
            waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
        } else {
            cfgPath = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.CFG;
            datPath = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.DAT;
            //适配文件后缀小写
            cfgPath2 = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.CFG.toLowerCase();
            datPath2 = OssPath.WAVE_DIR + ip + StrUtil.SLASH + waveName + GeneralConstant.DAT.toLowerCase();
            log.info("文件服务器波形文件路径----" + cfgPath);
            try (
                    InputStream cfgStream = fileStorageUtil.getFileStream(cfgPath);
                    InputStream datStream = fileStorageUtil.getFileStream(datPath)
            ) {
                if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) {
                    throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
                }
                waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
            } catch (Exception e) {
                try {
                    InputStream cfgStream = fileStorageUtil.getFileStream(cfgPath2);
                    InputStream datStream = fileStorageUtil.getFileStream(datPath2);
                    if (Objects.isNull(cfgStream) || Objects.isNull(datStream)) {
                        throw new BusinessException(WaveFileResponseEnum.ANALYSE_WAVE_NOT_FOUND);
                    }
                    waveDataDTO = waveFileComponent.getComtrade(cfgStream, datStream, 0);
                } catch (Exception e1) {
                    throw new BusinessException(WaveFileResponseEnum.WAVE_DATA_INVALID);
                }

            }
        }
        List<List<Float>> listWaveData = waveDataDTO.getListWaveData();
        // 暂降类型
        // 创建数据结构
        QvvrDLL.QvvrDataStruct typeDataStruct = new QvvrDLL.QvvrDataStruct();
        System.out.println("初始化qvvrdll成功-----------");
        typeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
        System.out.println("采样率-----------" + typeDataStruct.smp_rate);
        typeDataStruct.smp_len = listWaveData.size();
        System.out.println("波形长度-----------" + listWaveData.size());

        // 获取ABC三相的瞬时数据
        for (int i = 0; i < listWaveData.size(); i++) {
            typeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
            typeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
            typeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
        }


        // 执行算法分析 - 直接调用C DLL
        try {
            QvvrDLL.INSTANCE.qvvr_fun(typeDataStruct);
            System.out.println("调用qvvrdll成功-----------");

            if (typeDataStruct.evt_num > 0) {
                // 全局比较找出最小三相电压特征值
                float globalMinVoltage = Float.MAX_VALUE;
                int globalFaultType = 10;
                for (int i = 0; i < typeDataStruct.evt_num; i++) {
                    QvvrDLL.EventBuffer evt = typeDataStruct.evt_buf[i];
                    for (int j = 0; j < evt.u_min_num; j++) {
                        float u3min = evt.u3_min[j];
                        if (u3min < globalMinVoltage) {
                            globalMinVoltage = u3min;
                            globalFaultType = evt.qvvr_cata_type[j];
                        }
                    }
                }
                eventAnalysis.setType(globalFaultType);
            } else {
                eventAnalysis.setType(DataFeature.TYPE10);
            }
            System.out.println("结束qvvrdll方法调用-----------");
        } catch (Exception e) {
            eventAnalysis.setType(DataFeature.TYPE10);
            eventAnalysis.setTypeFlag(0);
        }


        // 暂降原因JNA的方式
        QvvrCauseDLL.QvvrDataStruct causeDataStruct = new QvvrCauseDLL.QvvrDataStruct();
        causeDataStruct.smp_rate = waveDataDTO.getComtradeCfgDTO().getFinalSampleRate();
        causeDataStruct.smp_len = listWaveData.size();
        // 获取ABC三相的瞬时数据
        for (int i = 0; i < listWaveData.size(); i++) {
            causeDataStruct.smp_va[i] = listWaveData.get(i).get(1);
            causeDataStruct.smp_vb[i] = listWaveData.get(i).get(2);
            causeDataStruct.smp_vc[i] = listWaveData.get(i).get(3);
        }
        // 执行算法分析 - 直接调用C DLL
        try {
            QvvrCauseDLL.INSTANCE.qvvr_fun_cause(causeDataStruct);
            eventAnalysis.setCause(causeDataStruct.cause);
            if (causeDataStruct.no_cal != 0) {
                eventAnalysis.setCauseFlag(0);
            }
        } catch (Exception e) {
            eventAnalysis.setCause(DataFeature.CAUSE_TYPE0);
            eventAnalysis.setCauseFlag(0);
        }
        System.out.println("暂降原因分析完毕===============");
        System.out.println("cause:" + eventAnalysis);
        return eventAnalysis;
    }
}
