package com.yeejoin.precontrol.common.listener.event.listener;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.precontrol.common.entity.*;
import com.yeejoin.precontrol.common.enums.MessageSubTypeEnum;
import com.yeejoin.precontrol.common.enums.MessageTypeEnum;
import com.yeejoin.precontrol.common.enums.TaskPersonTypeEnum;
import com.yeejoin.precontrol.common.enums.TaskTypeEnum;
import com.yeejoin.precontrol.common.listener.event.StatusEvent;
import com.yeejoin.precontrol.common.service.*;
import com.yeejoin.precontrol.common.utils.DateTools;
import com.yeejoin.precontrol.common.utils.DateUtils;
import com.yeejoin.precontrol.common.utils.PersonUtils;
import com.yeejoin.precontrol.common.utils.StringUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.*;

/**
 * @description: 状态服务专用监听器
 * @author: duanwei
 * @date: 2020-08-05 15:20
 **/
@Component
@Slf4j
public class StatusEventListener implements ApplicationListener<StatusEvent> {

	@Autowired
	ICompanyProjectJobStatusService iCompanyProjectJobStatusService;

	@Autowired
	ITaskPersonService iTaskPersonService;

	@Autowired
	ITaskService iTaskService;

	@Autowired
	ITaskPaycheckService iTaskPaycheckService;

	@Autowired
	IBadManagementPersonService iBadManagementPersonService;

	@Autowired
	IPersonMessageService iPersonMessageService;

	@Autowired
	IPersonAscriptionService iPersonAscriptionService;

	@Autowired
	IBadManagementService iBadManagementService;

	@Autowired
	PersonUtils personUtils;

	@SneakyThrows
	@Override
	public void onApplicationEvent(StatusEvent statusEvent) {
		JSONObject jsonObject = statusEvent.getMsg2();
		log.info("接收到状态更新消息,data:{}", jsonObject.toJSONString());
		String name = jsonObject.getString("name");
		switch (name) {
		case "task_job":
			log.info("接收到状态更新消息,更新表:rpm_company_project_job_status");
			popCompanyProjectJobStatus(jsonObject);
			break;
		case "read":
			log.info("接收到阅读状态更新消息");
			updateTaskRiskWithBuilderStatus(jsonObject);
			break;
		case "bad_person":
			log.info("接收到人员违章信息");
			updateTaskBadStatus(jsonObject);
			break;
		case "black_list":
			log.info("接收到人员黑名单信息");
			updatePersonBlackListStatus(jsonObject);
			break;
		default:
			break;
		}
	}

	/**
	 * 人员黑名单
	 *
	 * @param jsonObject
	 */
	private void updatePersonBlackListStatus(JSONObject jsonObject) {

		Person person = (Person) jsonObject.get("data");
		PersonAscription personAscription = iPersonAscriptionService
				.getOne(new LambdaQueryWrapper<PersonAscription>().eq(PersonAscription::getPersonId, person.getId()));
		List<Long> platformSecurityPerson = personUtils.getPlatformSecurityPerson();
		List<Long> projectSecurityPerson = personUtils.getProjectSecurityPerson(personAscription.getProjectId());
		if (StringUtil.isNotEmpty(platformSecurityPerson)) {
			for (Long personId : platformSecurityPerson) {
				savePersonBlackMessage(person, personAscription, personId);
			}
		}
		if (StringUtil.isNotEmpty(projectSecurityPerson)) {
			for (Long personId : projectSecurityPerson) {
				savePersonBlackMessage(person, personAscription, personId);
			}
		}
	}

	private void savePersonBlackMessage(Person person, PersonAscription personAscription, Long personId) {
		PersonMessage personMessage = new PersonMessage();
		personMessage.setPersonId(personId);
		personMessage.setType(MessageTypeEnum.PERSON.getType());
		if (personAscription != null) {
			personMessage.setProjectId(personAscription.getProjectId());
		}
		personMessage.setContent("个人黑名单告警");
		personMessage.setReadStatus(0);
		personMessage.setObjectId(person.getId());
		personMessage.setSubType(Long.valueOf(MessageSubTypeEnum.BLACK.getType()));
		iPersonMessageService.save(personMessage);
	}

