package org.security.trans.taskCheck.task.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.security.common.Constant;

import org.security.system.user.vo.UserVO;
import org.security.trans.basic.service.IDepartmentService;
import org.security.trans.dailyDuties.entity.Inspection;
import org.security.trans.dailyDuties.service.IInspectionService;
import org.security.trans.prevent.entity.PreventMaterial;
import org.security.trans.prevent.service.IPreventMaterialService;
import org.security.trans.task.entity.Task;
import org.security.trans.task.entity.TaskHandin;
import org.security.trans.task.service.ITaskHandinService;
import org.security.trans.taskCheck.task.dto.TaskHandinCheckDTO;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;

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

/**
 * @author zj 2022/4/11
 */
@Slf4j
@AllArgsConstructor
@Service
public class BaseTaskCheck {
	private final ITaskHandinService taskHandinService;
	private final IInspectionService iInspectionService;
	private final IPreventMaterialService preventMaterialService;
	private final IDepartmentService departmentService;

	public void handle(Task task, Date begin, Date end) {
		if (Func.isNotEmpty(task.getBeginDate()) && DateUtil.date().before(task.getBeginDate())) {
			log.info("=============任务开始时间: {}=============", task.getBeginDate());
			log.info("=============任务未开始，不做处理=============");
			return;
		}
		if (Func.isNotEmpty(task.getEndDate()) && DateUtil.date().after(task.getEndDate())) {
			log.info("=============任务结束时间: {}=============", task.getEndDate());
			log.info("=============任务已经结束，不做处理=============");
			return;
		}
		//获取任务接收的部门id
		Long[] deptIds = Func.toLongArray(task.getDeptIds());
		ArrayList<TaskHandin> taskHandins = new ArrayList<>();
		ArrayList<Inspection> inspections = new ArrayList<>();
		List<PreventMaterial> materialList = new ArrayList<>();
		//业务类型code
		String taskBusinessType = task.getBusinessType();
		String module = task.getModule();
		DateTime creatTime = DateUtil.date();
		for (Long deptId : deptIds) {
			//获取任务接收机构相关角色的用户信息
			List<UserVO> userList = iInspectionService.getUserByRoleId(task.getRoleId(), String.valueOf(deptId));
			String userIds = null;
			if (Func.isNotEmpty(userList)) {
				userIds = userList.stream().map(vo -> String.valueOf(vo.getId())).collect(Collectors.joining(","));
			}
			//检查整改
			if ("daily".equals(module)) {
				Inspection inspection = iInspectionService.getCheckInspection(task.getId(), String.valueOf(deptId), begin, end);
				if (Func.isNotEmpty(inspection)) {
					log.info("=============检查整改任务已生成，不做处理=============");
					continue;
				}
				//创建检查整改任务
				setInspectionData(task, end, inspections, creatTime, deptId, userIds);
			}
			//教育培训或应急演练
			if ("drill".equals(module) || "edu".equals(module)) {
				//教育培训或应急演练任务请求条件构造
				TaskHandin taskHandin = setEduOrDrillDataConditon(task, begin, end, deptId);
				if (Func.isNotEmpty(taskHandin)) {
					if ("drill".equals(taskHandin.getModule())){
						log.info("=============应急演练任务已生成，不做处理=============");
					}else {
						log.info("=============教育培训任务已生成，不做处理=============");
					}
					continue;
				}
				//封装教育培训和应急演练任务信息
				setTaskHandInData(task, end, taskHandins, taskBusinessType, creatTime, deptId, userIds);
			}
			//案件防控
			if ("prevent".equals(module)) {
				PreventMaterial preventMaterial = preventMaterialService.getPreventMaterialDatas(task.getId(), String.valueOf(deptId), begin, end);
				if (Func.isNotEmpty(preventMaterial)) {
					log.info("=============案件防控任务已生成，不做处理=============");
					continue;
				}
				//封装案件防控任务信息
				setPreventMaterialData(task, end, materialList, creatTime, deptId, userIds);
			}
		}
		if (!taskHandins.isEmpty()) {

			taskHandinService.saveBatch(taskHandins);
		}
		if (!inspections.isEmpty()) {
			iInspectionService.saveBatch(inspections);
		}
		if (Func.isNotEmpty(materialList)){
			preventMaterialService.saveBatch(materialList);
		}
	}

	private void setPreventMaterialData(Task task, Date end, List<PreventMaterial> materialList, DateTime creatTime, Long deptId, String userIds) {
		PreventMaterial material = new PreventMaterial();
		material.setTaskId(task.getId());
		material.setType(task.getBusinessType());
		material.setCreatedTime(creatTime);
		material.setDeptId(String.valueOf(deptId));
		material.setDeadline(end);
		material.setRoleId(task.getRoleId());
		material.setUserId(userIds);
		material.setDeptName(departmentService.getById(material.getDeptId()).getDeptName());
		material.setStatus("0");
		materialList.add(material);
	}

	/**
	 * 封装教育培训和应急演练任务信息
	 */
	private void setTaskHandInData(Task task, Date end, ArrayList<TaskHandin> taskHandins, String taskBusinessType, DateTime creatTime, Long deptId, String userIds) {
		TaskHandin handin = new TaskHandin();
		handin.setTaskId(task.getId());
		handin.setFlag(task.getFlag());
		handin.setModule(task.getModule());
		handin.setBusinessType(taskBusinessType);
		handin.setStatus(Constant.HANDIN_STATE_DRAFT);
		handin.setDeadline(end);
		handin.setDeptId(String.valueOf(deptId));
		handin.setDeptName(taskHandinService.getDeptName(String.valueOf(deptId)));
		handin.setCreatedTime(creatTime);
		handin.setUserId(userIds);
		handin.setRoleId(task.getRoleId());
		taskHandins.add(handin);
	}

	/**
	 * 教育培训或应急演练任务请求条件构造
	 */
	private TaskHandin setEduOrDrillDataConditon(Task task, Date begin, Date end, Long deptId) {
		TaskHandinCheckDTO checkDTO = TaskHandinCheckDTO.builder()
			.taskId(task.getId())
			.status(Constant.HANDIN_STATE_DRAFT)
			.deptId(String.valueOf(deptId))
			.creatStartDate(begin)
			.creatEndDate(end)
			.build();
		return taskHandinService.getTaskHandin(checkDTO);
	}

	/**
	 * 创建检查整改任务
	 */
	private void setInspectionData(Task task, Date end, ArrayList<Inspection> inspections, DateTime creatTime, Long deptId, String userIds) {
		Inspection ins = new Inspection();
		ins.setUserId(userIds);
		ins.setType(task.getFlag());
		ins.setCheckType(task.getCheckType());
		ins.setRoleId(task.getRoleId());
		ins.setTaskId(task.getId());
		ins.setInspectDep(Constant.INSPECTION_TYPE_SELF.equals(task.getCheckType()) ? String.valueOf(deptId) : task.getInspectDep());
		ins.setInspectedDep(String.valueOf(deptId));
		ins.setDeadline(end);
		ins.setDeptId(Constant.INSPECTION_TYPE_SELF.equals(task.getCheckType()) ? String.valueOf(deptId) : task.getInspectDep());
		ins.setDeptName(departmentService.getById(ins.getId()).getDeptName());
		ins.setModule(task.getModule());
		ins.setBusinessType(task.getBusinessType());
		ins.setCreatedTime(creatTime);
		inspections.add(ins);
	}
}
