package com.njcn.event.service.majornetwork.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.njcn.device.pq.api.DeptLineFeignClient;
import com.njcn.device.pq.api.LineFeignClient;
import com.njcn.device.pq.api.UserLedgerFeignClient;
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
import com.njcn.event.pojo.param.VoltageRideThroughQueryParam;
import com.njcn.event.pojo.po.EventDetail;
import com.njcn.event.pojo.vo.EventNewStationVo;
import com.njcn.event.pojo.vo.VoltageRideThroughVo;
import com.njcn.event.common.service.EventDetailService;
import com.njcn.event.service.majornetwork.SpThroughService;
import com.njcn.event.service.majornetwork.VoltageRideThroughEventService;
import com.njcn.event.pojo.param.SpThroughParam;
import com.njcn.supervision.pojo.vo.user.NewUserReportVO;
import com.njcn.system.api.AreaFeignClient;
import com.njcn.system.pojo.po.Area;
import com.njcn.user.api.DeptFeignClient;
import com.njcn.user.pojo.dto.DeptDTO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 高低电压穿越统计 服务类实现类
 * </p>
 *
 * @author guofeihu
 * @since 2024-08-14
 */
@Service
@AllArgsConstructor
@Slf4j
public class VoltageRideThroughEventServiceImpl implements VoltageRideThroughEventService {

    private final AreaFeignClient areaFeignClient;
    private final DeptFeignClient deptFeignClient;
    private final DeptLineFeignClient deptLineFeignClient;
    private final LineFeignClient lineFeignClient;
    private final EventDetailService eventDetailService;
    private final SpThroughService spThroughService;
    private final UserLedgerFeignClient userLedgerFeignClient;

    @Override
    public List<VoltageRideThroughVo> voltageRideThroughView(VoltageRideThroughQueryParam param) {
        List<VoltageRideThroughVo> voltageRideThroughVos = new ArrayList<>();
        //根据当前选择的部门ID获取其下的子部门集合
        List<DeptDTO> deptDTOS = deptFeignClient.getDepSonDetailByDeptId(param.getAreaId()).getData();
        for (DeptDTO deptDTO : deptDTOS) {
            //子部门信息
            VoltageRideThroughVo voltageRideThroughVo = new VoltageRideThroughVo();
            //赋值子部门名称及ID
            BeanUtils.copyProperties(deptDTO, voltageRideThroughVo);
            //根据部门的area获取经纬度
            Area area = areaFeignClient.selectIdArea(deptDTO.getArea()).getData();
            if (area != null) {
                voltageRideThroughVo.setLat(area.getLat());
                voltageRideThroughVo.setLng(area.getLng());
            }
            //开始计算当前地区高低压穿越次数
            //获取当前部门下所有的已绑定能源站的监测点
            List<String> lineIds = deptLineFeignClient.getLineByDeptIdAndNewStation(deptDTO.getId()).getData();
            if (!lineIds.isEmpty()) {
                //根据已绑定能源站的监测点获取关联的暂态事件
                List<EventDetail> eventDetails = eventDetailService.getEventDetail(lineIds,
                        DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())).toString(),
                        DateUtil.beginOfDay(DateUtil.parse(param.getSearchEndTime())).toString());
                if (CollUtil.isNotEmpty(eventDetails)) {
                    List<String> eventDetailIds = eventDetails.stream().map(EventDetail::getEventId).collect(Collectors.toList());
                    SpThroughParam spThroughParam = new SpThroughParam(eventDetailIds,null, param.getType());
                    List<String> eventIds = spThroughService.formatEventIds(spThroughParam);
                    spThroughParam.setEventIds(eventIds);
                    //赋值子部门高低电压穿越次数
                    BeanUtils.copyProperties(spThroughService.getDataByEventIds(spThroughParam), voltageRideThroughVo);
                }
            }
            voltageRideThroughVos.add(voltageRideThroughVo);
        }
        return voltageRideThroughVos;
    }

    @Override
    public List<EventNewStationVo> voltageRideThroughEventQueryPage(VoltageRideThroughQueryParam param) {
        List<EventNewStationVo> eventNewStationVos = new ArrayList<>();
        List<String> lineIds = new ArrayList<>();
        //获取当前部门下所有的已绑定能源站的监测点
        lineIds.addAll(deptLineFeignClient.getLineByDeptIdAndNewStation(param.getAreaId()).getData());
        if (!lineIds.isEmpty()) {
            //根据监测点获取监测点下所有的事件集合
            List<EventDetail> eventDetail = eventDetailService.getEventDetail(lineIds,
                    DateUtil.beginOfDay(DateUtil.parse(param.getSearchBeginTime())).toString(),
                    DateUtil.beginOfDay(DateUtil.parse(param.getSearchEndTime())).toString());
            eventNewStationVos = BeanUtil.copyToList(eventDetail, EventNewStationVo.class);
            if (!eventNewStationVos.isEmpty()) {
                List<String> eventDetailIds = eventNewStationVos.stream().map(EventNewStationVo::getEventId).collect(Collectors.toList());
                SpThroughParam spThroughParam = new SpThroughParam(eventDetailIds,param.getFrequencyType(), param.getType());
                //eventNewStationVos:事件集合中是包含了所有符合条件的事件,可能有部分事件并没有被高低电压穿越记录定时任务所执行 所以需要过滤下 具体逻辑说请看spThroughFeignClient.formatEventIds
                List<String> eventIds = spThroughService.formatEventIds(spThroughParam);
                //过滤掉不符合的事件(eventIds为有效事件ID)
                eventNewStationVos = eventNewStationVos.stream().filter(item -> eventIds.contains(item.getEventId())).collect(Collectors.toList());
                List<LineDetailDataVO> lineDetailDataVOS = lineFeignClient.getLineDetailList(lineIds).getData();
                Map<String, String> lineDetailDataMap = lineDetailDataVOS.stream().collect(Collectors.toMap(LineDetailDataVO::getLineId, LineDetailDataVO::getObjId));
                //特殊处理事件集合中新能源场站名称
                List<NewUserReportVO> userReportVOS = userLedgerFeignClient.getUserReportByIds(new ArrayList<>(lineDetailDataMap.values())).getData();
                Map<String, String> userReportMap = userReportVOS.stream().collect(Collectors.toMap(NewUserReportVO::getId, NewUserReportVO::getProjectName));
                for (EventNewStationVo eventNewStationVo : eventNewStationVos) {
                    if (lineDetailDataMap.containsKey(eventNewStationVo.getLineId())) {
                        String lineID = lineDetailDataMap.get(eventNewStationVo.getLineId());
                        if (userReportMap.containsKey(lineID)) {
                            eventNewStationVo.setNewStationName(userReportMap.get(lineID));
                        }
                    }
                }
            }
        }
        return eventNewStationVos;
    }
}
