package com.njcn.harmonic.service.upload.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.device.biz.commApi.CommLineClient;
import com.njcn.device.pms.api.MonitorClient;
import com.njcn.device.pms.api.PmsTerminalClient;
import com.njcn.device.pms.pojo.po.Monitor;
import com.njcn.device.pms.pojo.po.PmsTerminal;
import com.njcn.harmonic.mapper.upload.RUploadCommPointBusMapper;
import com.njcn.harmonic.mapper.upload.RUploadMainMonitorDataMapper;
import com.njcn.harmonic.pojo.dto.upload.RUploadMainMonitorDataDTO;
import com.njcn.harmonic.pojo.param.UploadDataParam;
import com.njcn.harmonic.pojo.po.upload.RUploadCommPointBus;
import com.njcn.harmonic.pojo.po.upload.RUploadMainMonitorData;
import com.njcn.harmonic.service.upload.RUploadCommPointBusService;
import com.njcn.harmonic.service.upload.RUploadMainMonitorService;
import com.njcn.system.api.DicDataFeignClient;
import com.njcn.system.api.DictTreeFeignClient;
import com.njcn.system.enums.DicDataEnum;
import com.njcn.system.enums.DicDataTypeEnum;
import com.njcn.system.enums.DicTreeEnum;
import com.njcn.system.pojo.po.DictData;
import com.njcn.system.pojo.po.SysDicTreePO;
import com.njcn.system.pojo.vo.DictTreeVO;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.vo.DeptTreeVO;
import com.njcn.user.pojo.vo.PvTerminalTreeVO;
import com.njcn.web.enums.GWSendEnum;
import com.njcn.web.factory.PageFactory;
import com.njcn.web.pojo.param.SendParam;
import com.njcn.web.utils.GwSendUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 公共连接点母线电能质量统计 服务实现类
 * </p>
 *
 * @author cdf
 * @since 2024-08-15
 */
@Service
@RequiredArgsConstructor
public class RUploadMainMonitorServiceImpl extends ServiceImpl<RUploadMainMonitorDataMapper, RUploadMainMonitorData> implements RUploadMainMonitorService {

    private final MonitorClient monitorClient;

    private final DeptFeignClient deptFeignClient;

    private final DicDataFeignClient dicDataFeignClient;

    private final DictTreeFeignClient dictTreeFeignClient;

    private final PmsTerminalClient pmsTerminalClient;


    @Override
    public Page<RUploadMainMonitorDataDTO> getMainMonitorPage(UploadDataParam param) {
        Page<RUploadMainMonitorDataDTO> result = new Page<>(param.getPageNum(),param.getPageSize());

        DateTime dateTime = DateUtil.parse(param.getSearchBeginTime(), DatePattern.NORM_DATE_PATTERN);
        if(param.getDataType().equals(DicDataEnum.STATISTICAL_TYPE_M.getCode())){
            param.setSearchBeginTime(DateUtil.format(dateTime,DatePattern.NORM_MONTH_PATTERN));
        }else if(param.getDataType().equals(DicDataEnum.STATISTICAL_TYPE_Y.getCode())){
            param.setSearchBeginTime(DateUtil.format(dateTime,DatePattern.NORM_YEAR_PATTERN));
        }
        LambdaQueryWrapper<RUploadMainMonitorData> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(RUploadMainMonitorData::getStatisticalType,param.getDataType())
                .eq(RUploadMainMonitorData::getStatisticalDate,param.getSearchBeginTime());
        Page<RUploadMainMonitorData> page = this.page(new Page<>(PageFactory.getPageNum(param),PageFactory.getPageSize(param)),lambdaQueryWrapper);
        if(CollUtil.isEmpty(page.getRecords())){
            return result;
        }
        List<RUploadMainMonitorData> rUploadMainMonitorDataList = page.getRecords();
        List<RUploadMainMonitorDataDTO> rUploadMainMonitorDataDTOList = new ArrayList<>();
        dataToResult(rUploadMainMonitorDataList,rUploadMainMonitorDataDTOList);
        result.setRecords(rUploadMainMonitorDataDTOList);
        result.setTotal(page.getTotal());
        return result;
    }

