/*
 *    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.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
import com.qunzhixinxi.hnqz.admin.entity.WmReport;
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.enums.ReportEnum;
import com.qunzhixinxi.hnqz.admin.enums.ScorePackageStatusEnum;
import com.qunzhixinxi.hnqz.admin.enums.TaskStatusEnum;
import com.qunzhixinxi.hnqz.admin.mapper.WmReportMapper;
import com.qunzhixinxi.hnqz.admin.service.SysUserService;
import com.qunzhixinxi.hnqz.admin.service.WmDaDistributionService;
import com.qunzhixinxi.hnqz.admin.service.WmDaHospitalService;
import com.qunzhixinxi.hnqz.admin.service.WmDaPharmacyService;
import com.qunzhixinxi.hnqz.admin.service.WmReportService;
import com.qunzhixinxi.hnqz.admin.service.WmScorePackageService;
import com.qunzhixinxi.hnqz.admin.service.WmScorePackageStatusService;
import com.qunzhixinxi.hnqz.admin.service.WmTaskService;
import com.qunzhixinxi.hnqz.common.core.util.R;
import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 报告审核表
 *
 * @author pigx code generator
 * @date 2020-12-21 20:57:26
 */
@Service
@AllArgsConstructor
public class WmReportServiceImpl extends ServiceImpl<WmReportMapper, WmReport> implements WmReportService {

	private final WmScorePackageService wmScorePackageService;
	private final WmScorePackageStatusService wmScorePackageStatusService;
	private final WmTaskService wmTaskService;
	private final WmReportMapper wmReportMapper;
	private final SysUserService sysUserService;
	private final WmDaDistributionService wmDaDistributionService;
	private final WmDaPharmacyService wmDaPharmacyService;
	private final WmDaHospitalService wmDaHospitalService;

	@Override
	public IPage<WmReport> getReportListPage(Page page, WmReport wmReport, String scoreId, String name){
		return wmReportMapper.getReportListPage(page,wmReport,scoreId,name);
	}