	/**
	 * 违章人员产生，状态处理
	 *
	 * @param jsonObject
	 */
	private void updateTaskBadStatus(JSONObject jsonObject) throws ParseException {
		List<BadManagementPerson> badPersonList = (List<BadManagementPerson>) jsonObject.get("badPerson");
		Long projectId = (Long) jsonObject.get("projectId");
		BadManagementPerson badManagementPerson = new BadManagementPerson();
		if (StringUtil.isNotEmpty(badPersonList)) {
			badManagementPerson = badPersonList.get(0);
		} else {
			badManagementPerson.setProjectId(projectId);
		}

		List<Long> platformSecurityPerson = personUtils.getPlatformSecurityPerson();
		List<Long> projectSecurityPerson = personUtils.getProjectSecurityPerson(badManagementPerson.getProjectId());

		// 每个人违章
		for (BadManagementPerson badPerson : badPersonList) {
			List<String> thirtyDay = getDay(-30);
			List<BadManagementPerson> badPersonHistory = iBadManagementPersonService
					.list(new LambdaQueryWrapper<BadManagementPerson>()
							.eq(BadManagementPerson::getPersonId, badPerson.getPersonId())
							.eq(BadManagementPerson::getProjectId, badPerson.getProjectId())
							.between(BadManagementPerson::getCreateDate, thirtyDay.get(0), thirtyDay.get(1)));
			// 30天内项目违章两次
			if (StringUtil.isNotEmpty(badPersonHistory) && badPersonHistory.size() >= 2) {
				savePersonMessage(badPerson, projectSecurityPerson, MessageTypeEnum.PERSON.getType(),
						MessageSubTypeEnum.PROJECT.getType(), "个人违章告警", null, badPerson.getPersonId());
				savePersonMessage(badPerson, platformSecurityPerson, MessageTypeEnum.PERSON.getType(),
						MessageSubTypeEnum.PROJECT.getType(), "个人违章告警", null, badPerson.getPersonId());
			}
		}

		List<String> sevenDay = getDay(-7);
		// 7天内分包商违章6次
		List<BadManagementPerson> badPersonAllHistory = iBadManagementPersonService
				.list(new LambdaQueryWrapper<BadManagementPerson>()
						.eq(BadManagementPerson::getCompanyId, badManagementPerson.getCompanyId())
						.between(BadManagementPerson::getCreateDate, sevenDay.get(0), sevenDay.get(1))
						.groupBy(BadManagementPerson::getPersonId));
		if (StringUtil.isNotEmpty(badPersonAllHistory) && badPersonAllHistory.size() >= 6) {
			savePersonMessage(badManagementPerson, projectSecurityPerson, MessageTypeEnum.COMPANY.getType(),
					MessageSubTypeEnum.COMPANY.getType(), "分包商风险预警", null, badManagementPerson.getCompanyId());
			savePersonMessage(badManagementPerson, platformSecurityPerson, MessageTypeEnum.COMPANY.getType(),
					MessageSubTypeEnum.COMPANY.getType(), "分包商风险预警", null, badManagementPerson.getCompanyId());
		}

		// 一个任务三人以上违章 形成群体违章
		if (badPersonList != null && badPersonList.size() >= 3) {
			// 目前如果是多个分包商的人混合在一起 难以判断 目前认为所有人都来自一个分包商 直接取第一个
			savePersonMessage(badManagementPerson, projectSecurityPerson, MessageTypeEnum.COMPANY.getType(),
					MessageSubTypeEnum.MANY_PERSON.getType(), "分包商风险预警", badManagementPerson.getTaskId(),
					badManagementPerson.getCompanyId());
			savePersonMessage(badManagementPerson, platformSecurityPerson, MessageTypeEnum.COMPANY.getType(),
					MessageSubTypeEnum.MANY_PERSON.getType(), "分包商风险预警", badManagementPerson.getTaskId(),
					badManagementPerson.getCompanyId());
		}

	}

	private void savePersonMessage(BadManagementPerson badPerson, List<Long> personIds, int type, int subType,
			String content, Long taskId, Long objectId) {

		if (StringUtil.isNotEmpty(personIds)) {
			for (Long personId : personIds) {
				PersonMessage personMessage = new PersonMessage();
				personMessage.setPersonId(personId);
				personMessage.setType(type);
				personMessage.setSubType(Long.valueOf(subType));
				personMessage.setProjectId(badPerson.getProjectId());
				personMessage.setTaskId(taskId);
				personMessage.setContent(content);
				personMessage.setReadStatus(0);
				personMessage.setObjectId(objectId);
				iPersonMessageService.save(personMessage);
			}
		}
	}

