package org.dromara.elevator.job;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.dromara.elevator.domain.EFaultStatistics;
import org.dromara.elevator.domain.vo.EElevatorInfoVo;
import org.dromara.elevator.domain.vo.EFaultMessageVo;
import org.dromara.elevator.service.IEElevatorInfoService;
import org.dromara.elevator.service.IEFaultMessageService;
import org.dromara.elevator.service.IEFaultStatisticsService;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 故障统计定时器
 *
 * @author ym
 * @version 1.0.0
 * @date 2024-09-04 09:26
 */
@EnableScheduling
@Component
@RequiredArgsConstructor
public class FaultStatisticsJob {

    private final IEFaultMessageService faultMessageService;

    private final IEElevatorInfoService elevatorInfoService;

    private final IEFaultStatisticsService faultStatisticsService;

    /**
     * 当天数据统计
     */
    //@Scheduled(cron = "0 0/5 * * * ? ")
    public void faultStatisticsJob() {
        Date now = new Date();
        Date beginTime = DateUtil.beginOfDay(now);
        Date endTime = DateUtil.endOfDay(now);
        doHandlerStFaultStatistics(beginTime, endTime);
    }

    /**
     * 补偿昨天数据统计
     */
    //@Scheduled(cron = "30 0 0 * * ? ")
    public void faultStatisticsYesterdayJob() {
        Date yesterday = DateUtil.yesterday();
        Date beginTime = DateUtil.beginOfDay(yesterday);
        Date endTime = DateUtil.endOfDay(yesterday);
        doHandlerStFaultStatistics(beginTime, endTime);
    }

    /**
     * 统计处理
     *
     * @param beginTime 开始时间
     * @param endTime   结束时间
     */
    private void doHandlerStFaultStatistics(Date beginTime, Date endTime) {
        List<EFaultMessageVo> faultList = faultMessageService.queryFaultListByHappenTime(beginTime, endTime);
        if (CollectionUtils.isEmpty(faultList)) {
            return;
        }
        // 根据电梯编号  故障编号分组
        Set<String> eleNumList = new HashSet<>();
        Map<String, List<EFaultMessageVo>> faultEleMap = faultList.stream().peek(item -> eleNumList.add(item.getElevatorNum()))
            .collect(Collectors.groupingBy(item -> item.getElevatorNum() + StrUtil.UNDERLINE + item.getFaultCode()));
        List<EElevatorInfoVo> elevatorList = elevatorInfoService.selectByElevatorNumList(eleNumList);
        if (CollectionUtils.isEmpty(elevatorList)) {
            return;
        }

        List<EFaultStatistics> faultStatisticsList = faultStatisticsService.selectFaultStatisticsList(eleNumList, LocalDate.now());
        // 故障统计Map
        Map<String, EFaultStatistics> faultStatisticsMap = faultStatisticsList.stream().collect(
            Collectors.toMap(item -> item.getElevatorNum() + StrUtil.UNDERLINE + item.getFaultCode(),
                Function.identity(), (o1, o2) -> o1));
        // 电梯信息Map
        Map<String, EElevatorInfoVo> elevatorMap = elevatorList.stream()
            .collect(Collectors.toMap(EElevatorInfoVo::getElevatorNum, Function.identity(), (o1, o2) -> o1));

        // 构建故障统计信息
        List<EFaultStatistics> statisticsList = faultEleMap.entrySet().stream().map(item -> {
            String[] keyArr = item.getKey().split(StrUtil.UNDERLINE);
            return buildFaultStatistics(elevatorMap.get(keyArr[0]), faultStatisticsMap.get(item.getKey()), item.getValue());
        }).filter(Objects::nonNull).collect(Collectors.toList());

        faultStatisticsService.insertOrUpdateBatch(statisticsList);
    }

    /**
     * 构建故障统计
     *
     * @param elevator        电梯信息
     * @param faultStatistics 故障统计
     * @param faultMsgList    故障消息
     * @return 故障统计
     */
    private EFaultStatistics buildFaultStatistics(EElevatorInfoVo elevator, EFaultStatistics faultStatistics,
                                                  List<EFaultMessageVo> faultMsgList) {
        if (Objects.isNull(elevator)) {
            return null;
        }
        if (Objects.isNull(faultStatistics)) {
            faultStatistics = new EFaultStatistics();
            faultStatistics.setCreateBy(1L);
            faultStatistics.setRegisterCode(elevator.getRegisterCode());
            faultStatistics.setElevatorNum(elevator.getElevatorNum());
            faultStatistics.setElevatorName(elevator.getElevatorName());
            faultStatistics.setDeviceCode(elevator.getDeviceCode());
            faultStatistics.setTenementId(Long.valueOf(elevator.getTenementId()));
            faultStatistics.setTenementName(elevator.getTenementName());
            faultStatistics.setMaintenanceId(Long.valueOf(elevator.getMaintenanceId()));
            faultStatistics.setMaintenanceName(elevator.getMaintenanceName());
            faultStatistics.setFaultCode(faultMsgList.get(0).getFaultCode());
            faultStatistics.setFaultName(faultMsgList.get(0).getFaultName());
            faultStatistics.setFaultTime(LocalDate.now());
            faultStatistics.setDeptId(elevator.getDeptId());
            faultStatistics.setAreaCode(elevator.getAreaCode());
            faultStatistics.setBrand(elevator.getBrand());
            faultStatistics.setUseScenario(elevator.getUseScenario());
        }
        faultStatistics.setFaultNum(faultMsgList.size());
        return faultStatistics;
    }

}
