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

import com.yifu.cloud.plus.v1.yifu.archives.entity.TSettleDomain;
import com.yifu.cloud.plus.v1.yifu.archives.vo.TSettleDomainListVo;
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.util.BigDecimalUtils;
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.R;
import com.yifu.cloud.plus.v1.yifu.common.dapr.util.ArchivesDaprUtil;
import com.yifu.cloud.plus.v1.yifu.social.entity.TForecastLibrary;
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.entity.TSocialFundInfo;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSendEkpErrorMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author fxj
 * @Date 2022/11/28
 * @Description  批量办理异步处理
 * @Version 1.0
 */
@Slf4j
@Component
public class DoSocialTask {
	@Autowired
	private TForecastLibraryService forecastLibraryService;

	@Autowired
	private TIncomeDetailService detailService;

	@Autowired
	private ArchivesDaprUtil archivesDaprUtil;

	@Autowired
	private TIncomeService incomeService;

	@Autowired
	private TSendEkpErrorMapper sendEkpErrorMapper;

	@Autowired
	private TSocialSoldierPushService tSocialSoldierPushService;

	@Autowired
	private TSocialFriendPushService tSocialFriendPushService;
	/**
	 * @Author fxj
	 * @Description 异步处理相关信息
	 * @Date 11:23 2022/11/28
	 * @param type=0 updateForecastLibaryByDispatchReduce   type=1 updateForecastLibaryByDispatch  type=2 pushForecastFundInfo   createIncomeInfo(library);
	 **/
	@Async
	public void asynchronousDisPatchHandle(ConcurrentHashMap<String, String> socialMap, ConcurrentHashMap<String, String> fundMap, TSocialFundInfo sf, int forecastFlag, List< TForecastLibrary > libs, TForecastLibrary library, int type) {
		synchronized (this){
			R<String> res;
			String linkId = null;
			try {
				// 派单减少变更预估库-派减
				if (type == CommonConstants.ZERO_INT){
					linkId = sf.getId();
					res = forecastLibraryService.updateForecastLibaryByDispatchReduce(sf, forecastFlag);
					if (Common.isEmpty(res) || CommonConstants.SUCCESS != res.getCode()){
						initSendError(library.getId(), res.getMsg(),"updateForecastLibaryByDispatchReduce:");
					}
				}
				// 派单变更预估库
				if (type == CommonConstants.ONE_INT){
					linkId = sf.getId();
					res  = forecastLibraryService.updateForecastLibaryByDispatch(socialMap,fundMap,sf);
					if (Common.isEmpty(res) || CommonConstants.SUCCESS != res.getCode()){
						initSendError(sf.getId(), res.getMsg(),"updateForecastLibaryByDispatch:");
					}
				}
				// 获取预估库数据并推送
				if (type == CommonConstants.TWO_INT){
					if (Common.isNotNull(libs)){
						for (TForecastLibrary lib:libs){
							if (Common.isEmpty(linkId)){
								linkId = lib.getId();
							}else {
								linkId = linkId + CommonConstants.COMMA_CHAR + lib.getId();
							}
						}
					}
					forecastLibraryService.pushForecastFundInfo(libs,false,null);
				}
				// 获取预估库数据生成收入并推送
				if (type == CommonConstants.THREE_INT){
					linkId = library.getId();
					createIncomeInfo(library);
				}
			}catch (Exception e){
				initSendError(linkId, e.getMessage(),"asynchronousDisPatchHandle:");
			}
		}
	}

	/**
	 * @Author fxj
	 * @Description 异步处理相关信息 公积金同事生成收入和预估并推送
	 * @Date 11:23 2022/11/28
	 * @param library 生成预估推送   libForIncome  生成收入推送
	 **/
	@Async
	public void asynchronousDisPatchHandleForDispatch(TForecastLibrary library,boolean foreFlag) {
		synchronized (this){
			List<TForecastLibrary> libs = new ArrayList<>();
			String linkId = null;
			try {
				if (Common.isNotNull(library)){
					// 获取预估库数据并推送
					if (foreFlag){
						libs.add(library);
						for (TForecastLibrary lib:libs){
							if (Common.isEmpty(linkId)){
								linkId = lib.getId();
							}else {
								linkId = linkId + CommonConstants.COMMA_CHAR + lib.getId();
							}
						}
						forecastLibraryService.pushForecastFundInfo(libs,false,null);
					}
					// 获取预估库数据生成收入并推送
					linkId = library.getId();
					createIncomeInfo(library);
				}
			}catch (Exception e){
				initSendError(linkId, e.getMessage(),"asynchronousDisPatchHandle:");
			}finally {
				libs.clear();
			}
		}
	}

	private void initSendError(String linkId, String msg,String title) {
		TSendEkpError error = new TSendEkpError();
		error.setCreateTime(new Date());
		error.setCreateDay(DateUtil.getThisDay());
		error.setType(CommonConstants.TWO_STRING);
		error.setCreateUserName("社保预估费用推送");
		error.setLinkId(linkId);
		error.setTitle(title+ msg);
		error.setNums(CommonConstants.ONE_INT);
		this.saveError(error);
		log.error("推送社保预估费用到EKP错误", msg);
	}