	private List<String> getDay(int i) throws ParseException {
		Calendar calendar = new GregorianCalendar();
		LinkedList<String> day = new LinkedList<>();
		Date e = new Date();
		calendar.setTime(e);
		calendar.add(Calendar.DAY_OF_MONTH, i);
		Date s = calendar.getTime();
		String start = DateUtils.dateFormat(s, "yyyy-MM-dd 00:00:00");
		String end = DateUtils.dateFormat(e, "yyyy-MM-dd 23:59:59");
		day.add(start);
		day.add(end);
		return day;
	}

	/**
	 * 填充交底任务的企业和项目
	 *
	 * @param jsonObject
	 */
	private void popCompanyProjectJobStatus(JSONObject jsonObject) {
		String taskId = jsonObject.getString("taskId");
		String day = DateTools.getPastDate(0);
		String start = day + " 00:00:00";
		String end = day + " 23:59:59";
		String projectId = jsonObject.getString("projectId");
		String companyId = jsonObject.getString("companyId");
		if (StringUtils.isNotEmpty(companyId) && StringUtils.isNotEmpty(projectId)) {
			CompanyProjectJobStatus companyProjectJobStatus = iCompanyProjectJobStatusService
					.getOne(new LambdaQueryWrapper<CompanyProjectJobStatus>()
							.eq(CompanyProjectJobStatus::getCompanyId, companyId)
							.eq(CompanyProjectJobStatus::getProjectId, projectId)
							.between(CompanyProjectJobStatus::getCreateDate, start, end));
			if (companyProjectJobStatus == null) {
				companyProjectJobStatus = new CompanyProjectJobStatus();
				companyProjectJobStatus.setProjectId(Long.valueOf(projectId));
				companyProjectJobStatus.setCompanyId(Long.valueOf(companyId));
				companyProjectJobStatus.setStatus(true);
				companyProjectJobStatus.setTaskId(Long.valueOf(taskId));
				iCompanyProjectJobStatusService.save(companyProjectJobStatus);
			}
		} else {
			log.info("填充交底任务监听事件：项目id或者企业id为空");
		}
	}

	/**
	 * 更新三交三查任务中的风险状态与施工人员确认状态
	 *
	 * @param jsonObject
	 */
	private void updateTaskRiskWithBuilderStatus(JSONObject jsonObject) {
		String taskId = jsonObject.getString("taskId");
		Task task = iTaskService.getById(taskId);
		// 属于三交三查
		if (task.getType().equals(TaskTypeEnum.TASKPAYCHECK.getValue())) {
			TaskPaycheck taskPaycheck = iTaskPaycheckService
					.getOne(new LambdaQueryWrapper<TaskPaycheck>().eq(TaskPaycheck::getTaskId, taskId));
			if (taskPaycheck != null) {
				// 查找非施工的人 如果查到有未阅读的 待办风险状态没完成
				List<TaskPerson> list = iTaskPersonService
						.list(new LambdaQueryWrapper<TaskPerson>().eq(TaskPerson::getTaskId, taskId)
								.notIn(TaskPerson::getType, TaskPersonTypeEnum.BUILDER.getValue())
								.eq(TaskPerson::getReadStatus, 0L));
				if (StringUtil.isEmpty(list)) {
					task.setRiskStatus(1L);
				} else {
					task.setRiskStatus(0L);
				}
				// 施工人员阅读完成则状态完成
				List<TaskPerson> builderList = iTaskPersonService
						.list(new LambdaQueryWrapper<TaskPerson>().eq(TaskPerson::getTaskId, taskId)
								.eq(TaskPerson::getType, TaskPersonTypeEnum.BUILDER.getValue())
								.eq(TaskPerson::getReadStatus, 0L));
				if (StringUtil.isEmpty(builderList)) {
					task.setBuilderStatus(1L);
				} else {
					task.setBuilderStatus(0L);
				}
				iTaskService.updateById(task);
			}
		}

	}

}
