/*
 *    Copyright (c) 2018-2025, hnqz All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: hnqz
 */
package com.qunzhixinxi.hnqz.admin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qunzhixinxi.hnqz.admin.api.vo.UserVO;
import com.qunzhixinxi.hnqz.admin.entity.WmDaHospital;
import com.qunzhixinxi.hnqz.admin.entity.WmScorePackage;
import com.qunzhixinxi.hnqz.admin.entity.WmScorePackageStatus;
import com.qunzhixinxi.hnqz.admin.entity.WmTask;
import com.qunzhixinxi.hnqz.admin.entity.WmTaskContent;
import com.qunzhixinxi.hnqz.admin.entity.WmTaskType;
import com.qunzhixinxi.hnqz.admin.entity.WmUserSign;
import com.qunzhixinxi.hnqz.admin.enums.DelEnum;
import com.qunzhixinxi.hnqz.admin.mapper.WmDaHospitalMapper;
import com.qunzhixinxi.hnqz.admin.mapper.WmTaskContentMapper;
import com.qunzhixinxi.hnqz.admin.mapper.WmUserSignMapper;
import com.qunzhixinxi.hnqz.admin.service.SysPublicParamService;
import com.qunzhixinxi.hnqz.admin.service.SysUserService;
import com.qunzhixinxi.hnqz.admin.service.WmScorePackageService;
import com.qunzhixinxi.hnqz.admin.service.WmScorePackageStatusService;
import com.qunzhixinxi.hnqz.admin.service.WmTaskContentService;
import com.qunzhixinxi.hnqz.admin.service.WmTaskService;
import com.qunzhixinxi.hnqz.admin.service.WmTaskTypeService;
import com.qunzhixinxi.hnqz.admin.util.HnqzUtils;
import com.qunzhixinxi.hnqz.common.core.util.R;
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 任务内容表
 *
 * @author gaoyanng
 * @date 2020-06-25 23:35:25
 */