	/**
	 * 报告审核状态修改--提交或结单
	 * reportStatus 1:待提交，2:已提交待审批 3：已部分审批  4：已退回 5:已审批待结单 6:已结单
	 * @param wmReport 报告审核表
	 * @return R
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R updateReportStatus(WmReport wmReport) {
		HnqzUser user= SecurityUtils.getUser();
		//提交修改状态，更新时间
		LambdaUpdateWrapper<WmReport> updateWrapper=new LambdaUpdateWrapper<>();
		updateWrapper.set(WmReport::getUpdatePeople,user.getId());
		updateWrapper.set(WmReport::getUpdateTime, LocalDateTime.now());
		updateWrapper.set(WmReport::getReportStatus, wmReport.getReportStatus());
		updateWrapper.eq(WmReport::getId,wmReport.getId());
		boolean isupdate=this.update(updateWrapper);
		if(!isupdate){
			return R.failed("更新报告状态失败");

		}
		//报告状态更新之后，要同时更新任务的报告审核状态
		updateTaskStatusByReport(wmReport);

		return R.ok("成功");
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public R del(WmReport wmReport)  {
		LambdaUpdateWrapper<WmReport> updateWrapper=new LambdaUpdateWrapper<>();
		updateWrapper.set(WmReport::getDelFlag, wmReport.getDelFlag());
		updateWrapper.eq(WmReport::getId,wmReport.getId());
		boolean isupdate=this.update(updateWrapper);
		if(!isupdate){
			return R.failed("更新报告状态失败");
		}
		wmReport.setReportStatus(null);
		updateTaskStatusByReport(wmReport);
		return R.ok("删除成功");
	}



	/**
	 * 报告状态更新之后，要同时更新任务的报告审核状态
	 * @param wmReport
	 */
	@Transactional(rollbackFor = Exception.class)
	public void updateTaskStatusByReport(WmReport wmReport){
		WmScorePackage scorePackage=wmScorePackageService.getById(wmReport.getScoreId());
		//typeid  0 药企  1一级代理商 2二级代理商 3全职学术推广员 4兼职学术推广员
		LambdaUpdateWrapper<WmTask> updateWrapper=new LambdaUpdateWrapper<>();

		if("0".equals(scorePackage.getTypeid())){//药企
			if("1".equals(wmReport.getDelFlag())){
				updateWrapper.set(WmTask::getReportDrugId,null);
				updateWrapper.set(WmTask::getReportDrugApprovalOpinion,null);
				updateWrapper.set(WmTask::getReportDrugApprovalInfo,null);
			}
			updateWrapper.set(WmTask::getReportDrugApprovalStatus,wmReport.getReportStatus());
			updateWrapper.eq(WmTask::getReportDrugId,wmReport.getId());
		}else if("1".equals(scorePackage.getTypeid())){//一级代理商类型
			if("1".equals(wmReport.getDelFlag())){
				updateWrapper.set(WmTask::getReportOneId,null);
				updateWrapper.set(WmTask::getReportOneApprovalOpinion,null);
				updateWrapper.set(WmTask::getReportOneApprovalInfo,null);
			}
			if(SecurityUtils.getRoles().contains(3)){//药企
				updateWrapper.set(WmTask::getReportDrugApprovalStatus,wmReport.getReportStatus());
			}
			updateWrapper.set(WmTask::getReportOneApprovalStatus,wmReport.getReportStatus());
			updateWrapper.eq(WmTask::getReportOneId,wmReport.getId());
		}else if("2".equals(scorePackage.getTypeid())){//二级代理商类型
			if("1".equals(wmReport.getDelFlag())){
				updateWrapper.set(WmTask::getReportSecondId,null);
				updateWrapper.set(WmTask::getReportSecondApprovalOpinion,null);
				updateWrapper.set(WmTask::getReportSecondApprovalInfo,null);
			}
			if(SecurityUtils.getRoles().contains(4)){// 一级CSO
				updateWrapper.set(WmTask::getReportOneApprovalStatus,wmReport.getReportStatus());
			}
			updateWrapper.set(WmTask::getReportSecondApprovalStatus,wmReport.getReportStatus());
			updateWrapper.eq(WmTask::getReportSecondId,wmReport.getId());
		}
		wmTaskService.update(updateWrapper);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public R approvalReport(WmReport wmReport, List<String> taskIds, String approvalOpinion, String approvalInfo) {
		List<WmTask> taskList=new ArrayList<>();//该报告关联的所有未提交的任务

		WmScorePackage scorePackage = wmScorePackageService.getById(wmReport.getScoreId());
		// 如果是源头积分包，则判断是否审核入库调查信息
		if (StringUtils.isBlank(scorePackage.getRelationScoreId())) {
			List<WmTask> tasks = wmTaskService.list(Wrappers.<WmTask>lambdaQuery().in(WmTask::getId, taskIds));
			// 调查信息审核（15、30-医院 16-商业公司 18-药店）
			tasks.forEach(task -> {
				if ("15".equals(task.getTaskTypeId()) || "30".equals(task.getTaskTypeId())) {
					Map<String, Object> data = (Map<String, Object>) wmDaHospitalService.approvalHospital(task.getId()).getData();
					WmTask _wmTask = (WmTask) data.get("wmTask");
					Map<String, String> paramMap = BeanUtil.toBean(data.get("newinfo"), Map.class);
					paramMap.put("approvalInfo", approvalInfo);
					paramMap.put("approvalOpinion", approvalOpinion);
					paramMap.put("compareResult", _wmTask.getCompareResult());
					paramMap.put("taskId", task.getId());
					wmDaHospitalService.updateByApproval(paramMap);
				} else if ("16".equals(task.getTaskTypeId())) {
					Map<String, Object> data = (Map<String, Object>) wmDaDistributionService.approvalDistribution(task.getId()).getData();
					WmTask _wmTask = (WmTask) data.get("wmTask");
					Map<String, String> paramMap = BeanUtil.toBean(data.get("newinfo"), Map.class);
					paramMap.put("approvalInfo", approvalInfo);
					paramMap.put("approvalOpinion", approvalOpinion);
					paramMap.put("compareResult", _wmTask.getCompareResult());
					paramMap.put("taskId", task.getId());
					wmDaDistributionService.updateByApproval(paramMap);
				} else if ("18".equals(task.getTaskTypeId())) {
					Map<String, Object> data = (Map<String, Object>) wmDaPharmacyService.approvalPharmacy(task.getId()).getData();
					WmTask _wmTask = (WmTask) data.get("_wmTask");
					Map<String, String> paramMap = MapUtil.newHashMap(4);
					paramMap.put("approvalInfo", approvalInfo);
					paramMap.put("approvalOpinion", approvalOpinion);
					paramMap.put("compareResult", _wmTask.getCompareResult());
					paramMap.put("taskId", task.getId());
					wmDaPharmacyService.updateByapproval(paramMap);
				}
			});
		}

		//更新任务表审批意见,查询所有未审核的任务，判断报告关联任务是否全部审核
		LambdaUpdateWrapper<WmTask> updateTaskWrapper=new LambdaUpdateWrapper<>();
		WmTask wmTask=new WmTask();
		if(SecurityUtils.getRoles().contains(3)){//药企
			updateTaskWrapper.set(WmTask::getReportDrugApprovalStatus,ReportEnum.REPORT_STATUS_SETTLE.getType());
			updateTaskWrapper.set(WmTask::getReportDrugApprovalOpinion,approvalOpinion);
			updateTaskWrapper.set(WmTask::getReportDrugApprovalInfo,approvalInfo);

			if("1".equals(scorePackage.getTypeid())){
				updateTaskWrapper.set(WmTask::getReportOneApprovalStatus,ReportEnum.REPORT_STATUS_SETTLE.getType());
				updateTaskWrapper.set(WmTask::getReportOneApprovalOpinion,approvalOpinion);
				updateTaskWrapper.set(WmTask::getReportOneApprovalInfo,approvalInfo);
			}
			updateTaskWrapper.in(WmTask::getId,taskIds);

		}else if(SecurityUtils.getRoles().contains(4)){//一级代理商类型

			updateTaskWrapper.set(WmTask::getReportOneApprovalStatus,ReportEnum.REPORT_STATUS_SETTLE.getType());
			updateTaskWrapper.set(WmTask::getReportOneApprovalOpinion,approvalOpinion);
			updateTaskWrapper.set(WmTask::getReportOneApprovalInfo,approvalInfo);
			if("2".equals(scorePackage.getTypeid())){
				updateTaskWrapper.set(WmTask::getReportSecondApprovalStatus,ReportEnum.REPORT_STATUS_SETTLE.getType());
				updateTaskWrapper.set(WmTask::getReportSecondApprovalOpinion,approvalOpinion);
				updateTaskWrapper.set(WmTask::getReportSecondApprovalInfo,approvalInfo);
			}
			updateTaskWrapper.in(WmTask::getId,taskIds);
		}
		if("0".equals(scorePackage.getTypeid())){//药企
			wmTask.setReportDrugId(wmReport.getId());
			wmTask.setReportDrugApprovalStatus(ReportEnum.REPORT_STATUS_APPROVAL.getType());
		}else if("1".equals(scorePackage.getTypeid())){//一级代理商类型
			wmTask.setReportOneId(wmReport.getId());
			wmTask.setReportOneApprovalStatus(ReportEnum.REPORT_STATUS_APPROVAL.getType());
		}else if("2".equals(scorePackage.getTypeid())) {//二级代理商类型
			wmTask.setReportSecondId(wmReport.getId());
			wmTask.setReportSecondApprovalStatus(ReportEnum.REPORT_STATUS_APPROVAL.getType());
		}
//
		if ("1".equals(approvalOpinion)) {
			updateTaskWrapper.set(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val());
		} else if ("2".equals(approvalOpinion)) {
			// 审核不通过，则设置TaskStatus为不通过
			updateTaskWrapper.set(WmTask::getTaskStatus, TaskStatusEnum.FAIL_APPROVED.val());
		}
		updateTaskWrapper.set(WmTask::getRealFlag, "0");
		wmTaskService.update(updateTaskWrapper);
		taskList = wmTaskService.list(Wrappers.query(wmTask));
		//更新报告状态
		HnqzUser user= SecurityUtils.getUser();
		//提交修改状态，更新时间
		LambdaUpdateWrapper<WmReport> updateWrapper=new LambdaUpdateWrapper<>();

		//判断任务是不是已经全部审核完成，所有的任务都完成才算完成
		if(taskList.isEmpty()){//taskList为空，说明任务都已审核
			updateWrapper.set(WmReport::getReportStatus, ReportEnum.REPORT_STATUS_SETTLE.getType());
		}else {//不为空，说明是部分审批
			updateWrapper.set(WmReport::getReportStatus, ReportEnum.REPORT_STATUS_PART_APPROVAL.getType());
		}
		updateWrapper.set(WmReport::getUpdatePeople, user.getId());
		updateWrapper.set(WmReport::getUpdateTime, LocalDateTime.now());
		updateWrapper.eq(WmReport::getId, wmReport.getId());
		this.update(updateWrapper);

		LambdaQueryWrapper<WmTask> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.in(WmTask::getId, taskIds);
		List<WmTask> wmTaskList = wmTaskService.list(queryWrapper);
		if ("2".equals(approvalOpinion)) {
			// 审核不通过，则释放积分值，从而直接可以重新做任务
			wmTaskList.forEach(task -> {
				// 查询积分包状态
				WmScorePackageStatus scorePackageStatus = new WmScorePackageStatus();
				scorePackageStatus.setPackageId(task.getScorePackageId());
				scorePackageStatus.setUserId(task.getTaskUserId());
				scorePackageStatus.setStatus("2");//接单审核通过
				WmScorePackageStatus updateScorePackageStatus = wmScorePackageStatusService.getOne(Wrappers.query(scorePackageStatus));
				// 查询已提交的任务（除去审核不通过的任务）
				Wrapper<WmTask> taskQueryWrapper = Wrappers.<WmTask>lambdaQuery()
						.eq(WmTask::getScorePackageId, task.getScorePackageId())
						.in(WmTask::getTaskStatus, "1", "2", "3")
						.eq(WmTask::getRealFlag, "0");
				List<WmTask> submitedTaskList = wmTaskService.list(taskQueryWrapper);
				// 统计判断任务累计积分是否达到积分包的预设值
				int totalTaskScore = submitedTaskList.stream().mapToInt(WmTask::getScore).sum();
				WmScorePackage taskScorePackage = wmScorePackageService.getById(task.getScorePackageId());
				WmScorePackage updateScorePackage = new WmScorePackage();
				updateScorePackage.setId(task.getScorePackageId());
				if (totalTaskScore >= taskScorePackage.getScore()) {
					updateScorePackage.setScorePackageStatus(ScorePackageStatusEnum.TO_BE_APPROVAL.val());
					updateScorePackage.setTaskAddFlag("0");
					updateScorePackageStatus.setTaskAddFlag("0");
				}else {
					updateScorePackage.setScorePackageStatus(ScorePackageStatusEnum.IN_PROGRESS.val());
					updateScorePackage.setTaskAddFlag("1");
					updateScorePackageStatus.setTaskAddFlag("1");
				}
				wmScorePackageStatusService.updateById(updateScorePackageStatus);
				wmScorePackageService.updateById(updateScorePackage);
			});
		} else if ("1".equals(approvalOpinion)) {
			// 审核通过，则判断企业审核通过积分值是否达到积分包的预设值
			wmTaskList.forEach(task -> {
				Wrapper<WmTask> apporvalWrapper = Wrappers.<WmTask>lambdaQuery()
						.eq(WmTask::getScorePackageId, task.getScorePackageId())
						.eq(WmTask::getTaskStatus, TaskStatusEnum.APPROVED.val())
						.eq(WmTask::getRealFlag, "0")
						.and(wrapper -> wrapper.eq(WmTask::getReportDrugApprovalOpinion, "1")
								.or().eq(WmTask::getReportOneApprovalOpinion, "1"));
				List<WmTask> approvalTaskList = wmTaskService.list(apporvalWrapper);
				int totalScore = approvalTaskList.stream().mapToInt(WmTask::getScore).sum();
				WmScorePackage taskScorePackage = wmScorePackageService.getById(task.getScorePackageId());
				if (totalScore >= taskScorePackage.getScore()) {
					WmScorePackage updateScorePackage = new WmScorePackage();
					updateScorePackage.setId(task.getScorePackageId());
					updateScorePackage.setScorePackageStatus(ScorePackageStatusEnum.TO_BE_SETTLED.val());
					updateScorePackage.setTaskAddFlag("0");
					wmScorePackageService.updateById(updateScorePackage);
				}
			});
		}

		return R.ok("审批成功");
	}

	/**
	 * 报告管理--查看
	 * @param page
	 * @param wmReport
	 * @param isApprovalPage 1审批，0查看
	 * @return
	 */
	@Override
	public R getTaskListPage(Page page, WmReport wmReport, Integer isApprovalPage) {
		Page pages=null;
		WmScorePackage scorePackage=wmScorePackageService.getById(wmReport.getScoreId());
		WmTask wmTask=new WmTask();
		LambdaQueryWrapper<WmTask> lambdaQueryWrapper= Wrappers.<WmTask>query().lambda();
		lambdaQueryWrapper.and(wrapper -> wrapper.eq(WmTask::getReportDrugId, wmReport.getId())
				.or().eq(WmTask::getReportOneId, wmReport.getId())
				.or().eq(WmTask::getReportSecondId, wmReport.getId()));
		// 如果是审批页面，则过滤掉通过和不通过的数据（reportDrugApprovalOpinion或reportOneApprovalOpinion：1通过，2不通过）
		if (isApprovalPage != null && isApprovalPage.equals(1)) {
			if ("0".equals(scorePackage.getTypeid())) {//药企
				lambdaQueryWrapper.and(wrapper -> wrapper.isNull(WmTask::getReportDrugApprovalOpinion));
			} else if ("1".equals(scorePackage.getTypeid())) {//一级代理商类型
				lambdaQueryWrapper.and(wrapper -> wrapper.isNull(WmTask::getReportDrugApprovalOpinion));
			} else if ("2".equals(scorePackage.getTypeid())) {//二级代理商类型
				lambdaQueryWrapper.and(wrapper -> wrapper.isNull(WmTask::getReportOneApprovalOpinion));
			}
		}
		pages=wmTaskService.page(page, lambdaQueryWrapper);
//		if("0".equals(scorePackage.getTypeid())){//药企
//			wmTask.setReportDrugId(wmReport.getId());
//			pages=wmTaskService.page(page, Wrappers.query(wmTask));
//		}else if("1".equals(scorePackage.getTypeid())){//一级代理商类型
//			wmTask.setReportOneId(wmReport.getId());
//			pages=wmTaskService.page(page, Wrappers.query(wmTask));
//		}else if("2".equals(scorePackage.getTypeid())){//二级代理商类型
//			wmTask.setReportSecondId(wmReport.getId());
//			pages=wmTaskService.page(page, Wrappers.query(wmTask));
//		}
		if(pages==null){
			return R.ok();
		}
		List<WmTask> taskList=pages.getRecords();
		if(!taskList.isEmpty()){
			List<Map> resList =taskList.stream().map(wmtask -> {
				Map map = JSON.parseObject(JSON.toJSONString(wmtask), Map.class);
				map.put("reportNo",wmReport.getReportNo());
				map.put("scoreId",wmReport.getScoreId());
				if("0".equals(scorePackage.getTypeid())){//药企
					map.put("reportApprovalOpinion",wmtask.getReportDrugApprovalOpinion());
				}else if("1".equals(scorePackage.getTypeid())){//一级代理商类型
//					map.put("reportApprovalOpinion",wmtask.getReportOneApprovalOpinion());
					map.put("reportApprovalOpinion",wmtask.getReportDrugApprovalOpinion());
				}else if("2".equals(scorePackage.getTypeid())){//二级代理商类型
//					map.put("reportApprovalOpinion",wmtask.getReportSecondApprovalOpinion());
					map.put("reportApprovalOpinion",wmtask.getReportOneApprovalOpinion());
				}
				// 姓名
				if (StringUtils.isNumeric(wmtask.getTaskUserId())) {
					SysUser user = sysUserService.getById(Integer.parseInt(wmtask.getTaskUserId()));
					map.put("taskUsername", user.getRealname());
				}
				return map;
			}).collect(Collectors.toList());

			page.setRecords(resList);
		}
		return R.ok(pages);
	}


}



