package com.njcn.influx.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.njcn.influx.bo.po.*;
import com.njcn.influx.config.RedisUtil;
import com.njcn.influx.mapper.OracleRmpEventDetailPOMapper;
import com.njcn.influx.mapper.PqDeviceMapper;
import com.njcn.influx.mapper.RmpEventDetailPOMapper;
import com.njcn.influx.service.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wr
 * @description
 * @date 2024/3/5 15:04
 */
@RequiredArgsConstructor
@Service
public class OracleMonitorStatusToMysqlServiceImpl implements OracleMonitorStatusToMysqlService {

    @Value("${business.type}")
    private Integer systemType;

    private final RmpEventDetailPOMapper rmpEventDetailPOMapper;
    private final IPqDeviceBakService pqDeviceBakService;
    private final PqDeviceMapper pqDeviceMapper;
    private final IPmsMonitorService pmsMonitorService;
    private final IPmsTerminalService pmsTerminalService;
    private final PqDeviceMysqlService pqDeviceMysqlService;
    private final PqLineBakService pqLineBakService;
    private final OraclePqLineDetailService oraclePqLineDetailService;
    private final IPqLineDetailService pqLineDetailService;
    private final OracleRmpEventDetailPOMapper oracleRmpEventDetailPOMapper;
    private final RedisUtil redisUtil;

    /**
     * 1.查询oracle装置表信息
     * 2.查询pq_device_bak->mysql匹配oracle所对应的装置
     * 3.更改mysql监测点信息和装置信息
     */
    @Override
    public void monitorStatusSync() {
        Map<String, String> DevIdMapping = (Map<String, String>) redisUtil.getObjectByKey("DevIdMapping");
        List<DictData> monitorDicList = rmpEventDetailPOMapper.selectByDicCodeList("Line_State");
        List<DictData> devDicList = rmpEventDetailPOMapper.selectByDicCodeList("Dev_Status");
        List<PqDeviceBak> list = pqDeviceBakService.list();
        //lineId:Oracle终端ID id:Mysql终端ID
        Map<Long, String> oracleDevMysql = list.stream().collect(Collectors.toMap(PqDeviceBak::getDevId, PqDeviceBak::getId));
        List<PqDevice> pqDevices = pqDeviceMapper.selectList(null);
        //pq的设备表更改通信状态
        if(systemType == 0){
            List<PqDeviceMysql>  tempList = new ArrayList<>();
            pqDevices.stream().forEach(temp->{
                String id ="";
                if (!DevIdMapping.containsKey(temp.getDevIndex()+"")){
                    return;
                }else {
                    id=DevIdMapping.get(temp.getDevIndex()+"");
                }
                pqDeviceMysqlService.update(new LambdaUpdateWrapper<PqDeviceMysql>()
                        .set(PqDeviceMysql::getRunFlag,temp.getDevFlag())
                        .set(PqDeviceMysql::getComFlag,temp.getStatus())
                        .set(PqDeviceMysql::getUpdateTime,temp.getUpdateTime())
                        .eq(PqDeviceMysql::getId,id));

            });
        }else {
            Map<Integer, List<Long>> oracleDevMap = pqDevices.stream().collect(Collectors.groupingBy(PqDevice::getDevFlag
                    , Collectors.mapping(PqDevice::getDevIndex, Collectors.toList())));
            oracleDevMap.forEach((key, value) -> {
                List<String> info = new ArrayList<>();
                for (Long aLong : value) {
                    if (oracleDevMysql.containsKey(aLong)) {
                        info.add(oracleDevMysql.get(aLong));
                    }
                }
                String devStatus = devStatusId(key, devDicList);
                String monitorStatus = monitorStatusId(key, monitorDicList);
                if (StrUtil.isNotBlank(devStatus) && CollUtil.isNotEmpty(info)) {
                    //修改终端状态
                    pmsTerminalService.update(new LambdaUpdateWrapper<PmsTerminal>()
                            .set(PmsTerminal::getTerminalState, devStatusId(key, devDicList))
                            .in(PmsTerminal::getId, info)
                    );
                }
                if (StrUtil.isNotBlank(monitorStatus) && CollUtil.isNotEmpty(info)) {
                    //修改监测点状态
                    pmsMonitorService.update(new LambdaUpdateWrapper<PmsMonitor>()
                            .set(PmsMonitor::getMonitorState, monitorStatusId(key, monitorDicList))
                            .in(PmsMonitor::getTerminalId, info)
                    );
                }
            });
        }




    }

    @Override
    public void devUpdateTimeSync() {
        List<PqDeviceBak> list = pqDeviceBakService.list();
        //lineId:Oracle终端ID id:Mysql终端ID
        Map<Long, String> oracleDevMysql = list.stream().collect(Collectors.toMap(PqDeviceBak::getDevId, PqDeviceBak::getId));
        List<PqDevice> pqDevices = pqDeviceMapper.selectList(null);
        Map<Long, LocalDateTime> oracleDevMap = pqDevices.stream().collect(Collectors.toMap(PqDevice::getDevIndex, PqDevice::getUpdateTime));

        oracleDevMap.forEach((key,value)->{
            if(oracleDevMysql.containsKey(key)){
                String mysqlDevID = oracleDevMysql.get(key);
                pmsTerminalService.update(new LambdaUpdateWrapper<PmsTerminal>()
                        .set(PmsTerminal::getUpdateTime,value)
                        .eq(PmsTerminal::getId,mysqlDevID)
                );
            }
        });
    }