@Slf4j
@Service
@AllArgsConstructor
public class WmTaskContentServiceImpl extends ServiceImpl<WmTaskContentMapper, WmTaskContent> implements WmTaskContentService {
	private final WmTaskService wmTaskService;
	private final SysUserService sysUserService;
	private final WmTaskTypeService wmTaskTypeService;
	private final WmScorePackageService wmScorePackageService;
	private final WmScorePackageStatusService wmScorePackageStatusService;
	private final WmUserSignMapper wmUserSignMapper;
	private final WmDaHospitalMapper wmDaHospitalMapper;
	private final SysPublicParamService sysPublicParamService;

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R<?> saveTaskContent(WmTaskContent wmTaskContent) {
		if (StringUtils.isEmpty(wmTaskContent.getTemp30())) {
			return R.failed("任务类型不能为空");
		}

		if (StringUtils.isEmpty(wmTaskContent.getTemp32())) {
			return R.failed("关联积分包不能为空");
		}
		WmScorePackage tWmScorePackage = wmScorePackageService.getById(wmTaskContent.getTemp32());
		if (null == tWmScorePackage) {
			log.warn("获取不到积分包：{}", wmTaskContent.getId());
			return R.failed("获取不到积分包");
		}
		UserVO sysU = sysUserService.selectUserVoById(SecurityUtils.getUser().getId());
		WmScorePackageStatus query = new WmScorePackageStatus();
		query.setUserId(sysU.getUserId() + "");
		query.setStatus("2");
		query.setTaskAddFlag("1");
		query.setPackageId(tWmScorePackage.getId());
		List<WmScorePackageStatus> statusList = wmScorePackageStatusService.list(Wrappers.lambdaQuery(query));
		if (CollectionUtils.isEmpty(statusList)) {
			log.warn("获取积分包异常，任务保存失败9001：{}", tWmScorePackage.getId());
			return R.failed("获取积分包异常，任务保存失败");
		}
		if (statusList.size() != 1) {
			log.warn("获取积分包异常，任务保存失败9002：{}", tWmScorePackage.getId());
			return R.failed("获取积分包异常，任务保存失败");
		}
		/**
		 * 检验分值 5W
		 */

		if ("1".equals(tWmScorePackage.getPackageType1())) {

			Boolean fullFlag = wmTaskService.checkUserTaskSubScore(sysU.getUserId() + "");
			if (fullFlag) {
				String value = sysPublicParamService.getSysPublicParamKeyToValue("USER_TASK_SUB_SCORE");
				String info = StringUtils.isEmpty(value) ? "每日最多提交3万积分" : "每日最多提交" + Integer.parseInt(value) + "积分";
				log.warn("系统当前限制积分上限：【{}】，提示：【{}】", value, info);
				return R.failed(1, info);
			}
		}

		WmScorePackageStatus scorePackageStatus = statusList.get(0);
		if ("1".equals(wmTaskContent.getTemp30())) {
			// 会议举办
			// 限制每天两次
			LocalDate currentLookintoDate =
					LocalDate.parse(wmTaskContent.getTemp4(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
			LocalDateTime start = LocalDateTime.of(currentLookintoDate,LocalTime.MIN);
			LocalDateTime end = LocalDateTime.of(currentLookintoDate,LocalTime.MAX);
			long meetingTaskCount = wmTaskService.countMeetingTask(CollectionUtil.toList("1", "2", "3", "4"),
							String.valueOf(sysU.getUserId()), start, end);
			log.info("会议举办次数：{}", meetingTaskCount);
			if (meetingTaskCount >= 2L) {
				return R.failed(1, "每天最多举办两场会议");
			}

			//会议类型
			String date = wmTaskContent.getTemp4();
			Date date1 = DateUtil.parse(date);
			Date date2 = new Date();
			if (date1.after(date2)) {
				return R.failed(1, "会议时间不能选择之后的时间");
			}
			long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
			if (betweenDay >= 30L) {
				return R.failed(1, "30天以前的任务无法提交");
			}
			wmTaskContent.setTemp30(wmTaskContent.getTemp3());
		} else if ("19".equals(wmTaskContent.getTemp30())) {
			// 一对一专访
			// 限制每天两次
			LocalDate currentLookintoDate =
					LocalDate.parse(wmTaskContent.getTemp4(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
			LocalDateTime start = LocalDateTime.of(currentLookintoDate,LocalTime.MIN);
			LocalDateTime end = LocalDateTime.of(currentLookintoDate,LocalTime.MAX);
			long meetingTaskCount = wmTaskService.countMeetingTask(CollectionUtil.toList("19"),
					String.valueOf(sysU.getUserId()), start, end);
			log.info("一对一专访次数：{}", meetingTaskCount);
			if (meetingTaskCount >= 2L) {
				return R.failed(1, "每天最多举办两场一对一专访");
			}

			//会议类型
			String date = wmTaskContent.getTemp4();
			Date date1 = DateUtil.parse(date);
			Date date2 = new Date();
			if (date1.after(date2)) {
				return R.failed(1, "专访时间不能选择之后的时间");
			}
			long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
			if (betweenDay >= 30L) {
				return R.failed(1, "30天以前的任务无法提交");
			}
			wmTaskContent.setTemp30(wmTaskContent.getTemp3());
		}

		if ("21".equals(wmTaskContent.getTemp30()) || "12".equals(wmTaskContent.getTemp30())
				|| "13".equals(wmTaskContent.getTemp30()) || "14".equals(wmTaskContent.getTemp30()) || "17".equals(wmTaskContent.getTemp30())) {
			//会议类型
			String date = wmTaskContent.getTemp4();
			Date date1 = DateUtil.parse(date);
			Date date2 = new Date();
			if (date1.after(date2)) {
				return R.failed(1, "任务时间不能选择之后的时间");
			}
			long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
			if (betweenDay >= 30L) {
				return R.failed(1, "30天以前的任务无法提交");
			}

			if ("14".equals(wmTaskContent.getTemp30())){
				// 设置调查对象和调查品种
				wmTaskContent.setTemp24(wmTaskContent.getTemp24label());
				wmTaskContent.setTemp26(wmTaskContent.getTemp26label());
			}
		}

		if ("15".equals(wmTaskContent.getTemp30()) || "16".equals(wmTaskContent.getTemp30())) {
			if ("15".equals(wmTaskContent.getTemp30())) {
				WmDaHospital wmDaHospital = new WmDaHospital();
				wmDaHospital.setYymc(wmTaskContent.getTemp3());
				int num = wmDaHospitalMapper.selectCount(Wrappers.query(wmDaHospital));
				if (num != 0) {
					wmTaskContent.setTemp30("30");
				}
			}
			//会议类型
			String date = wmTaskContent.getTemp2();
			Date date1 = DateUtil.parse(date);
			Date date2 = new Date();
			if (date1.after(date2)) {
				return R.failed(1, "任务时间不能选择之后的时间");
			}
			long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
			if (betweenDay >= 30L) {
				return R.failed(1, "30天以前的任务无法提交");
			}
		}

		if ("18".equals(wmTaskContent.getTemp30())) {
			//会议类型
			String date = wmTaskContent.getTemp6();
			Date date1 = DateUtil.parse(date);
			Date date2 = new Date();
			if (date1.after(date2)) {
				return R.failed(1, "任务时间不能选择之后的时间");
			}
			long betweenDay = DateUtil.between(date1, date2, DateUnit.DAY);
			if (betweenDay >= 30L) {
				return R.failed(1, "30天以前的任务无法提交");
			}
		}

		if ("29".equals(wmTaskContent.getTemp30())) {
			if ("1".equals(wmTaskContent.getTemp29())) {
				wmTaskContent.setTemp30("5");
			} else {
				wmTaskContent.setTemp30("6");
			}
		}

		// 医院信息收集、医院信息修改两类任务做的任务总积分不得大于积分包值的60%（积分包值小于5000不做限制）
		if ("15".equals(wmTaskContent.getTemp30()) || "30".equals(wmTaskContent.getTemp30())) {
			if (tWmScorePackage.getScore() > 5000) {
				List<WmTask> wmTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery()
						.eq(WmTask::getRealFlag, "0")
						.eq(WmTask::getDelFlag, DelEnum.NOT_DEL.val())
						.in(WmTask::getScorePackageId, tWmScorePackage.getId())
						.in(WmTask::getTaskTypeId, "15", "30")
						.ne(WmTask::getTaskStatus, "4"));
				if (CollectionUtil.isNotEmpty(wmTaskList)) {
					int totalScore = tWmScorePackage.getScore();
					int partScore = wmTaskList.stream().mapToInt(WmTask::getScore).sum();
					if (partScore * 1.0 / totalScore > 0.6) {
						return R.failed("医院信息收集、医院信息修改两类任务总积分不得大于积分包值的60%");
					}
				}
			}
		}

		// 校验医院信息修改的任务（同一家医院，同一个人一个月只能修改一次，该医院一个月最多可修改3次）
		if ("30".equals(wmTaskContent.getTemp30())) {
			List<WmTask> taskList = wmTaskService.listCurrentMonthHospitalTask(wmTaskContent.getTemp29());
			if (CollectionUtil.isNotEmpty(taskList)) {
				boolean anyMatch = taskList.stream()
						.anyMatch(wmTask -> String.valueOf(sysU.getUserId()).equals(wmTask.getTaskUserId()));
				if (anyMatch) {
					return R.failed("该医院同一个人一个月只能修改一次");
				}
				if (taskList.size() > 3) {
					return R.failed("该医院一个月最多只能修改3次");
				}
			}
		}

		// 校验首次库存调查
		if ("31".equals(wmTaskContent.getTemp30())) {
			// 获取调查类别：0：首次
			String surveyType = wmTaskContent.getTemp23();

			if (!"0".equals(surveyType)) {
				return R.failed(1, "首次调查类型错误");
			}

			// 调查对象
			String surveyTarget = wmTaskContent.getTemp26label();
			// 调查品种
			String surveyCategory = wmTaskContent.getTemp24label();
			// 所属区域
			String location = wmTaskContent.getTemp5();

			// List<WmScorePackage> allPackages = wmScorePackageService.list(Wrappers.<WmScorePackage>lambdaQuery()
			// 		.eq(WmScorePackage::getDeptId, tWmScorePackage.getDeptId()));
			// List<Integer> allPackagesIdList = allPackages.stream().mapToInt(wsp -> Integer.parseInt(wsp.getId())).boxed().collect(Collectors.toList());
			//获取任务id
			// List<Integer> taskIdList = wmTaskList.stream()
			// 		.mapToInt(task -> Integer.parseInt(task.getId()))
			// 		.boxed()
			// 		.collect(Collectors.toList());
			List<WmTaskContent> taskContentList = list(Wrappers.<WmTaskContent>lambdaQuery()
					.eq(WmTaskContent::getTemp23, surveyType)
					.eq(WmTaskContent::getTemp26, surveyTarget)
					.eq(WmTaskContent::getTemp24, surveyCategory)
			);

			log.warn("内容：【{}】", taskContentList.toString());
			if (CollectionUtils.isNotEmpty(taskContentList)) {
				// 获取 所有任务id为31的任务且不是审核不通过的任务
				List<Integer> taskContentIdList = taskContentList.stream().mapToInt(WmTaskContent::getId).boxed().collect(Collectors.toList());
				List<WmTask> wmTaskList = wmTaskService.list(Wrappers.<WmTask>lambdaQuery().eq(WmTask::getTaskTypeId, "31")
						.ne(WmTask::getTaskStatus, "4")
						.in(WmTask::getTaskContentId, taskContentIdList)
				);
				if (CollectionUtils.isNotEmpty(wmTaskList)) {
					return R.failed(1, "该药品在本院的首次调查已经完结，不能提交");
				}
			}

			// 设置调查对象和调查品种
			wmTaskContent.setTemp24(surveyCategory);
			wmTaskContent.setTemp26(surveyTarget);

		}


		Map<String, String> resultMap = new HashMap<>();

		int score = 0;
		boolean saveContent = super.save(wmTaskContent);
		if (saveContent) {
			if (null != sysU) {
				WmTask wmTask = new WmTask();
				wmTask.setTaskFrom("1");
				LocalDateTime localDateTime = LocalDateTime.now();
				wmTask.setUpdateTime(localDateTime);
				wmTask.setTaskUserId(sysU.getUserId() + "");  //任务提交人
				wmTask.setLookintoDate(localDateTime);       //调研时间
				wmTask.setDrugEntId(tWmScorePackage.getDrugEntId());

				wmTask.setTaskTypeId(wmTaskContent.getTemp30());

				WmTaskType wmTaskType = new WmTaskType();
				wmTaskType.setRuleId(tWmScorePackage.getRuleId());
				WmTaskType wmTaskType1 = wmTaskTypeService.getById(wmTaskContent.getTemp30());
				wmTaskType.setTaskTypeName(wmTaskType1.getTaskTypeName());
				score = wmTaskTypeService.getWmTaskTypeByEnt(wmTaskType);

				/**
				 *
				 * 2020-12-13 医院区分新增和修改 start
				 * 修改积分搞为1000
				 */
				if ("15".equals(wmTaskContent.getTemp30()) || "30".equals(wmTaskContent.getTemp30())) {
					System.err.println("医院区分新增和修改:" + score);
					WmDaHospital wmDaHospital = new WmDaHospital();
					wmDaHospital.setYymc(wmTaskContent.getTemp3());
					if (wmDaHospitalMapper.selectCount(Wrappers.query(wmDaHospital)) != 0) {
						WmTaskType wmTaskType2 = new WmTaskType();
						WmScorePackage wmScorePackage1 = wmScorePackageService.getById(wmTaskContent.getTemp32());
						wmTaskType2.setRuleId(wmScorePackage1.getRuleId());
						wmTaskType2.setTaskTypeName("医院信息修改");
						score = wmTaskTypeService.getWmTaskTypeByEnt(wmTaskType2);
					}
				}
				/**
				 * 2020-12-13 医院区分新增和修改 end
				 */

				/*
				 * 2021-06-11 库存调查分成，首次调查和常规调查，常规调查走之前的逻辑 start
				 */
				if ("31".equals(wmTaskContent.getTemp30())) {
						WmTaskType wmTaskType2 = new WmTaskType();
						WmScorePackage wmScorePackage1 = wmScorePackageService.getById(wmTaskContent.getTemp32());
						wmTaskType2.setRuleId(wmScorePackage1.getRuleId());
						wmTaskType2.setTaskTypeName("库存信息收集-首次");
						score = wmTaskTypeService.getWmTaskTypeByEnt(wmTaskType2);
				}

				/*
				 * 2021-06-11 库存调查分成，首次调查和常规调查，常规调查走之前的逻辑 end
				 */

				System.out.println("获取任务得分：" + score);
				if (score < 0) {
					return R.failed("获取任务积分失败");
				}
				wmTask.setScore(score);

				resultMap.put("score", tWmScorePackage.getPackageType1());
				log.warn("获取积分包ID：{}", tWmScorePackage);

				wmTask.setScorePackageId(tWmScorePackage.getId());
				wmTask.setTaskRuleId(tWmScorePackage.getTaskRuleId());

				wmTask.setTaskContentId(wmTaskContent.getId() + "");

				if (HnqzUtils.isZbRole(sysU.getRoleList(), 5)) {
					wmTask.setTaskUserType("5");
				}

				wmTask.setCreateTime(localDateTime);

				if (HnqzUtils.isZbRole(sysU.getRoleList(), 6)) {
					wmTask.setTaskUserType("6");
				}

				wmTask.setDeptId(sysU.getDeptId() + "");
				wmTask.setSubmitStatus("0");

				/**
				 * 不需要平台管理员审核的直接提交上级审核  taskStatus = 2 已提交
				 * 否则 taskStatus = 1 待提交
				 */
				wmTask.setRealFlag("0");
				wmTask.setTaskStatus("2");

				//保存任务
				boolean isSave = wmTaskService.save(wmTask);
				/**
				 * 2020-12-21
				 * 15、30-医院 16-商业  18-药店
				 * 三类修改为平台管理员审核后才能在任务中心查出来
				 * realFlag  0-真实  1-非真实  9-审核中
				 *
				 * 2021-9-2 by lixuesong
				 * 去掉平台管理员审核，调整到个人任务审核
				 */
				if ("15".equals(wmTaskContent.getTemp30())
						|| "16".equals(wmTaskContent.getTemp30())
						|| "30".equals(wmTaskContent.getTemp30())
						|| "18".equals(wmTaskContent.getTemp30())) {
					// 校验调查信息审核，对比信息无改动则不可保存（15、30-医院 16-商业  18-药店）
					R taskResult = wmTaskService.getSurveryTaskInfo(wmTask.getId());
					Map<String, Object> data = (Map<String, Object>) taskResult.getData();
					WmTask task = (WmTask) data.get("wmTask");
					if ("3".equals(task.getCompareResult())) {
						// 3-信息无变化，删除这条任务
						wmTaskService.removeById(wmTask.getId());
						this.removeById(wmTask.getTaskContentId());
						return R.failed("信息无变化，不可提交");
					}
					resultMap.put("type", "3");
				}
				/**
				 * 2020-12-21 end
				 */

				//判断任务是否完成
				if (isSave) {
					WmScorePackage wmScorePackage1 = wmScorePackageService.getById(tWmScorePackage.getId());
					if (null != wmScorePackage1) {
						WmTask taskQuery = new WmTask();
						taskQuery.setScorePackageId(tWmScorePackage.getId());
						QueryWrapper<WmTask> taskQueryWrapper = Wrappers.query(taskQuery);
						/**
						 * 查询出 审核通过和审核中的任务
						 */
						taskQueryWrapper.lambda()
								.ne(WmTask::getTaskStatus, "4")
								.eq(WmTask::getRealFlag, "0");
//								.ne(WmTask::getRealFlag, "1");
						List<WmTask> wmTaskList = wmTaskService.list(taskQueryWrapper);
						/**
						 * 判断定量还是定额 1- 定额   2-定量
						 */
						if ("1".equals(wmScorePackage1.getPackageType1())) {

							int totalCount = 0;
							for (WmTask wmtask : wmTaskList) {
								totalCount += wmtask.getScore();
							}

							if (totalCount >= wmScorePackage1.getScore()) {
								wmScorePackage1.setTaskAddFlag("0");
								scorePackageStatus.setTaskAddFlag("0");
								wmScorePackageStatusService.updateById(scorePackageStatus);
							}
							resultMap.put("type", "1");
						} else if ("2".equals(wmScorePackage1.getPackageType1()) || "3".equals(wmScorePackage1.getPackageType1())) {
							score = 0;

							List<WmTask> userTaskList = wmTaskList.stream().filter(item ->
									item.getTaskUserId().equals(sysU.getUserId() + "")).collect(Collectors.toList());

							if (userTaskList.size() >= scorePackageStatus.getTaskNum()) {
								scorePackageStatus.setTaskAddFlag("0");
								wmScorePackageStatusService.updateById(scorePackageStatus);

								/**
								 * 改变大包状态
								 */
								WmScorePackageStatus queryAll = new WmScorePackageStatus();
								queryAll.setPackageId(tWmScorePackage.getId());
								queryAll.setStatus("2");
								queryAll.setTaskAddFlag("0");
								List<WmScorePackageStatus> statusAll = wmScorePackageStatusService.
										list(Wrappers.query(queryAll));
								if (new BigDecimal(wmScorePackage1.getUserNum())
										.compareTo(new BigDecimal(statusAll.size())) <= 0) {
									wmScorePackage1.setTaskAddFlag("0");
								}
							}

//							if (wmTaskList.size() >= wmScorePackage1.getTaskNum()) {
//								wmScorePackage1.setTaskAddFlag("0");
//							}
							resultMap.put("type", "2");
						}

						wmScorePackage1.setIsConduct("1");
						wmScorePackageService.updateById(wmScorePackage1);

					}

				} else {
					return R.failed("任务保存失败");
				}
				//保存打卡记录
				if ("5".equals(wmTaskContent.getTemp30()) || "6".equals(wmTaskContent.getTemp30())) {
					WmUserSign wmUserSign = new WmUserSign();
					wmUserSign.setSignEntType(wmTaskContent.getTemp29());
					wmUserSign.setSignEntName(wmTaskContent.getTemp7());
					wmUserSign.setLatitude(wmTaskContent.getTemp28());
					wmUserSign.setLongitude(wmTaskContent.getTemp26());
					wmUserSign.setSignUserid(wmTaskContent.getTemp25());
					wmUserSign.setSignEntId(wmTaskContent.getTemp24());
					wmUserSign.setSignDate(localDateTime);
					wmUserSignMapper.insert(wmUserSign);
				}
			}

		}

		resultMap.put("score", score + "");
		return R.ok(resultMap);
	}

}
