package com.yuchen.saas.park.service.xxlJobThread;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.yuchen.saas.manage.system.api.entity.NestOrgUser;
import com.yuchen.saas.manage.system.api.feign.IOrgUserClient;
import com.yuchen.saas.manage.user.api.entity.User;
import com.yuchen.saas.manage.user.api.feign.IUserClient;
import com.yuchen.saas.message.api.dto.PmgBatMessageDto;
import com.yuchen.saas.message.api.feign.message.MessageFeignServer;
import com.yuchen.saas.park.api.entity.fire.inspect.SaasParkFireInspectPlan;
import com.yuchen.saas.park.api.entity.fire.inspect.SaasParkFireInspectPlanTask;
import com.yuchen.saas.park.api.enums.inspect.PlanExecuteStateEnum;
import com.yuchen.saas.park.api.enums.inspect.TaskStateEnum;
import com.yuchen.saas.park.service.service.fire.inspect.ISaasParkFireInspectPlanService;
import com.yuchen.saas.park.service.service.fire.inspect.ISaasParkFireInspectPlanTaskService;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.mp.base.BaseEntity;
import org.nest.springwrap.core.tool.utils.DateUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhouhanwei
 * @create 2024/4/10 15:29
 */
@Component
@Slf4j
public class InspectPlanTaskJob {

    @Resource
    private ISaasParkFireInspectPlanService planService;

    @Resource
    private ISaasParkFireInspectPlanTaskService planTaskService;

    @Resource
    private MessageFeignServer messageFeignServer;

    @Resource
    private IOrgUserClient iOrgUserClient;

    @Resource
    private IUserClient iUserClient;