	private boolean saveError(TSendEkpError tSendEkpError) {
		// 类型、创建日不可为空
		if (Common.isEmpty(tSendEkpError.getType()) || Common.isEmpty(tSendEkpError.getCreateDay())) {
			return false;
		}
		TSendEkpError error = sendEkpErrorMapper.getByTitleTypeDay(tSendEkpError);
		if (error == null) {
			return sendEkpErrorMapper.insert(tSendEkpError) > 0;
		} else {
			if (Common.isEmpty(tSendEkpError.getNums())) {
				tSendEkpError.setNums(CommonConstants.ONE_INT);
			}
			error.setNums(error.getNums() + tSendEkpError.getNums());
			return sendEkpErrorMapper.updateById(error) >= 0;
		}
	}
	public void createIncomeInfo(TForecastLibrary library) {
		//获取项目信息
		TSettleDomain settleDomain = new TSettleDomain();
		List<TSettleDomainSelectVo> settleDomainR = null;
		R<TSettleDomainListVo> listVo = null;
		listVo = archivesDaprUtil.selectSettleDomainSelectVoById(library.getSettleDomainId());
		if (Common.isNotNull(listVo)) {
			TSettleDomainListVo tSettleDomainListVo = listVo.getData();
			if (Common.isNotNull(tSettleDomainListVo) && Common.isNotEmpty(tSettleDomainListVo.getListSelectVO())) {
				settleDomainR = tSettleDomainListVo.getListSelectVO();
				for (TSettleDomainSelectVo vo :settleDomainR) {
					BeanUtils.copyProperties(vo,settleDomain);
				}
			}
		}

		//判断是否存在当月的公积金收入数据
		boolean isExist = false;
		TIncomeDetail incomeDetail = new TIncomeDetail();
		incomeDetail.setEmpIdcard(library.getEmpIdcard());
		incomeDetail.setPayMonth(library.getProvidentPayMonth());
		incomeDetail.setDeptNo(library.getDeptNo());
		incomeDetail.setSourceType(CommonConstants.TWO_STRING);
		List<TIncomeDetail> detailList = detailService.getTIncomeDetailList(incomeDetail);
		if (Common.isNotNull(detailList)) {
			BigDecimal sumMoney = BigDecimal.ZERO;
			for (TIncomeDetail income : detailList) {
				sumMoney = BigDecimalUtils.safeAdd(income.getMoney(),sumMoney);
			}
			if (sumMoney.compareTo(BigDecimal.ZERO) > 0) {
				isExist = true;
			}
		}

		if (Common.isNotNull(settleDomain)) {
			// 含有社保，则计算收入
			if (Common.isNotNull(settleDomain.getManageServerItem()) && settleDomain.getManageServerItem()
					.contains(CommonConstants.TWO_STRING) && !isExist &&
					CommonConstants.ZERO_STRING.equals(settleDomain.getManagementTag()) &&
					CommonConstants.ONE_STRING.equals(settleDomain.getMrSettleType())) {
				//预估模式
				//预估模式只有按人次和人数收费
				createIncomeInsurance(library, settleDomain, CommonConstants.ONE_STRING,
						settleDomain.getManagementFee().toString(), settleDomain.getManagementType(),
						settleDomain.getManagementFee());
			}
			if (Common.isNotNull(settleDomain.getRiskServerItem()) && settleDomain.getRiskServerItem()
					.contains(CommonConstants.TWO_STRING) && !isExist &&
					CommonConstants.ZERO_STRING.equals(settleDomain.getRiskFundTag()) &&
					CommonConstants.ONE_STRING.equals(settleDomain.getMrSettleType())) {
				//预估模式
				createIncomeInsurance(library, settleDomain, CommonConstants.TWO_STRING,
						settleDomain.getRiskFundFee().toString(), settleDomain.getRiskFundType(),
						settleDomain.getRiskFundFee());
			}
		}
	}

	public void createIncomeInsurance(TForecastLibrary library, TSettleDomain settleDomain, String feeType,
									  String charges, String feeMode, BigDecimal money) {
		//生成收入数据
		TIncomeDetail detail = new TIncomeDetail();
		detail.setCreateTime(DateUtil.getCurrentDateTime());
		detail.setDeptName(settleDomain.getDepartName());
		detail.setDeptNo(settleDomain.getDepartNo());
		detail.setDeptId(settleDomain.getId());
		detail.setEmpIdcard(library.getEmpIdcard());
		detail.setEmpName(library.getEmpName());
		detail.setUnitNo(settleDomain.getCustomerNo());
		detail.setUnitId(settleDomain.getCustomerId());
		detail.setUnitName(settleDomain.getCustomerName());
		detail.setDataCreateMonth(DateUtil.addMonth(0));
		detail.setSourceId(library.getId());
		detail.setSourceType(CommonConstants.TWO_STRING);
		detail.setCreateMonth(library.getProvidentCreateMonth());
		detail.setPayMonth(library.getProvidentPayMonth());
		detail.setMoney(money);
		detail.setFeeType(feeType);
		detail.setFeeMode(feeMode);
		detail.setCharges(charges);
		detail.setMrSettleType(settleDomain.getMrSettleType());
		detail.setRedData(CommonConstants.ZERO_STRING);
		detail.setId(CommonConstants.NULL);

		// 批量办理成功 收入不异步推送
		incomeService.saveDetail(detail,false);
	}
	/**
	 * @Author fxj
	 * @Description 单个或批量审核 异步调用自动化派单任务
	 * @Date 11:22 2024/5/13
	 * @Param
	 * @return
	**/
	@Async
	public void pushSoldier(String dispatchId, boolean isFriend, String isSingleAudit) {
		List<String> dispatchIdList = new ArrayList<>();
		dispatchIdList.add(dispatchId);
		try {
			Thread.sleep(60000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		// 当前默认 安徽省 ，且开关是税友的，才可以税友推送办理
		if (isFriend) {
			// 断开派单单条推送税友
			// 单个审核接口并且户类型为单个，即时推送税友
			if (CommonConstants.ONE_STRING.equals(isSingleAudit)) {
				tSocialFriendPushService.pushFriend(dispatchIdList);
			}
		} else {
			tSocialSoldierPushService.pushSoldier(dispatchIdList);
		}
	}
}
