package com.yifu.cloud.plus.v1.yifu.salary.util;

import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainSelectVo;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.SecurityConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.util.*;
import com.yifu.cloud.plus.v1.yifu.common.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.common.dapr.config.DaprSocialProperties;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.HttpDaprUtil;
import com.yifu.cloud.plus.v1.yifu.ekp.util.EkpSalaryUtil;
import com.yifu.cloud.plus.v1.yifu.ekp.vo.EkpSalaryBackParam;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TApprovalRecord;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryAccount;
import com.yifu.cloud.plus.v1.yifu.salary.entity.TSalaryStandard;
import com.yifu.cloud.plus.v1.yifu.salary.mapper.TSalaryStandardMapper;
import com.yifu.cloud.plus.v1.yifu.salary.service.TApprovalRecordService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TInsuranceUnpurchasePersonSalaryService;
import com.yifu.cloud.plus.v1.yifu.salary.service.TSalaryAccountService;
import com.yifu.cloud.plus.v1.yifu.social.entity.TIncome;
import com.yifu.cloud.plus.v1.yifu.social.entity.TIncomeDetail;
import com.yifu.cloud.plus.v1.yifu.social.entity.TSendEkpError;
import com.yifu.cloud.plus.v1.yifu.social.vo.TIncomeDetailReturnVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author hgw
 * @Date 2022-11-29 16:31:09
 * @Description 异步执行薪资
 */
@Slf4j
@Component
@AllArgsConstructor
@EnableConfigurationProperties({DaprSocialProperties.class})
public class DoJointSalaryAsyncTask {

	private final DaprSocialProperties socialProperties;
	private final TSalaryStandardMapper salaryStandardMapper;
	private final TSalaryAccountService tSalaryAccountService;
	private final RedisUtil redisUtil;

	private final TApprovalRecordService auditLogService;
	private final EkpSalaryUtil ekpSalaryUtil;
	private final TInsuranceUnpurchasePersonSalaryService tInsuranceUnpurchasePersonSalaryService;


	/**
	 * @Description: 收入
	 * @Author: hgw
	 * @Date: 2022-11-29 17:28:494
	 **/
	@Async
	public void doIncomeDetail(TSettleDomainSelectVo dept, List<TSalaryAccount> salaryAccountList, String id, TSalaryStandard tSalaryStandard) {
		log.info("推送收入到EKP-线程开始");

		if (salaryAccountList != null && !salaryAccountList.isEmpty()) {
			List<String> idCardList = new ArrayList<>();
			for (TSalaryAccount account : salaryAccountList) {
				idCardList.add(account.getEmpIdcard());
			}
			Map<String, Integer> detailMap = new HashMap<>();
			boolean isTrue = true;
			TSalaryStandard s = salaryStandardMapper.selectById(id);
			try {
				// 收入相关
				R<String> failed1 = getIncomeDetailMap(tSalaryStandard, dept, idCardList, detailMap);
				if (failed1 != null) {
					isTrue = false;
				} else {
					// 含有薪资，则计算收入
					// 管理费
					if (Common.isNotNull(dept.getManageServerItem()) && dept.getManageServerItem().contains(CommonConstants.FOUR_STRING) && CommonConstants.ZERO_STRING.equals(dept.getManagementTag())) {
						// 金额-人数
						if (CommonConstants.TWO_STRING.equals(dept.getManagementType())) {
							// 保存明细
							isTrue = saveIncomeDetail(salaryAccountList, tSalaryStandard, dept, detailMap, dept.getManagementType(), CommonConstants.ONE_STRING);
						} else {
							// 保存明细
							isTrue = saveIncomeDetail(salaryAccountList, tSalaryStandard, dept, new HashMap<>(), dept.getManagementType(), CommonConstants.ONE_STRING);
						}
					}
					// 风险金
					if (isTrue && Common.isNotNull(dept.getRiskServerItem()) && dept.getRiskServerItem().contains(CommonConstants.FOUR_STRING) && CommonConstants.ZERO_STRING.equals(dept.getRiskFundTag())) {
						// 金额-人数
						if (CommonConstants.TWO_STRING.equals(dept.getRiskFundType())) {
							// 保存明细
							isTrue = saveIncomeDetail(salaryAccountList, tSalaryStandard, dept, detailMap, dept.getRiskFundType(), CommonConstants.TWO_STRING);
						} else {
							// 保存明细
							isTrue = saveIncomeDetail(salaryAccountList, tSalaryStandard, dept, new HashMap<>(), dept.getRiskFundType(), CommonConstants.TWO_STRING);
						}
					}
				}
			} catch (Exception e) {
				isTrue = false;
				log.error(e.getMessage());
			}
			if (s != null && (s.getStatus() == CommonConstants.dingleDigitIntArray[11] || s.getStatus() == CommonConstants.dingleDigitIntArray[12])) {
				s.setIncomeEndTime(new Date());
				if (isTrue) {
					s.setStatus(CommonConstants.TWO_INT);
					salaryStandardMapper.updateById(s);
				} else {
					s.setStatus(CommonConstants.dingleDigitIntArray[12]);
					salaryStandardMapper.updateById(s);
				}
			}
		}

		log.info("推送收入到EKP结束");
	}

