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

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ctc.wstx.util.StringUtil;
import com.google.common.collect.Lists;
import com.yeejoin.precontrol.common.entity.PersonAscription;
import com.yeejoin.precontrol.common.entity.Project;
import com.yeejoin.precontrol.common.enums.MessageAttributeEnum;
import com.yeejoin.precontrol.common.enums.MessageSubTypeEnum;
import com.yeejoin.precontrol.common.enums.MessageTypeEnum;
import com.yeejoin.precontrol.common.publish.MessageEventPublish;
import com.yeejoin.precontrol.common.service.IPersonAscriptionService;
import com.yeejoin.precontrol.common.service.IProjectService;
import com.yeejoin.precontrol.common.service.IStatisticsService;

import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.typroject.tyboot.component.emq.EmqxListener;
import org.typroject.tyboot.core.foundation.context.RequestContext;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.precontrol.common.constant.Constant;
import com.yeejoin.precontrol.common.entity.MessageException;
import com.yeejoin.precontrol.common.entity.Person;
import com.yeejoin.precontrol.common.entity.PersonCondition;
import com.yeejoin.precontrol.common.entity.PersonExam;
import com.yeejoin.precontrol.common.entity.PersonExamRecord;
import com.yeejoin.precontrol.common.entity.TaskPerson;
import com.yeejoin.precontrol.common.enums.OfflineExamEnum;
import com.yeejoin.precontrol.common.enums.QualifiedStageEnum;
import com.yeejoin.precontrol.common.exception.BaseException;
import com.yeejoin.precontrol.common.service.ICompanyService;
import com.yeejoin.precontrol.common.service.IMessageExceptionService;
import com.yeejoin.precontrol.common.service.IPersonConditionService;
import com.yeejoin.precontrol.common.service.IPersonExamRecordService;
import com.yeejoin.precontrol.common.service.IPersonExamService;
import com.yeejoin.precontrol.common.service.IPersonService;
import com.yeejoin.precontrol.common.service.ITaskPersonService;
import com.yeejoin.precontrol.common.service.ITaskRiskControlService;
import com.yeejoin.precontrol.common.vo.TaskRiskControlVo;

import lombok.extern.slf4j.Slf4j;

import java.util.List;

/**
 * @Description: mqtt监听服务
 * @Author: duanwei
 * @Date: 2020/9/15
 */
@Component
@Slf4j
public class ExamMqTtlListener extends EmqxListener {

	@Autowired
	ICompanyService iCompanyService;

	@Autowired
	IPersonService iPersonService;

	@Autowired
	IPersonConditionService iPersonConditionService;

	@Autowired
	IMessageExceptionService iMessageExceptionService;

	@Autowired
	IPersonExamService iPersonExamService;

	@Autowired
	ITaskPersonService iTaskPersonService;

	@Autowired
	ITaskRiskControlService iTaskRiskControlService;

	@Autowired
	IPersonExamRecordService iPersonExamRecordService;

	@Autowired
	IPersonAscriptionService personAscriptionService;

	@Autowired
	IProjectService projectService;

	@Autowired
	MessageEventPublish messageEventPublish;

	@Autowired
	IStatisticsService statisticsService;

//	/**
//	 * 产品号
//	 */
//	@Value("${admin.product.web}")
//	String product;
//	/**
//	 * 产品密钥
//	 */
//	@Value("${admin.appkey}")
//	String appkey;