    @XxlJob("inspectPlanTaskSendJobHandler")
    public void inspectPlanTaskSendJobHandler() {
        log.info("智慧巡检任务通知");
        Date newDate = new Date();
        LambdaQueryWrapper<SaasParkFireInspectPlanTask> lambdaWrapper = Wrappers.lambdaQuery();
        // 是否开启任务通知
        lambdaWrapper.eq(SaasParkFireInspectPlanTask::getTaskStartNotifyDemand, "1");
        lambdaWrapper.le(SaasParkFireInspectPlanTask::getTaskNotifyTime, newDate);
        // 开启任务通知的任务数据
        List<SaasParkFireInspectPlanTask> planTaskList = planTaskService.list(lambdaWrapper);
        // 添加服务消息
        List<PmgBatMessageDto> messageDtoList = new ArrayList<>();
        if (CollUtil.isNotEmpty(planTaskList)) {
            // 获取所有的人员列表
            List<Long> orgUserAllList = new ArrayList<>();
            for (SaasParkFireInspectPlanTask planTask : planTaskList) {
                List<Long> taskPeopleIds = Arrays.stream(planTask.getTaskPeopleIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
                orgUserAllList.addAll(taskPeopleIds);
            }
            // 获取所有人员数据
            List<NestOrgUser> orgUserList = iOrgUserClient.findOrgUserListByIds(orgUserAllList.stream().distinct().collect(Collectors.toList())).getData();
            Map<Long, NestOrgUser> orgUserMap = orgUserList.stream().collect(Collectors.toMap(NestOrgUser::getId, v -> v, (v1, v2) -> v2));
            // 获取平台用户id
            List<Long> userIdList = orgUserList.stream().map(NestOrgUser::getUserId).collect(Collectors.toList());
            List<User> userList = iUserClient.findUserListByUserIds(userIdList).getData();
            Map<Long, Long> userListMap = userList.stream().collect(Collectors.toMap(BaseEntity::getId, User::getUserDetailId));
            for (SaasParkFireInspectPlanTask planTask : planTaskList) {
                List<Long> taskPeopleIdList = Arrays.stream(planTask.getTaskPeopleIds().split(",")).map(Long::parseLong).collect(Collectors.toList());
                for (Long orgUserId : taskPeopleIdList) {
                    // 封装站内消息
                    PmgBatMessageDto messageDto = new PmgBatMessageDto();
                    messageDto.setMessageType(3);
                    messageDto.setMessageTitle(planTask.getReceiptCode());
                    messageDto.setLinkId(planTask.getId());
                    messageDto.setLinkType(6);
                    Long orgId = orgUserMap.get(orgUserId).getDeptId();
                    messageDto.setSiteId(orgId);
                    Long userId = orgUserMap.get(orgUserId).getUserId();
                    Long userDetailId = userListMap.get(userId);
                    messageDto.setUserDetailId(userDetailId);
                    messageDto.setCustomerId(planTask.getCustomerId());
                    messageDto.setMessageTime(newDate);
                    messageDtoList.add(messageDto);
                }
            }
            // 发送站内消息
            messageFeignServer.saveBatchMessage(messageDtoList);
        }

    }

    @XxlJob("inspectPlanChangeJobHandler")
    public void inspectPlanChangeJobHandler() {
        log.info("智慧巡检计划执行状态变更");
        Date newDate = new Date();
        // 状态变更为执行中
        changePlanExecuting(newDate);
        // 状态变更为已完成
        changePlanExecuted(newDate);
    }

    private void changePlanExecuted(Date newDate) {
        // 查询计划结束时间小于当前时间
        LambdaQueryWrapper<SaasParkFireInspectPlan> lambdaWrapper = Wrappers.lambdaQuery();
        lambdaWrapper.lt(SaasParkFireInspectPlan::getPlanEndDate, DateUtil.format(newDate, DateUtil.PATTERN_DATE));
        List<SaasParkFireInspectPlan> planList = planService.list(lambdaWrapper);
        if (CollUtil.isNotEmpty(planList)) {
            for (SaasParkFireInspectPlan planTask : planList) {
                planTask.setPlanState(PlanExecuteStateEnum.EXECUTED.getCode());
            }
            planService.updateBatchById(planList);
        }
    }

    private void changePlanExecuting(Date newDate) {
        // 查询执行中数据
        LambdaQueryWrapper<SaasParkFireInspectPlan> lambdaWrapper = Wrappers.lambdaQuery();
        lambdaWrapper.le(SaasParkFireInspectPlan::getPlanStartDate, DateUtil.format(newDate, DateUtil.PATTERN_DATE));
        lambdaWrapper.ge(SaasParkFireInspectPlan::getPlanEndDate, DateUtil.format(newDate, DateUtil.PATTERN_DATE));
        List<SaasParkFireInspectPlan> planList = planService.list(lambdaWrapper);
        if (CollUtil.isNotEmpty(planList)) {
            for (SaasParkFireInspectPlan planTask : planList) {
                planTask.setPlanState(PlanExecuteStateEnum.EXECUTING.getCode());
            }
            planService.updateBatchById(planList);
        }
    }

    @XxlJob("inspectPlanTaskChangeJobHandler")
    public void inspectPlanTaskChangeJobHandler() {
        log.info("智慧巡检任务执行状态变更");
        Date newDate = new Date();
        // 状态变更为执行中
        changeTaskExecuting(newDate);
        // 查询任务过期自动关闭
        changeTaskOut(newDate);
        // 查询任务执行状态为逾期未完成，逾期未巡检，
        changeTaskAutoClose(newDate);
    }

    private void changeTaskAutoClose(Date newDate) {
        LambdaQueryWrapper<SaasParkFireInspectPlanTask> lambdaWrapper = Wrappers.lambdaQuery();
        lambdaWrapper.notIn(SaasParkFireInspectPlanTask::getTaskState, TaskStateEnum.PROCESSED.getCode(), TaskStateEnum.ClOSE.getCode());
        lambdaWrapper.eq(SaasParkFireInspectPlanTask::getTaskAutoCloseDemand, "1");
        lambdaWrapper.lt(SaasParkFireInspectPlanTask::getTaskOutTime, newDate);
        // 查询任务过期自动关闭
        List<SaasParkFireInspectPlanTask> planTaskAutoCloseList = planTaskService.list(lambdaWrapper);
        if (CollUtil.isEmpty(planTaskAutoCloseList)) {
            return;
        }
        for (SaasParkFireInspectPlanTask planTask : planTaskAutoCloseList) {
            // 逾期自动关闭
            planTask.setTaskState(TaskStateEnum.ClOSE.getCode());
            planTask.setCloseType("2");
            planTask.setExecuteState(PlanExecuteStateEnum.ClOSE.getCode());

        }
        planTaskService.updateBatchById(planTaskAutoCloseList);
    }

    private void changeTaskOut(Date newDate) {
        LambdaQueryWrapper<SaasParkFireInspectPlanTask> lambdaWrapper = Wrappers.lambdaQuery();
        lambdaWrapper.notIn(SaasParkFireInspectPlanTask::getTaskState, TaskStateEnum.PROCESSED.getCode(), TaskStateEnum.ClOSE.getCode());
        lambdaWrapper.notIn(SaasParkFireInspectPlanTask::getExecuteState, PlanExecuteStateEnum.OUT_NO_COMPLETE.getCode(),PlanExecuteStateEnum.OUT_NO_INSPECT.getCode());
        lambdaWrapper.lt(SaasParkFireInspectPlanTask::getTaskOutTime, newDate);
        // 查询任务执行状态为逾期未完成，逾期未巡检，过期自动关闭
        List<SaasParkFireInspectPlanTask> planTaskOutList = planTaskService.list(lambdaWrapper);
        if (CollUtil.isEmpty(planTaskOutList)) {
            return;
        }
        for (SaasParkFireInspectPlanTask planTask : planTaskOutList) {
            if (planTask.getInspectedNum() > 0) {
                planTask.setExecuteState(PlanExecuteStateEnum.OUT_NO_COMPLETE.getCode());
            } else {
                planTask.setExecuteState(PlanExecuteStateEnum.OUT_NO_INSPECT.getCode());
            }

        }
        planTaskService.updateBatchById(planTaskOutList);
    }

    private void changeTaskExecuting(Date newDate) {
        LambdaQueryWrapper<SaasParkFireInspectPlanTask> lambdaWrapper = Wrappers.lambdaQuery();
        lambdaWrapper.notIn(SaasParkFireInspectPlanTask::getTaskState, TaskStateEnum.PROCESSED.getCode(), TaskStateEnum.ClOSE.getCode());
        lambdaWrapper.ne(SaasParkFireInspectPlanTask::getExecuteState, PlanExecuteStateEnum.EXECUTING.getCode());
        lambdaWrapper.le(SaasParkFireInspectPlanTask::getTaskStartTime, newDate);
        lambdaWrapper.ge(SaasParkFireInspectPlanTask::getTaskEndTime, newDate);
        // 查询任务执行状态为执行中
        List<SaasParkFireInspectPlanTask> planTaskList = planTaskService.list(lambdaWrapper);
        if (CollUtil.isEmpty(planTaskList)) {
            return;
        }
        for (SaasParkFireInspectPlanTask planTask : planTaskList) {
            planTask.setExecuteState(PlanExecuteStateEnum.EXECUTING.getCode());
        }
        planTaskService.updateBatchById(planTaskList);
    }
}