	/**
	 * @Description: 获取收入信息
	 * @Author: hgw
	 * @Date: 2022/9/6 10:39
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	private R<String> getIncomeDetailMap(TSalaryStandard tSalaryStandard, TSettleDomainSelectVo dept, List<String> idCardList, Map<String, Integer> detailMap) {
		TIncomeDetail detail = new TIncomeDetail();
		detail.setApplyNo(tSalaryStandard.getApplyNo());
		detail.setPayMonth(tSalaryStandard.getIncomeMonth());
		detail.setIdCardList(idCardList);
		detail.setDeptId(dept.getId());
		R<TIncomeDetailReturnVo> detailR = HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId(), "/tincomedetail/inner/getTIncomeDetailList", detail, TIncomeDetailReturnVo.class, SecurityConstants.FROM_IN);
		Integer value;
		if (detailR != null) {
			if (detailR.getData() != null && detailR.getData().getDetailList() != null && !detailR.getData().getDetailList().isEmpty()) {
				TIncomeDetailReturnVo vo = detailR.getData();
				List<TIncomeDetail> detailList = vo.getDetailList();
				for (TIncomeDetail incomeDetail : detailList) {
					value = detailMap.get(incomeDetail.getEmpIdcard() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getDeptId() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getFeeType() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getSourceType());
					if (Common.isEmpty(value)) {
						value = CommonConstants.ZERO_INT;
					}
					if (CommonConstants.ZERO_STRING.equals(incomeDetail.getRedData())) {
						value++;
					} else {
						value--;
					}
					detailMap.put(incomeDetail.getEmpIdcard() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getDeptId() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getFeeType() + CommonConstants.DOWN_LINE_STRING + incomeDetail.getSourceType(), value);
				}
			}
		} else {
			return R.failed("获取收入明细的详情出错，请联系管理员！");
		}
		return null;
	}

	/**
	 * @param feeType  1按比例2金额-人数3金额-人次
	 * @param isManage 1 管理费2 风险金
	 * @Description: 保存明细
	 * @Author: hgw
	 * @Date: 2022/9/2 17:25
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	private boolean saveIncomeDetail(List<TSalaryAccount> salaryAccountList, TSalaryStandard tSalaryStandard, TSettleDomainSelectVo dept, Map<String, Integer> detailMap, String feeType, String isManage) {
		TIncomeDetail detail;
		Integer value;
		BigDecimal money;
		String redisKey = String.valueOf(UUID.randomUUID()).replaceAll("-", "") + "_incomePush";
		for (TSalaryAccount account : salaryAccountList) {
			value = detailMap.get(account.getEmpIdcard() + CommonConstants.DOWN_LINE_STRING + account.getDeptId() + CommonConstants.DOWN_LINE_STRING + isManage + CommonConstants.DOWN_LINE_STRING + CommonConstants.FOUR_STRING);
			if (Common.isEmpty(value) || value == 0) {
				detail = new TIncomeDetail();
				detail.setRedisKey(redisKey);
				detail.setPayMonth(tSalaryStandard.getIncomeMonth());
				detail.setDeptId(account.getDeptId());
				detail.setDeptName(account.getDeptName());
				detail.setDeptNo(account.getDeptNo());
				detail.setUnitId(tSalaryStandard.getUnitId());
				detail.setUnitName(tSalaryStandard.getUnitName());
				detail.setUnitNo(tSalaryStandard.getUnitNo());
				detail.setCreateMonth(tSalaryStandard.getSettlementMonth());
				detail.setEmpIdcard(account.getEmpIdcard());
				detail.setEmpName(account.getEmpName());
				detail.setFeeMode(dept.getManagementType());
				detail.setFeeType(isManage);
				detail.setCharges(String.valueOf(dept.getManagementFee()));
				money = dept.getManagementFee();
				if (CommonConstants.TWO_STRING.equals(isManage)) {
					money = dept.getRiskFundFee();
					detail.setCharges(String.valueOf(dept.getRiskFundFee()));
					detail.setFeeMode(dept.getRiskFundType());
				}
				if (CommonConstants.ONE_STRING.equals(feeType)) {
					money = BigDecimalUtils.safeMultiply(account.getRelaySalary(), money, CommonConstants.ONE_OF_PERCENT);
				}
				detail.setMoney(money);
				detail.setMrSettleType(dept.getMrSettleType());
				detail.setRedData(CommonConstants.ZERO_STRING);
				detail.setSourceId(account.getId());
				detail.setSourceType(CommonConstants.FOUR_STRING);
				detail.setApplyNo(tSalaryStandard.getApplyNo());
				R<Boolean> saveR = HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId(), "/tincome/inner/saveSalaryDetail", detail, Boolean.class, SecurityConstants.FROM_IN);
				if (saveR == null || saveR.getCode() == CommonConstants.ONE_INT || Boolean.FALSE.equals(saveR.getData())) {
					return false;
				}
			}
		}
		//推送失败的数据重新推送
		if (Common.isNotNull(redisUtil.get(redisKey))) {
			List<TIncome> list = (List<TIncome>) redisUtil.get(redisKey);
			for (TIncome income : list) {
				R<Boolean> saveR = HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId(), "/tincome/inner/saveSalaryPushIncome", income, Boolean.class, SecurityConstants.FROM_IN);
				if (saveR == null || saveR.getCode() == CommonConstants.ONE_INT || Boolean.FALSE.equals(saveR.getData())) {
					return false;
				}
			}
			redisUtil.remove(redisKey);
		}
		return true;
	}

	/**
	 * @param applyNo
	 * @param ss
	 * @Description: 异步-薪资退表
	 * @Author: hgw
	 * @Date: 2023/8/2 16:56
	 * @return: void
	 **/
	@Async
	public void doBackSalary(String applyNo, TSalaryStandard ss, YifuUser user) {
		EkpSalaryBackParam param = new EkpSalaryBackParam();
		param.setFd_3b3c293745e7b4(ss.getDeptName());
		param.setFd_3b3c2935c13056(ss.getDeptNo());
		param.setFd_3b3c293811c0ee(ss.getApplyNo());
		if (user != null) {
			param.setFd_3b422d73d73e02(user.getUsername());
		} else {
			param.setFd_3b422d73d73e02("");
		}
		String sendBack = ekpSalaryUtil.backStandardToEKP(param);
		if (Common.isEmpty(sendBack) || sendBack.length() != 32) {
			sendBack = ekpSalaryUtil.backStandardToEKP(param);
		}
		if (Common.isNotNull(sendBack) && sendBack.length() == 32) {
			// 删除不购买商险的关联项
			if (Common.isNotNull(ss.getIsCheckRisk()) && ss.getIsCheckRisk() == CommonConstants.ONE_INT) {
				tInsuranceUnpurchasePersonSalaryService.deletePersonSalaryBySalaryId(ss.getId());
				ss.setIsCheckRisk(CommonConstants.ZERO_INT);
			}
			// 更新薪资为确认不通过
			ss.setStatus(SalaryConstants.STATUS[6]);
			ss.setSendMonth(null);
			ss.setSendTime(null);
			ss.setBackTime(new Date());
			ss.setBackEkpId(sendBack);
			salaryStandardMapper.updateById(ss);
			// 更新报账表
			tSalaryAccountService.backSalaryBySalaryId(ss.getId());
			TIncome income = new TIncome();
			income.setApplyNo(applyNo);
			// 删除收入对应编号的明细
			HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId(), "/tincome/inner/deleteIncomeAndDetailByApplyNo", income, Object.class, SecurityConstants.FROM_IN);
			// 添加流程进展明细
			if (user != null) {
				ss.setRemark(" ");
				this.saveRecordLog(ss, user, CommonConstants.ZERO_STRING, "从EKP退表");
			}
		} else {
			TSendEkpError error = new TSendEkpError();
			error.setCreateTime(new Date());
			error.setCreateDay(DateUtil.getThisDay());
			error.setType(CommonConstants.SEVEN_STRING);
			error.setCreateUserName(ss.getCreateName());
			error.setLinkId(ss.getId());
			error.setTitle(sendBack == null ? ss.getId() + "：" + SalaryConstants.EKP_NO_RETURN : ss.getId() + "：" + sendBack);
			error.setNums(CommonConstants.ONE_INT);
			HttpDaprUtil.invokeMethodPost(socialProperties.getAppUrl(), socialProperties.getAppId(), "/tsendekperror/inner/saveError", error, Boolean.class, SecurityConstants.FROM_IN);
		}
	}

	/**
	 * @param tSalaryStandard
	 * @param user
	 * @param status
	 * @param nodeId
	 * @Description: 流程进展明细
	 * @Author: hgw
	 * @Date: 2023/8/2 16:48
	 * @return: void
	 **/
	public void saveRecordLog(TSalaryStandard tSalaryStandard, YifuUser user, String status, String nodeId) {
		TApprovalRecord tApprovalRecord = new TApprovalRecord();
		tApprovalRecord.setApprovalResult(status);
		tApprovalRecord.setApprovalOpinion(tSalaryStandard.getRemark());
		tApprovalRecord.setSalaryId(tSalaryStandard.getId());
		tApprovalRecord.setNodeId(nodeId);
		tApprovalRecord.setApprovalMan(user.getId());
		tApprovalRecord.setApprovalManName(user.getNickname());
		tApprovalRecord.setApprovalTime(DateUtil.getCurrentDateTime());
		auditLogService.save(tApprovalRecord);
	}

}
