package org.dromara.elevator.service.impl;

import cn.hutool.core.date.DateUtil;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.service.DictService;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.elevator.constant.ElevatorConstant;
import org.dromara.elevator.constant.WorkStateEnum;
import org.dromara.elevator.constant.WorkType;
import org.dromara.elevator.domain.bo.*;
import org.dromara.elevator.domain.vo.*;
import org.dromara.elevator.service.*;
import org.dromara.system.domain.bo.SysDeptBo;
import org.dromara.system.domain.vo.SysDeptVo;
import org.dromara.system.service.ISysDeptService;
import org.springframework.stereotype.Service;

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

import static org.dromara.elevator.constant.ElevatorConstant.TRAPPED_FAULT_CODE_LIST;

/**
 * 首页业务接口实现
 *
 * @author ym
 * @version 1.0.0
 * @date 2024-09-18 11:20
 */
@Service
@RequiredArgsConstructor
public class HomeServiceImpl implements HomeService {

    private final IEElevatorInfoService elevatorInfoService;
    private final IEFaultStatisticsService faultStatisticsService;
    private final IEMaintenanceInfoService maintenanceInfoService;
    private final IEThirdPartyUserService thirdPartyUserService;
    private final ISysDeptService deptService;
    private final IEWorkDataService workDataService;
    private final IEBlackBoxInfoService blackBoxInfoService;
    private final DictService dictService;

    @Override
    public HomeInfoVo queryHomeInfo(HomeInfoBo bo) {
        if (Objects.isNull(bo.getStartTime()) || Objects.isNull(bo.getEndTime())) {
            Date now = new Date();
            bo.setStartTime(DateUtil.beginOfDay(now));
            bo.setEndTime(DateUtil.endOfDay(now));
        }

        HomeInfoVo homeInfo = new HomeInfoVo();
        // 今日困人电梯数 (部)
        EFaultStatisticsBo faultStatisticsBo = new EFaultStatisticsBo();
        // 困人故障code
        faultStatisticsBo.setFaultCodeList(TRAPPED_FAULT_CODE_LIST);
        List<EFaultStatisticsVo> faultStatisticsList = faultStatisticsService.queryList(faultStatisticsBo);
        Set<String> elevatorNumSet = faultStatisticsList.stream().map(EFaultStatisticsVo::getElevatorNum).collect(Collectors.toSet());
        homeInfo.setTrappedEleNum(elevatorNumSet.size());
        // 超期未检验电梯数
        EWorkDataBo workDataBo = new EWorkDataBo();
        workDataBo.setOverdueFlag(Boolean.TRUE);
        workDataBo.setWorkType(WorkType.REPAIR.getType());
        workDataBo.setStateList(WorkStateEnum.unComplete());
        workDataBo.setExpectTime(LocalDate.now());
        List<EWorkDataVo> expiredRepairList = workDataService.queryList(workDataBo);
        Set<String> expiredEleNumSet = expiredRepairList.stream().map(EWorkDataVo::getElevatorNum).collect(Collectors.toSet());
        homeInfo.setExpiredMainEleNum(expiredEleNumSet.size());
        homeInfo.setExpiredEleNumList(new ArrayList<>(expiredEleNumSet));
        // 逾期未保养电梯数
        workDataBo.setWorkType(WorkType.MAINTENANCE.getType());
        List<EWorkDataVo> overdueMaintenanceList = workDataService.queryList(workDataBo);
        Set<String> overdueEleNumSet = overdueMaintenanceList.stream().map(EWorkDataVo::getElevatorNum).collect(Collectors.toSet());
        homeInfo.setOverdueMainEleNum(overdueEleNumSet.size());
        homeInfo.setOverdueEleNumList(new ArrayList<>(overdueEleNumSet));

        // 项目数量
        List<SysDeptVo> deptList = deptService.selectDeptList(new SysDeptBo());
        Set<Long> parentIds = new HashSet<>();
        List<Long> deptIds = deptList.stream().peek(item -> parentIds.add(item.getParentId()))
            .map(SysDeptVo::getDeptId).collect(Collectors.toList());
        deptIds.removeAll(parentIds);
        homeInfo.setProjectNum(deptIds.size());

        // 维保企业数量
        List<EMaintenanceInfoVo> maintenanceList = maintenanceInfoService.queryList(new EMaintenanceInfoBo());
        homeInfo.setMaintenanceNum(maintenanceList.size());
        List<String> maintenanceIds = StreamUtils.toList(maintenanceList, item -> String.valueOf(item.getId()));
        // 维保员工数量
        EThirdPartyUserBo thirdPartyUserBo = new EThirdPartyUserBo();
        thirdPartyUserBo.setUnitIds(maintenanceIds);
        List<EThirdPartyUserVo> thirdPartyUserList = thirdPartyUserService.queryList(thirdPartyUserBo);
        homeInfo.setMaintenanceStaffNum(thirdPartyUserList.size());

        // 接入电梯总数
        homeInfo.setElevatorNum(elevatorInfoService.selectCount(new EElevatorInfoBo()).intValue());
        // 安装智能终端数量
        Long deviceNum = blackBoxInfoService.selectCount(new EBlackBoxInfoBo());
        homeInfo.setDeviceNum(deviceNum.intValue());
        return homeInfo;
    }

    @Override
    public TableDataInfo<RescueOverTimeVo> pageRescueList(HomeInfoBo bo, PageQuery pageQuery) {
        // TODO 待补全
        return TableDataInfo.build(new ArrayList<>());
    }

    @Override
    public TableDataInfo<ProjectFaultVo> pageFaultList(HomeInfoBo bo, PageQuery pageQuery) {
        EFaultStatisticsBo faultStatisticsBo = new EFaultStatisticsBo();
        faultStatisticsBo.setStartTime(bo.getStartTime());
        faultStatisticsBo.setEndTime(bo.getEndTime());
        Map<String, String> faultMap = dictService.getAllDictByDictType(ElevatorConstant.FAULT_TYPE_DICT_KEY);

        faultStatisticsBo.setFaultCodeList(new ArrayList<>(faultMap.keySet()));
        return faultStatisticsService.queryFaultPageList(faultStatisticsBo, pageQuery);
    }

    @Override
    public TableDataInfo<ProjectFaultVo> pageTrappedList(HomeInfoBo bo, PageQuery pageQuery) {
        EFaultStatisticsBo faultStatisticsBo = new EFaultStatisticsBo();
        faultStatisticsBo.setStartTime(bo.getStartTime());
        faultStatisticsBo.setEndTime(bo.getEndTime());
        faultStatisticsBo.setFaultCodeList(TRAPPED_FAULT_CODE_LIST);
        return faultStatisticsService.queryFaultPageList(faultStatisticsBo, pageQuery);
    }
}
