/*
 *    Copyright (c) 2018-2025, lengleng 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 yifu4cloud.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: lengleng (wangiegie@gmail.com)
 */
package com.yifu.cloud.plus.v1.yifu.archives.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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.pig4cloud.plugin.excel.vo.ErrorMessage;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TCustomerInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmpChangeInfo;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TEmployeeProject;
import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TEmpChangeInfoMapper;
import com.yifu.cloud.plus.v1.yifu.archives.mapper.TSettleDomainMapper;
import com.yifu.cloud.plus.v1.yifu.archives.service.TCustomerInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TEmpChangeInfoService;
import com.yifu.cloud.plus.v1.yifu.archives.service.TEmployeeProjectService;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TEmpChangeInfoVO;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.ErrorCodes;
import com.yifu.cloud.plus.v1.yifu.common.core.util.Common;
import com.yifu.cloud.plus.v1.yifu.common.core.util.DateUtil;
import com.yifu.cloud.plus.v1.yifu.common.core.util.MsgUtils;
import com.yifu.cloud.plus.v1.yifu.common.core.util.R;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.SocialDaprUtils;
import com.yifu.cloud.plus.v1.yifu.salary.vo.UpdateSocialFoundVo;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;

import java.util.*;
import java.util.regex.Pattern;

/**
 * 档案划转日志表
 *
 * @author fxj
 * @date 2022-06-18 09:39:46
 */
@Service
@RequiredArgsConstructor
public class TEmpChangeInfoServiceImpl extends ServiceImpl<TEmpChangeInfoMapper, TEmpChangeInfo> implements TEmpChangeInfoService {

	private final TEmployeeProjectService tEmployeeProjectService;

	private final TCustomerInfoService tCustomerInfoService;

	private final TSettleDomainMapper tSettleDomainMapper;

	private final TEmployeeLogServiceImpl tEmployeeLogService;

	@Autowired
	private final SocialDaprUtils socialDaprUtils;

	public static final Pattern PATTERN = Pattern.compile("^[-\\+]?[\\d]*$");