    @Override
    public Boolean upGwMainMonitor(UploadDataParam param) {
        if(StrUtil.isBlank(param.getSearchBeginTime())){
            throw new BusinessException("日期不可为空");
        }
        LambdaQueryWrapper<RUploadMainMonitorData> lambdaQueryWrapper = new LambdaQueryWrapper<>();

        String temDate = param.getSearchBeginTime();
        if(StrUtil.isBlank(param.getDataType())){
            //类型为空则上送日月年数据
            DateTime dateTime = DateUtil.parse(param.getSearchBeginTime(),DatePattern.NORM_DATE_PATTERN);
            String month = DateUtil.format(dateTime,DatePattern.NORM_MONTH_PATTERN);
            String year = DateUtil.format(dateTime,DatePattern.NORM_YEAR_PATTERN);
            lambdaQueryWrapper.in(RUploadMainMonitorData::getStatisticalDate, Stream.of(temDate,month,year).collect(Collectors.toList()));
        }else {
            if(param.getDataType().equals(DicDataEnum.STATISTICAL_TYPE_M.getCode())){
                temDate = DateUtil.format(DateUtil.parse(param.getSearchBeginTime(),DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_MONTH_PATTERN);
            }else if(param.getDataType().equals(DicDataEnum.STATISTICAL_TYPE_Y.getCode())){
                temDate = DateUtil.format(DateUtil.parse(param.getSearchBeginTime(),DatePattern.NORM_DATE_PATTERN),DatePattern.NORM_YEAR_PATTERN);
            }
            lambdaQueryWrapper.eq(RUploadMainMonitorData::getStatisticalType,param.getDataType())
                    .eq(RUploadMainMonitorData::getStatisticalDate,temDate);
        }
        List<RUploadMainMonitorData> rUploadMainMonitorDataList = this.list(lambdaQueryWrapper);
        if(CollUtil.isEmpty(rUploadMainMonitorDataList)){
            throw new BusinessException("查询数据为空");
        }

        List<RUploadMainMonitorDataDTO> rUploadMainMonitorDataDTOList = new ArrayList<>();
        dataToResult(rUploadMainMonitorDataList,rUploadMainMonitorDataDTOList);

        List<List<RUploadMainMonitorDataDTO>> list = CollUtil.split(rUploadMainMonitorDataDTOList,100);
        for(int i=0;i<list.size();i++){
            SendParam sendParam = new SendParam();
            if(i==0){
                sendParam.setIsAppend("0");
            }else if(i==list.size()-1){
                sendParam.setIsAppend("2");
            }else {
                sendParam.setIsAppend("1");
            }

            if(StrUtil.isNotBlank(param.getDataType())){
                sendParam.setStatisticalType(param.getDataType());
            }

            sendParam.setStatisticalDate(temDate);
            sendParam.setStats(list.get(i));
            Map<String, String> sendRes = GwSendUtil.newSend(sendParam, GWSendEnum.MAIN_MONITOR);
            List<String> ids = list.get(i).stream().map(RUploadMainMonitorDataDTO::getObjId).collect(Collectors.toList());
            int count = GwSendUtil.returnInfoMsg(ids,sendRes);
            System.out.println("上送成功,上送成功返回"+count+"条");
           // if(count == list.get(i).size()){
                LambdaUpdateWrapper<RUploadMainMonitorData> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                lambdaUpdateWrapper.set(RUploadMainMonitorData::getUploadStatus,1).in(RUploadMainMonitorData::getObjId,ids);
                this.update(lambdaUpdateWrapper);
          //  }
        }
        return true;
    }



    private void assOrg(Map<String,PvTerminalTreeVO> pvTerminalTreeVOCodeMap,Map<String,PvTerminalTreeVO> pvTerminalTreeVOIdMap,RUploadMainMonitorDataDTO rUploadMainMonitorDataDTO,Monitor monitor){
        PvTerminalTreeVO pvTerminalTreeVO = pvTerminalTreeVOCodeMap.get(monitor.getOrgId());
        rUploadMainMonitorDataDTO.setMaintOrg(pvTerminalTreeVO.getCode());
        rUploadMainMonitorDataDTO.setMaintOrgName(pvTerminalTreeVO.getName());

        PvTerminalTreeVO pvTerminalTreeCity = pvTerminalTreeVOIdMap.get(pvTerminalTreeVO.getPid());
        rUploadMainMonitorDataDTO.setCityOrg(pvTerminalTreeCity.getCode());
        rUploadMainMonitorDataDTO.setCityOrgName(pvTerminalTreeCity.getName());

        PvTerminalTreeVO pvTerminalTreeProvince = pvTerminalTreeVOIdMap.get(pvTerminalTreeCity.getPid());
        rUploadMainMonitorDataDTO.setProvinceOrg(pvTerminalTreeProvince.getCode());
        rUploadMainMonitorDataDTO.setProvinceOrgName(pvTerminalTreeProvince.getName());
    }


    /**
     * 数据赋值
     * @param rUploadMainMonitorDataList
     * @param rUploadMainMonitorDataDTOList
     */
    private void dataToResult(List<RUploadMainMonitorData> rUploadMainMonitorDataList,List<RUploadMainMonitorDataDTO> rUploadMainMonitorDataDTOList){
        List<PvTerminalTreeVO> deptTreeVOList = deptFeignClient.allDeptList().getData();
        Map<String,PvTerminalTreeVO> pvTerminalTreeVOCodeMap = deptTreeVOList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getCode,Function.identity()));
        Map<String,PvTerminalTreeVO> pvTerminalTreeVOIdMap = deptTreeVOList.stream().collect(Collectors.toMap(PvTerminalTreeVO::getId,Function.identity()));