	@Override
	public void processMessage(String topic, MqttMessage message) {
		JSONObject jsonObject = null;
		try {
			jsonObject = JSONObject.parseObject(message.toString());
			String userId = jsonObject.getString("userId");
			String score = jsonObject.getString("score");
			String type = jsonObject.getString("type");
			String token = jsonObject.getString("token");
			String product = jsonObject.getString("product");
			String appkey = jsonObject.getString("appKey");
			String evaluateResult = jsonObject.getString("evaluateResult");
			String examId = jsonObject.getString("examId");
			String examTemplateId = jsonObject.getString("templateId");
			String industryKey = jsonObject.getString("industryKey");
			String templateName = jsonObject.getString("templateName");
			Person person = iPersonService.getOne(new LambdaQueryWrapper<Person>().eq(Person::getUserId, userId));
			if (person == null) {
				throw new BaseException("用户不存在！");
			}
			// person.setExamineScore(Double.valueOf(score).longValue());
			// iPersonService.updateById(person);\
			PersonExam exam = new PersonExam();
			exam.setPersonId(person.getId());
			exam.setScore(Double.valueOf(score).intValue());
			RequestContext.setToken(token);
			RequestContext.setProduct(product);
			RequestContext.setAppKey(appkey);
			if (templateName != null) {
				exam.setType(templateName);
			} else {
				exam.setType(
						Systemctl.dictionarieClient.value(Constant.EXAM_TYPE, type).getResult().getDictDataValue());
			}
			Boolean qualified = !"4".equals(evaluateResult);
			exam.setExamTemplateId(examTemplateId);
			exam.setExamSubjectType(industryKey);
			exam.setQualified(qualified);
			iPersonExamService.save(exam);

			// 更新考试记录
			PersonExamRecord personExamRecord = new PersonExamRecord();
			personExamRecord.setQualified(qualified ? 1 : 0);
			personExamRecord.setScore(new Double(score).intValue());
			iPersonExamRecordService.update(personExamRecord, new LambdaQueryWrapper<PersonExamRecord>()
					.eq(PersonExamRecord::getUserId, userId).eq(PersonExamRecord::getExamId, examId));

			Long oldColor = person.getColor();
			// 修改人员主表通过
			if (OfflineExamEnum.THREE_SEC.getType().equals(industryKey)) {
				person.setQualifiedStage(QualifiedStageEnum.THREE_LEVEL_QULIFIED.getValue());
				person.setQualified(qualified);
				person.setExamineScore(Long.valueOf(Float.valueOf(score).longValue()));
				// 如果三级安全考试不合格 设置红码
				if (!qualified) {
					person.setColor(0L);
				} else {
					person.setColor(2L);
				}
			}
			iPersonService.updateById(person);

			// 更新推送
			if (oldColor != person.getColor()) {
				statisticsService.initWs(person.getOrgCode(), Constant.WS_REDORGREENCODE);
			}

//			TaskPerson taskperson = iTaskPersonService.getOne(new LambdaQueryWrapper<TaskPerson>()
//					.eq(TaskPerson::getExamId, examId).eq(TaskPerson::getPersonId, person.getId()));
			List<TaskPerson> taskpersonList =iTaskPersonService.list(new LambdaQueryWrapper<TaskPerson>()
					.eq(TaskPerson::getExamId, examId).eq(TaskPerson::getPersonId, person.getId()));
			if (!com.yeejoin.precontrol.common.utils.StringUtil.isEmpty(taskpersonList)) {
				for(TaskPerson taskperson:taskpersonList) 
				{
					TaskRiskControlVo taskRiskControlVo = new TaskRiskControlVo();
					taskRiskControlVo.setTaskPersonId(taskperson.getId());
					iTaskRiskControlService.doExam(taskRiskControlVo, qualified);
				}
			}

			PersonCondition personCondition = iPersonConditionService.getOne(new LambdaQueryWrapper<PersonCondition>()
					.eq(PersonCondition::getPersonId, person.getId()).eq(PersonCondition::getExamId, examId));
			log.info("考试系统同步注册考试id:{}", examId);
			log.info("考试系统同步注册考试信息:{}", JSON.toJSON(personCondition));
			if (personCondition != null) {
				personCondition.setExamStatus(qualified ? 1 : 0);
				iPersonConditionService.updateById(personCondition);
			}

			// 消息通知--考试结果
			examResultNotice(person, qualified, industryKey, examId);
		} catch (Exception e) {
			log.info("考试系统同步消息失败:{}", e.getMessage());
			e.printStackTrace();
			MessageException messageException = new MessageException();
			messageException.setJson(jsonObject.toJSONString());
			messageException.setMessage(e.getMessage());
			iMessageExceptionService.save(messageException);
		}
		log.info("考试系统推送消息同步完成");
	}

	/**
	 * 考试结果通知
	 *
	 * @param person      考试人员
	 * @param qualified   是否通过
	 * @param industryKey 考试类型
	 * @param examId      考试id
	 */
	private void examResultNotice(Person person, Boolean qualified, String industryKey, String examId) {
		MessageTypeEnum typeEnum;
		MessageSubTypeEnum subTypeEnum;
		if (OfflineExamEnum.THREE_SEC.getType().equals(industryKey)) {
			typeEnum = MessageTypeEnum.THREE_LEVEL_EXAM;
			// 三级安全考试结果
			if (qualified) {
				// 考试通过
				subTypeEnum = MessageSubTypeEnum.THREE_LEVEL_EXAM_PASSED;
			} else {
				subTypeEnum = MessageSubTypeEnum.THREE_LEVEL_EXAM_FAILURE;
			}
		} else {
			typeEnum = MessageTypeEnum.SPECIAL_EXAM;
			// 专项考试结果
			if (qualified) {
				// 考试通过
				subTypeEnum = MessageSubTypeEnum.SPECIAL_EXAM_PASSED;
			} else {
				subTypeEnum = MessageSubTypeEnum.SPECIAL_EXAM_FAILURE;
			}
		}

		// 获取项目部所有人
		QueryWrapper<PersonAscription> queryWrapper = new QueryWrapper<>();
		queryWrapper.lambda().eq(PersonAscription::getPersonId, person.getId());
		PersonAscription personAscription = personAscriptionService.getOne(queryWrapper); // 查询归属信息
		QueryWrapper<Project> projectQueryWrapper = new QueryWrapper<>();
		projectQueryWrapper.lambda().eq(Project::getId, personAscription.getProjectId());
		Project project = projectService.getOne(projectQueryWrapper); // 查询项目信息
		if (project == null) {
			return;
		}
		QueryWrapper<Person> personQueryWrapper = new QueryWrapper<>();
		personQueryWrapper.lambda().eq(Person::getIsJxdj, 1).like(Person::getOrgCode, project.getOrgCode());
		List<Person> personList = iPersonService.list(personQueryWrapper); // 根据项目orgCode查询项目下所有人

		if (!CollectionUtils.isEmpty(personList)) {
			JSONArray array = new JSONArray();
			personList.forEach(p -> {
				JSONObject jsonObject = new JSONObject();
				jsonObject.put(MessageAttributeEnum.MSG_TYPE.getName(), typeEnum.getType());
				jsonObject.put(MessageAttributeEnum.MSG_SUB_TYPE.getName(), subTypeEnum.getType());
				jsonObject.put(MessageAttributeEnum.PERSON_ID.getName(), p.getId());
				jsonObject.put(MessageAttributeEnum.CONTENT.getName(), person.getName());
				jsonObject.put(MessageAttributeEnum.TASK_ID.getName(), Long.valueOf(examId));
				jsonObject.put(MessageAttributeEnum.PARAM.getName(), person.getUserId());

				array.add(jsonObject);
			});

			JSONObject data = new JSONObject();
			data.put("param", array);
			messageEventPublish.publish(data);
		}
	}
}