    @Override
    public void monitorTimeSync() {
        List<PqLineBak> list = pqLineBakService.list();

        //lineId:Oracle监测点ID id:Mysql监测点ID
        Map<String, String> oracleRelationMysql = list.stream().collect(Collectors.toMap(PqLineBak::getId, PqLineBak::getLineId));
        //oracle监测点信息
        List<OraclePqLineDetail> oracleLineDetail = oraclePqLineDetailService.lineDetailList();
        Map<String, OraclePqLineDetail> oraclePqLineDetailMap =
                oracleLineDetail.stream().collect(Collectors.toMap(OraclePqLineDetail::getLineIndex, Function.identity()));
        //msql监测点
        List<PqLineDetail> lineDetail = pqLineDetailService.list();

        //干扰源类型
        List<String> loadTypeIds = oracleLineDetail.stream().map(OraclePqLineDetail::getLoadtype).distinct().collect(Collectors.toList());
        List<DictData> loadTypeData = oracleRmpEventDetailPOMapper.selectDicByIds(loadTypeIds);
        Map<String, String> loadTypeMap = loadTypeData.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));

        //行业类型
        List<String> businessTypeIds = oracleLineDetail.stream().map(OraclePqLineDetail::getBusinesstype).distinct().collect(Collectors.toList());
        List<DictData> businessTypeData = oracleRmpEventDetailPOMapper.selectDicByIds(businessTypeIds);
        Map<String, String> businessTypeMap = businessTypeData.stream().collect(Collectors.toMap(DictData::getId, DictData::getName));
        for (PqLineDetail line : lineDetail) {
            if (oracleRelationMysql.containsKey(line.getId())) {
                String s = oracleRelationMysql.get(line.getId());
                if(oraclePqLineDetailMap.containsKey(s)){
                    OraclePqLineDetail oraclePqLineDetail = oraclePqLineDetailMap.get(s);
                    LambdaUpdateWrapper<PqLineDetail> eq = new LambdaUpdateWrapper<PqLineDetail>()
                            .set(PqLineDetail::getPt1, oraclePqLineDetail.getPt1())
                            .set(PqLineDetail::getPt2, oraclePqLineDetail.getPt2())
                            .set(PqLineDetail::getCt1, oraclePqLineDetail.getCt1())
                            .set(PqLineDetail::getCt2, oraclePqLineDetail.getCt2())
                            .set(PqLineDetail::getDevCapacity, oraclePqLineDetail.getDevcMp())
                            .set(PqLineDetail::getShortCapacity, oraclePqLineDetail.getDlcMp())
                            .set(PqLineDetail::getStandardCapacity, oraclePqLineDetail.getJzcMp())
                            .set(PqLineDetail::getDealCapacity, oraclePqLineDetail.getXycMp())
                            .set(PqLineDetail::getPtType, oraclePqLineDetail.getPttype())
                            .set(PqLineDetail::getTimeInterval, oraclePqLineDetail.getTinterval())

                            .set(PqLineDetail::getPowerFlag, oraclePqLineDetail.getPowerid())
                            .set(PqLineDetail::getObjName, oraclePqLineDetail.getObjname())
                            .set(PqLineDetail::getMonitorId, oraclePqLineDetail.getMonitorId())
                            .set(PqLineDetail::getStatFlag, oraclePqLineDetail.getStatflag())
                            .set(PqLineDetail::getPowerSubstationName, oraclePqLineDetail.getPowerSubstationName())
                            .eq(PqLineDetail::getId, line.getId());
                    if(loadTypeMap.containsKey(oraclePqLineDetail.getLoadtype())){
                        DictData  loadType= rmpEventDetailPOMapper.getDicDataByNameAndTypeName("干扰源类型", loadTypeMap.get(oraclePqLineDetail.getLoadtype()));
                        if(ObjectUtil.isNotNull(loadType)){
                            eq.set(ObjectUtil.isNotNull(loadType), PqLineDetail::getLoadType, loadType.getId());
                        }
                    }
                    if(businessTypeMap.containsKey(oraclePqLineDetail.getBusinesstype())){
                        DictData businessType= rmpEventDetailPOMapper.getDicDataByNameAndTypeName("行业类型", businessTypeMap.get(oraclePqLineDetail.getBusinesstype()));
                        if(ObjectUtil.isNotNull(businessType)){
                            eq.set(ObjectUtil.isNotNull(businessType), PqLineDetail::getBusinessType, businessType.getId());
                        }
                    }
                    pqLineDetailService.update(eq);
                }
            }
        }

    }

    /**
     * @Description: 监测点状态类型
     */
    private String monitorStatusId(Integer data, List<DictData> list) {
        //装置状态（0：投运；1：热备用；2：停运）
        String code = "";
        switch (data) {
            case 0:
                code = "Run";
                break;
            case 1:
                code = "Overhaul";
                break;
            case 2:
                code = "Decommissioning";
                break;
        }
        String finalCode = code;
        DictData dictData = list.stream().filter(x -> finalCode.equals(x.getCode())).findFirst().get();
        if (ObjectUtil.isNotNull(dictData)) {
            return dictData.getId();
        }
        return "";
    }
    /**
     * @Description: 终端状态类型
     */
    private String devStatusId(Integer data, List<DictData> list) {
        //装置状态（0：投运；1：热备用；2：停运）
        String code = "";
        switch (data) {
            case 0:
                code = "Running";
                break;
            case 1:
                code = "Not_Operation";
                break;
            case 2:
                code = "Retire";
                break;
        }
        String finalCode = code;
        DictData dictData = list.stream().filter(x -> finalCode.equals(x.getCode())).findFirst().get();
        if (ObjectUtil.isNotNull(dictData)) {
            return dictData.getId();
        }
        return "";
    }


}
