package org.security.trans.taskCheck.device;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.security.common.Constant;
import org.security.common.eum.FrequencyEnum;
import org.security.common.util.TaskCehckUtil;
import org.security.system.user.vo.UserVO;
import org.security.ht.entity.basic.Device;
import org.security.trans.basic.service.IDepartmentService;
import org.security.trans.basic.service.IDeviceService;
import org.security.trans.dailyDuties.entity.DeviceInspection;
import org.security.trans.dailyDuties.service.IDeviceInspectionService;
import org.security.trans.dailyDuties.service.IInspectionService;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;

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

/**
 * @author zj 2022/4/26
 * 设备检查
 */
@Slf4j
@AllArgsConstructor
@Service
public class DeviceCheck {
	private static final int NUMS = 1000;
	private final IDepartmentService departmentService;
	private final IDeviceService deviceService;
	private final IDeviceInspectionService deviceInspectionService;
	private final IInspectionService iInspectionService;

	/**
	 * 分页查询需要生成检查任务的设备进行处理,
	 */
	public void handle() {
		log.info("=============设备定时任务开始处理=============");
		DateTime date = DateUtil.date();
		int cueernt = 0;
		Query query = new Query();
		query.setCurrent(cueernt);
		query.setSize(NUMS);
		IPage<Device> deviceIPage = deviceService.getCheckList(query);
		log.info("=============当前页码：[{}]，总页数：[{}]=============", cueernt, deviceIPage.getPages());
		List<Device> deviceList = Optional.ofNullable(deviceIPage.getRecords()).orElse(Collections.emptyList());
		deviceCheck(date, deviceList);
		if (deviceIPage.getPages() > 1) {
			while (cueernt < deviceIPage.getPages()) {
				query.setCurrent(++cueernt);
				IPage<Device> checkList = deviceService.getCheckList(query);
				log.info("=============当前页码：[{}]，总页数：[{}]=============", cueernt, deviceIPage.getPages());
				deviceCheck(date, checkList.getRecords());
			}
		}

	}

	private void deviceCheck(Date date, List<Device> deviceList) {
		ArrayList<DeviceInspection> list = new ArrayList<>();
		for (Device device : deviceList) {
			List<UserVO> userRole = iInspectionService.getUserByRoleId(device.getRoleId(), device.getDepId());
			FrequencyEnum frequency = FrequencyEnum.wrapper(device.getFrequency());
			//按天
			switch (frequency) {
				case BY_DAY:
					byDayCheck(date, device, userRole, list);
					break;
				case BY_WEEK:
					byWeekCheck(date, device, userRole, list);
					break;
				case BY_MONTH:
					byMonthCheck(date, device, userRole, list);
					break;
				case BY_QUARTER:
					byQuarterCheck(date, device, userRole, list);
					break;
				case BY_HALFYEAR:
					byHalfYearCehck(date, device, userRole, list);
					break;
				case BY_YEAR:
					byYearCheck(date, device, userRole, list);
					break;
				default:
					unknowCheck();
					break;
			}
		}
		if (!list.isEmpty()) {
			deviceInspectionService.saveBatch(list);
		}
	}

	private void byDayCheck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按天]开始处理=============");
		DateTime begin = DateUtil.beginOfDay(date);
		DateTime end = DateUtil.endOfDay(date);
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按天]处理结束=============");
	}

	private void byWeekCheck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按周]开始处理=============");
		DateTime begin = DateUtil.beginOfWeek(date);
		DateTime end = DateUtil.endOfWeek(date);
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按周]处理结束=============");
	}

	private void byMonthCheck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按月]开始处理=============");
		DateTime begin = DateUtil.beginOfMonth(date);
		DateTime end = DateUtil.endOfMonth(date);
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按月]处理结束=============");
	}

	private void byQuarterCheck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按季]开始处理=============");
		DateTime begin = DateUtil.beginOfQuarter(date);
		DateTime end = DateUtil.endOfMonth(date);
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按季]处理结束=============");
	}

	private void byHalfYearCehck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按半年]开始处理=============");
		Date begin = TaskCehckUtil.getHalfYearStart();
		Date end = TaskCehckUtil.getHalfYearEnd();
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按半年]处理结束=============");
	}

	private void byYearCheck(Date date, Device device, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		log.info("=============设备检查[按年]开始处理=============");
		DateTime begin = DateUtil.beginOfYear(date);
		DateTime end = DateUtil.endOfYear(date);
		checkDevice(device, begin, end, userRole, list);
		log.info("=============设备检查[按年]处理结束=============");
	}

	private void unknowCheck() {
		log.info("=============设备检查[未知]不做处理=============");
	}

	private void checkDevice(Device device, Date begin, Date end, List<UserVO> userRole, ArrayList<DeviceInspection> list) {
		DeviceInspection deviceIns = deviceInspectionService.getDeviceIns(device.getId(), begin, end);
		if (Func.isNotEmpty(deviceIns)) {
			log.info("===========已生成设备检查任务，不做处理=============");
			return;
		}
		DeviceInspection deviceInspection = new DeviceInspection();
		deviceInspection.setDeviceId(device.getId());
		deviceInspection.setDeviceName(device.getName());
		deviceInspection.setDeviceModelNum(device.getModelNum());
		deviceInspection.setCreateDeptId(device.getDepId());
		String ids = userRole.stream().map(vo -> String.valueOf(vo.getId())).collect(Collectors.joining(","));
		deviceInspection.setInspectUser(ids);
		deviceInspection.setStatus(Constant.DEVICE_STATE_INSPECTION);
		deviceInspection.setDeptId(device.getDepId());
		deviceInspection.setDeptName(departmentService.getById(deviceInspection.getDeptId()).getDeptName());
		deviceInspection.setCheckDeadline(end);
		list.add(deviceInspection);
	}
}