	/**
	 * @Author huyc
	 * @Description  档案划转
	 * @Date 2022/6/22
	 **/
	@Override
	public R changeEmpProArc(TEmpChangeInfo tEmpChangeInfo) {

		//待划转员工已在目标项目下不可划转
		TEmployeeProject tEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query().lambda()
				.eq(TEmployeeProject::getEmpIdcard, tEmpChangeInfo.getEmpIdcard()).eq(TEmployeeProject::getDeptNo,tEmpChangeInfo.getDeptNo())
				.eq(TEmployeeProject::getDeleteFlag,CommonConstants.STATUS_NORMAL));
		if (Common.isNotNull(tEmployeeProject)) {
			return R.failed("待划转员工已在目标项目下不可划转");
		}
		//划转+已产生未结算金额划转，并且选择了划转月份
		//社保公积金派单处需要直接修改为最新的项目
		//社保预估库、缴费库、对比库、代理差额库，需要同步修改未结算（并且满足这个条件：数据 生成月≥此处划转起始月）的数据，已结算数据不变更；
		//划转,更新项目信息
		TEmployeeProject updateTEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query().lambda()
				.eq(TEmployeeProject::getEmpIdcard, tEmpChangeInfo.getEmpIdcard()).eq(TEmployeeProject::getDeptName,tEmpChangeInfo.getOldSettle())
				.eq(TEmployeeProject::getDeleteFlag,CommonConstants.STATUS_NORMAL).eq(TEmployeeProject::getProjectStatus,CommonConstants.ZERO_INT));
		if (Common.isNotNull(updateTEmployeeProject)) {

			if (updateTEmployeeProject.getSocialStatus() == CommonConstants.dingleDigitIntArray[1] ||
					updateTEmployeeProject.getFundStatus() == CommonConstants.dingleDigitIntArray[1]) {
				return R.failed("人员在原项目中存在在途的服务，请先终止后，再进行划转");
			}

			TSettleDomain tSettleDomain = tSettleDomainMapper.selectOne(Wrappers.<TSettleDomain>query().lambda()
					.eq(TSettleDomain::getDepartNo, tEmpChangeInfo.getDeptNo()).eq(TSettleDomain::getDepartName, tEmpChangeInfo.getNewSettle())
					.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING).eq(TSettleDomain::getStopFlag, CommonConstants.ZERO_STRING));
			TEmployeeProject tEmployeeProjectOld = tEmployeeProjectService.getById(updateTEmployeeProject.getId());
			updateTEmployeeProject.setDeptNo(tEmpChangeInfo.getDeptNo());
			updateTEmployeeProject.setDeptId(tEmpChangeInfo.getDeptId());
			updateTEmployeeProject.setDeptName(tEmpChangeInfo.getNewSettle());
			updateTEmployeeProject.setUnitId(tEmpChangeInfo.getUnitId());
			updateTEmployeeProject.setUnitNo(tEmpChangeInfo.getUnitNo());
			updateTEmployeeProject.setUnitName(tEmpChangeInfo.getNewDept());
			updateTEmployeeProject.setBusinessPrimaryType(tSettleDomain.getBusinessPrimaryType());
			updateTEmployeeProject.setBusinessSecondType(tSettleDomain.getBusinessSecondType());
			updateTEmployeeProject.setBusinessThirdType(tSettleDomain.getBusinessThirdType());
			tEmployeeProjectService.updateById(updateTEmployeeProject);
			tEmpChangeInfo.setProId(updateTEmployeeProject.getId());
			// 记录变更日志
			tEmployeeLogService.saveModificationRecord(CommonConstants.dingleDigitIntArray[1], "", updateTEmployeeProject.getId(), tEmployeeProjectOld, updateTEmployeeProject);

			UpdateSocialFoundVo updateSocialFoundVo = new UpdateSocialFoundVo();
			updateSocialFoundVo.setEmpIdcard(updateTEmployeeProject.getEmpIdcard());
			updateSocialFoundVo.setSettleDomainCode(updateTEmployeeProject.getDeptNo());
			updateSocialFoundVo.setSettleDomainId(updateTEmployeeProject.getDeptId());
			updateSocialFoundVo.setSettleDomainName(updateTEmployeeProject.getDeptName());
			updateSocialFoundVo.setUnitId(updateTEmployeeProject.getUnitId());
			updateSocialFoundVo.setUnitName(updateTEmployeeProject.getUnitName());
			if (CommonConstants.ONE_STRING.equals(tEmpChangeInfo.getUnsettleDeal())) {
				updateSocialFoundVo.setSocialCreateMonth(tEmpChangeInfo.getChangeStartMonth().replace("-",""));
				socialDaprUtils.updatePaymentSocialAndFound(updateSocialFoundVo);
				socialDaprUtils.updateForSocialAndFound(updateSocialFoundVo);
			}
			if (CommonConstants.ZERO_INT != updateTEmployeeProject.getSocialStatus()) {
				updateSocialFoundVo.setFlag(CommonConstants.ZERO_STRING);
				socialDaprUtils.updateSocialAndFoundInfo(updateSocialFoundVo);
			}
			if (CommonConstants.ZERO_INT != updateTEmployeeProject.getFundStatus()) {
				updateSocialFoundVo.setFlag(CommonConstants.ONE_STRING);
				socialDaprUtils.updateSocialAndFoundInfo(updateSocialFoundVo);
			}
		}

		//保存档案划转记录
		this.save(tEmpChangeInfo);
		return R.ok();
	}

	@Override
	public R<List<ErrorMessage>> batchChangeArc(List<TEmpChangeInfoVO> excelVOList, BindingResult bindingResult) {
		// 通用校验获取失败的数据
		List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
		Map<Long,ErrorMessage> errorMsgMap = new HashMap<>();
		if (Common.isNotNull(errorMessageList)){
			errorMessageList.stream().forEach(errorMessage -> errorMsgMap.put(errorMessage.getLineNum(),errorMessage));
		}

		List<TEmployeeProject> updateList = new ArrayList<>();
		Set<String> errorMsg;
		// 执行数据插入操作 组装
		for (int i = 0; i < excelVOList.size(); i++) {
			// 已有验证报错直接下一个
			if (Common.isNotNull(errorMsgMap.get(i+2))){
				continue;
			}
			errorMsg = new HashSet<>();
			TEmpChangeInfoVO excel = excelVOList.get(i);
			excel.setUnsettleDeal(CommonConstants.IS_NO_CHANGE);
			if (Common.isNotNull(excel.getChangeStartMonth()) && excel.getChangeStartMonth().length() > CommonConstants.dingleDigitIntArray[6]) {
				errorMsg.add("划转起始月长度不能超过6位");
			}
			if (!Common.isEmpty(excel.getChangeStartMonth()) && !PATTERN.matcher(excel.getChangeStartMonth()).matches()) {
				errorMsg.add("划转起始月格式错误");
			}
			if (excel.getUnsettleDeal().equals(CommonConstants.IS_CHANGE)) {
				if (Common.isEmpty(excel.getChangeStartMonth())) {
					errorMsg.add("划转起始月不能为空");
				} else if (PATTERN.matcher(excel.getChangeStartMonth()).matches()) {
					if (Integer.parseInt(excel.getChangeStartMonth()) > Integer.parseInt(DateUtil.getThisMonth())) {
						errorMsg.add("划转起始月要小于等于当前月");
					}
				}
			}

			//项目编码校验
			TSettleDomain tSettleDomain = tSettleDomainMapper.selectOne(Wrappers.<TSettleDomain>query().lambda()
					.eq(TSettleDomain::getDepartNo, excel.getNewSettleCode())
					.eq(TSettleDomain::getStopFlag, CommonConstants.ZERO_STRING)
					.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING));
			if (Common.isEmpty(tSettleDomain)) {
				errorMsg.add(MsgUtils.getMessage(ErrorCodes.PROJECT_SEARCH_NOT_EXIST, excel.getNewSettleCode()));
			}

			//待划转员工已在目标项目下不可划转
			TEmployeeProject tEmployeeProject = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query().lambda()
					.eq(TEmployeeProject::getEmpIdcard, excel.getEmpIdcard()).eq(TEmployeeProject::getDeptNo,excel.getNewSettleCode())
					.eq(TEmployeeProject::getDeleteFlag,CommonConstants.STATUS_NORMAL)
					.eq(TEmployeeProject::getProjectStatus,CommonConstants.ZERO_INT));
			if (Common.isNotNull(tEmployeeProject)) {
				errorMsg.add(MsgUtils.getMessage(ErrorCodes.CHECKS_CHANGE_EMP_PROJECT, excel.getNewSettleCode()));
			}
			// 数据合法情况
			if (CollUtil.isEmpty(errorMsg)) {
				//划转,更新项目信息
				TEmployeeProject updateTEmployeePro = tEmployeeProjectService.getOne(Wrappers.<TEmployeeProject>query().lambda()
						.eq(TEmployeeProject::getEmpIdcard, excel.getEmpIdcard()).eq(TEmployeeProject::getDeptNo,excel.getOldSettleCode())
						.eq(TEmployeeProject::getDeleteFlag,CommonConstants.STATUS_NORMAL));
				if (Common.isNotNull(updateTEmployeePro)) {
					if (updateTEmployeePro.getSocialStatus() == CommonConstants.dingleDigitIntArray[1] ||
							updateTEmployeePro.getFundStatus() == CommonConstants.dingleDigitIntArray[1]) {
						errorMsg.add(MsgUtils.getMessage(ErrorCodes.QT_PROJECT_CHANGE_NOT_EXIST, excel.getOldSettleCode()));
					}
					if (CommonConstants.ONE_INT == updateTEmployeePro.getProjectStatus()) {
						errorMsg.add(MsgUtils.getMessage(ErrorCodes.PROJECT_PERSON_DELETE_EXIT, excel.getOldSettleCode()));
					} else if (Common.isNotNull(tSettleDomain)) {
						TEmployeeProject tEmployeeProjectOld = tEmployeeProjectService.getById(updateTEmployeePro.getId());
						updateTEmployeePro.setDeptNo(tSettleDomain.getDepartNo());
						updateTEmployeePro.setDeptId(tSettleDomain.getId());
						updateTEmployeePro.setDeptName(tSettleDomain.getDepartName());
						updateTEmployeePro.setBusinessPrimaryType(tSettleDomain.getBusinessPrimaryType());
						updateTEmployeePro.setBusinessSecondType(tSettleDomain.getBusinessSecondType());
						updateTEmployeePro.setBusinessThirdType(tSettleDomain.getBusinessThirdType());
						TCustomerInfo tCustomerInfo = tCustomerInfoService.getById(tSettleDomain.getCustomerId());
						if (Common.isNotNull(tCustomerInfo)) {
							updateTEmployeePro.setUnitId(tCustomerInfo.getId());
							updateTEmployeePro.setUnitNo(tCustomerInfo.getCustomerCode());
							updateTEmployeePro.setUnitName(tCustomerInfo.getCustomerName());
						}
						updateTEmployeePro.setChangeStartMonth(excel.getChangeStartMonth());
						updateTEmployeePro.setUnsettleDeal(CommonConstants.IS_NO_CHANGE);
						updateList.add(updateTEmployeePro);
						// 记录变更日志
						tEmployeeLogService.saveModificationRecord(CommonConstants.dingleDigitIntArray[1], "", tEmployeeProjectOld.getId(), tEmployeeProjectOld, updateTEmployeePro);
					}
				} else {
					errorMsg.add(MsgUtils.getMessage(ErrorCodes.PROJECT_PERSON_SEARCH_EXIT, excel.getOldSettleCode()));
				}
			}
			if (!CollUtil.isEmpty(errorMsg)) {
				errorMessageList.add(new ErrorMessage((long) (i + 2), errorMsg));
			}
		}

		if (CollUtil.isNotEmpty(errorMessageList)) {
			return R.failed(errorMessageList);
		} else {
			tEmployeeProjectService.updateBatchById(updateList);
			for (TEmployeeProject tEmployeeProject: updateList) {
				UpdateSocialFoundVo updateSocialFoundVo = new UpdateSocialFoundVo();
				updateSocialFoundVo.setEmpIdcard(tEmployeeProject.getEmpIdcard());
				updateSocialFoundVo.setSettleDomainCode(tEmployeeProject.getDeptNo());
				updateSocialFoundVo.setSettleDomainId(tEmployeeProject.getDeptId());
				updateSocialFoundVo.setUnitId(tEmployeeProject.getUnitId());
				updateSocialFoundVo.setUnitName(tEmployeeProject.getUnitName());
				updateSocialFoundVo.setSettleDomainName(tEmployeeProject.getDeptName());
				if (CommonConstants.IS_CHANGE.equals(tEmployeeProject.getUnsettleDeal())) {
					updateSocialFoundVo.setSocialCreateMonth(tEmployeeProject.getChangeStartMonth());
					socialDaprUtils.updatePaymentSocialAndFound(updateSocialFoundVo);
					socialDaprUtils.updateForSocialAndFound(updateSocialFoundVo);
				}
				if (CommonConstants.ZERO_INT != tEmployeeProject.getSocialStatus()) {
					updateSocialFoundVo.setFlag(CommonConstants.ZERO_STRING);
					socialDaprUtils.updateSocialAndFoundInfo(updateSocialFoundVo);
				}
				if (CommonConstants.ZERO_INT != tEmployeeProject.getFundStatus()) {
					updateSocialFoundVo.setFlag(CommonConstants.ONE_STRING);
					socialDaprUtils.updateSocialAndFoundInfo(updateSocialFoundVo);
				}
			}
		}
		return R.ok();
	}

	/**
	 * 获取所有项目名称
	 * @return R
	 * @Author huyc
	 * @Date 2022-06-22
	 * @param customerName
	 */
	@Override
	public R<List<TSettleDomain>> getAllDept(String customerName) {
		List<TSettleDomain> list = null;
		if (Common.isNotNull(customerName)){
			list = tSettleDomainMapper.selectList(Wrappers.<TSettleDomain>query().lambda().eq(TSettleDomain::getDeleteFlag, CommonConstants.STATUS_NORMAL)
					.eq(TSettleDomain::getStopFlag,CommonConstants.STATUS_NORMAL).eq(TSettleDomain::getCustomerName,customerName));
		}else {
			list = tSettleDomainMapper.selectList(Wrappers.<TSettleDomain>query().lambda().eq(TSettleDomain::getDeleteFlag, CommonConstants.STATUS_NORMAL)
					.eq(TSettleDomain::getStopFlag,CommonConstants.STATUS_NORMAL));
		}
		return R.ok(list);
	}

	/**
	 * 获取所有单位名称
	 * @return R
	 * @Author huyc
	 * @Date 2022-06-22
	 * @param customerName
	 */
	@Override
	public R<List<TCustomerInfo>> getAllUint(String customerName) {
		//List<TCustomerInfo> list = tCustomerInfoService.list(Wrappers.<TCustomerInfo>query().lambda().eq(TCustomerInfo::getDeleteFlag, CommonConstants.STATUS_NORMAL));
		List<TCustomerInfo> list = tCustomerInfoService.getAllUnit(customerName);
		return R.ok(list);
	}

	/**
	 * 分页获取所有项目名称
	 * @return R
	 * @Author huyc
	 * @Date 2022-07-26
	 */
	@Override
	public IPage<TSettleDomain> getAllDeptPage(Page page, String deptName, String customerId) {
		LambdaQueryWrapper<TSettleDomain> wrapper = buildQueryWrapper(deptName, customerId);
		return tSettleDomainMapper.selectPage(page,wrapper);
	}

	private LambdaQueryWrapper buildQueryWrapper(String deptName, String customerId) {
		LambdaQueryWrapper<TSettleDomain> wrapper = Wrappers.lambdaQuery();
		if (Common.isNotNull(deptName)) {
			wrapper.like(TSettleDomain::getDepartName, deptName);
		}
		if (Common.isNotNull(customerId)) {
			wrapper.eq(TSettleDomain::getCustomerId, customerId);
		}
		wrapper.eq(TSettleDomain::getDeleteFlag, CommonConstants.ZERO_STRING);
		wrapper.eq(TSettleDomain::getStopFlag, CommonConstants.ZERO_STRING);
		return wrapper;
	}
}