        List<DictData> dictDataList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_VOLTAGE.getCode()).getData();
        Map<String,DictData> voltageMap = dictDataList.stream().collect(Collectors.toMap(DictData::getId,Function.identity()));

        List<DictData> stateList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.LINE_STATE.getCode()).getData();
        Map<String,DictData> stateMap = stateList.stream().collect(Collectors.toMap(DictData::getId,Function.identity()));

        //监测点标签
        List<DictData> tagList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.MONITORING_LABELS.getCode()).getData();
        Map<String,DictData> tagMap = tagList.stream().collect(Collectors.toMap(DictData::getId,Function.identity()));
        //监测点接线方式
        List<DictData> wireList = dicDataFeignClient.getDicDataByTypeCode(DicDataTypeEnum.DEV_CONNECT.getCode()).getData();
        Map<String,DictData> wireMap = wireList.stream().collect(Collectors.toMap(DictData::getId,Function.identity()));


        List<SysDicTreePO>  sysDicTreePOList = dictTreeFeignClient.queryAllByType(Integer.valueOf(DicTreeEnum.HB_PMS_TYPE.getCode())).getData();
        Map<String,SysDicTreePO> dicTreeMap = sysDicTreePOList.stream().collect(Collectors.toMap(SysDicTreePO::getId,Function.identity()));

        //获取测点map
        List<String> monitorIds = rUploadMainMonitorDataList.stream().map(RUploadMainMonitorData::getMonitorId).distinct().collect(Collectors.toList());
        List<Monitor> monitorList = monitorClient.getMonitorListByMid(monitorIds).getData();
        Map<String,Monitor> monitorMap = monitorList.stream().collect(Collectors.toMap(Monitor::getMonitorId, Function.identity()));

        List<String> terminalIds = monitorList.stream().map(Monitor::getTerminalId).distinct().collect(Collectors.toList());
        List<PmsTerminal> pmsTerminalList = pmsTerminalClient.getTerminalSelectByIds(terminalIds).getData();
        Map<String,PmsTerminal> pmsTerminalMap = pmsTerminalList.stream().collect(Collectors.toMap(PmsTerminal::getId,Function.identity()));


        rUploadMainMonitorDataList.forEach(item->{
            RUploadMainMonitorDataDTO rUploadMainMonitorDataDTO = new RUploadMainMonitorDataDTO();
            BeanUtil.copyProperties(item,rUploadMainMonitorDataDTO);

            if(monitorMap.containsKey(item.getMonitorId())){
                Monitor monitor = monitorMap.get(item.getMonitorId());
                assOrg(pvTerminalTreeVOCodeMap,pvTerminalTreeVOIdMap,rUploadMainMonitorDataDTO,monitor);
                rUploadMainMonitorDataDTO.setMonitorName(monitor.getName());
                rUploadMainMonitorDataDTO.setMonitorVoltageLevel(String.format("%02d",voltageMap.get(monitor.getVoltageLevel()).getAlgoDescribe()));
                rUploadMainMonitorDataDTO.setMonitorStatus(stateMap.get(monitor.getMonitorState()).getValue());
                rUploadMainMonitorDataDTO.setSubstationId(monitor.getPowerrId());
                rUploadMainMonitorDataDTO.setSubstationName(monitor.getPowerrName());
                rUploadMainMonitorDataDTO.setBusId(monitor.getLineId());
                rUploadMainMonitorDataDTO.setBusName(monitor.getLineName());

                String objType = monitor.getObjType();
                SysDicTreePO sysDicTreePO = dicTreeMap.get(objType);
                rUploadMainMonitorDataDTO.setMonitorObjTypeSmall(sysDicTreePO.getCode());
                if("0".equals(sysDicTreePO.getPid())){
                    rUploadMainMonitorDataDTO.setMonitorObjTypeBig(sysDicTreePO.getCode());
                }else {
                    SysDicTreePO sysDicTreeSmall = dicTreeMap.get(sysDicTreePO.getPid());
                    rUploadMainMonitorDataDTO.setMonitorObjTypeBig(sysDicTreeSmall.getCode());
                }
                rUploadMainMonitorDataDTO.setMonitorTag(tagMap.get(monitor.getMonitorTag()).getValue());
                rUploadMainMonitorDataDTO.setMonitorObjName(monitor.getMonitorObjectName());
                rUploadMainMonitorDataDTO.setMinShortCapacity(BigDecimal.valueOf(monitor.getMinShortCircuitCapacity()));
                rUploadMainMonitorDataDTO.setSupplyEquipCapacity(BigDecimal.valueOf(monitor.getPowerSupplyEqCapacity()));
                rUploadMainMonitorDataDTO.setUserProtocolCapacity(BigDecimal.valueOf(monitor.getUserAgreementCapacity()));

                PmsTerminal pmsTerminal = pmsTerminalMap.get(monitor.getTerminalId());
                rUploadMainMonitorDataDTO.setTerminalCode(pmsTerminal.getTerminalCode());
                rUploadMainMonitorDataDTO.setTerminalConnect(wireMap.get(monitor.getTerminalWiringMethod()).getValue());
            }

            rUploadMainMonitorDataDTOList.add(rUploadMainMonitorDataDTO);
        });
    }



}
