/*
 *    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.social.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
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.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.core.vo.YifuUser;
import com.yifu.cloud.plus.v1.yifu.social.config.SocialFriendConfig;
import com.yifu.cloud.plus.v1.yifu.social.entity.*;
import com.yifu.cloud.plus.v1.yifu.social.mapper.TSocialFriendMapper;
import com.yifu.cloud.plus.v1.yifu.social.service.*;
import com.yifu.cloud.plus.v1.yifu.social.vo.FriendResult;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 税友
 *
 * @author hgw
 * @date 2024-5-8 14:55:36
 */
@AllArgsConstructor
@Log4j2
@Service
public class TSocialFriendServiceImpl extends ServiceImpl<TSocialFriendMapper, TSocialInfo> implements TSocialFriendService {

	private RestTemplate restTemplate = new RestTemplate();
	private final SocialFriendConfig socialFriendConfig;
	private final TDispatchInfoService tDispatchInfoService;
	private final TSocialInfoService tSocialInfoService;
	private final FailReasonConfigService failReasonConfigService;
	private final TAuditInfoService tAuditInfoService;
	private final TSocialSoldierLogService tSocialSoldierLogService;
	private final TSocialFriendBackLogService tSocialFriendBackLogService;
	private final TSocialFreindSetService tSocialFreindSetService;
	private final AtomicInteger atomicGetFriend = new AtomicInteger(0);

	/**
	 * @Description: 5 查看任务进度
	 * @Author: hgw
	 * @Date: 2024/5/11 15:08
	 * @return: com.yifu.cloud.plus.v1.yifu.common.core.util.R<java.lang.String>
	 **/
	@Override
	public R<String> getInfoByRequestId() {
		if (atomicGetFriend.incrementAndGet() <= 1) {
			try {
				TSocialFreindSet set = tSocialFreindSetService.getById("1");
				if (set != null && Common.isNotNull(set.getType()) && 1 == set.getType()) {
					// true养工失 false 医生大
					boolean typeFlag = true;
					Set<String> dbAuthsSet = new HashSet<>();
					Collection<? extends GrantedAuthority> authorities = AuthorityUtils
							.createAuthorityList(dbAuthsSet.toArray(new String[0]));
					YifuUser user = new YifuUser("1", 1L, "", "税友",
							"税友", "0", SecurityConstants.BCRYPT + "123456",
							"12345678911", true, true, true,
							true,
							"1", authorities, "1",
							null, null,
							null, null);
					// 失败原因配置
					Map<String, FailReasonConfig> errorMap = failReasonConfigService.getFailReasonMap();
					// 获取所有需要反馈的任务id
					List<TSocialInfo> socialList = tSocialInfoService.getSocialFriendYgsAll();
					List<TSocialFriendBackLog> logList;
					TSocialFriendBackLog backLog = new TSocialFriendBackLog();
					FriendResult info;
					List<FriendResult> resultList;
					Map<String, FriendResult> resultMap;
					String key;
					if (socialList != null && !socialList.isEmpty()) {
						logList = new ArrayList<>();
						resultMap = new HashMap<>();
						for (TSocialInfo socialInfo : socialList) {
							key = socialInfo.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+socialInfo.getYgsRequestId();
							info = resultMap.get(key);
							if (info == null) {
								backLog = new TSocialFriendBackLog();
								backLog.setSocialId(socialInfo.getEmpIdcard());
								backLog.setRequestId(socialInfo.getYgsRequestId());
								backLog.setType(11);
								if (Common.isNotNull(socialInfo.getDispatchType()) && CommonConstants.ONE_STRING.equals(socialInfo.getDispatchType())) {
									backLog.setType(12);
								}
								resultList = socialFriendConfig.getFriendByRequestId(restTemplate, socialInfo.getYgsRequestId()
										, backLog, socialInfo.getDispatchType());
								logList.add(backLog);
								if (resultList != null && !resultList.isEmpty()) {
									for (FriendResult result : resultList) {
										resultMap.put(result.getIdCard()+CommonConstants.DOWN_LINE_STRING+socialInfo.getYgsRequestId(), result);
									}
									info = resultMap.get(key);
								}
							} else {
								backLog.setSocialId(backLog.getSocialId() + "," +socialInfo.getEmpIdcard());
							}
							if (info != null && Common.isNotNull(info.getZt())) {
								doCore(info, socialInfo, typeFlag, user, errorMap);
							}
						}
						if (!logList.isEmpty()) {
							tSocialFriendBackLogService.saveBatch(logList);
						}
					}
					// 医保
					typeFlag = false;
					List<TSocialInfo> socialYsdList = tSocialInfoService.getSocialFriendYsdAll();
					if (socialYsdList != null && !socialYsdList.isEmpty()) {
						logList = new ArrayList<>();
						resultMap = new HashMap<>();
						backLog = new TSocialFriendBackLog();
						for (TSocialInfo socialInfo : socialYsdList) {
							key = socialInfo.getEmpIdcard()+CommonConstants.DOWN_LINE_STRING+socialInfo.getYsdRequestId();
							info = resultMap.get(key);
							if (info == null) {
								backLog = new TSocialFriendBackLog();
								backLog.setSocialId(socialInfo.getEmpIdcard());
								backLog.setRequestId(socialInfo.getYsdRequestId());
								backLog.setType(13);
								if (Common.isNotNull(socialInfo.getDispatchType()) && CommonConstants.ONE_STRING.equals(socialInfo.getDispatchType())) {
									backLog.setType(14);
								}
								resultList = socialFriendConfig.getFriendByRequestId(restTemplate, socialInfo.getYsdRequestId()
										, backLog, socialInfo.getDispatchType());
								if (resultList != null && !resultList.isEmpty()) {
									for (FriendResult result : resultList) {
										resultMap.put(result.getIdCard()+CommonConstants.DOWN_LINE_STRING+socialInfo.getYsdRequestId(), result);
									}
									info = resultMap.get(key);
								}
								logList.add(backLog);
							} else {
								backLog.setSocialId(backLog.getSocialId() + "," +socialInfo.getEmpIdcard());
							}
							if (info != null && Common.isNotNull(info.getZt())) {
								doCore(info, socialInfo, typeFlag, user, errorMap);
							}
						}
						if (!logList.isEmpty()) {
							tSocialFriendBackLogService.saveBatch(logList);
						}
					}
				}
			} finally {
				atomicGetFriend.decrementAndGet();
			}
			return R.ok();
		} else {
			atomicGetFriend.decrementAndGet();
			return R.failed("距离上一次获取任务时间间隔太短，请10分钟后再试！！！");
		}
	}

	/**
	 * @Description: 核心信息
	 * @Author: hgw
	 * @Date: 2024/12/12 17:46
	 * @return: void
	 **/
	private void doCore(FriendResult info, TSocialInfo socialInfo, boolean typeFlag, YifuUser user
			, Map<String, FailReasonConfig> errorMap) {
		// 个性化校验逻辑
		// 执行数据插入操作 组装
		TSocialInfo updateSocial;
		FailReasonConfig failConfig;
		String auditRemark;
		String ygsHandleStatus;
		String ysdHandleStatus;
		// 养工失办理成功的单子
		List<String> ygsList = new ArrayList<>();
		// 养工失办理失败的单子
		List<String> ygsFailList = new ArrayList<>();
		// 医生大办理成功的单子
		List<String> ysdList = new ArrayList<>();
		// 医生大办理失败的单子
		List<String> ysdFailList = new ArrayList<>();

		// 处理社保办理成功后的状态同步-成功
		String typeSub = CommonConstants.ZERO_STRING;
		String handleStatus;
		String title;
		String handleRemark = null;
		String remark = null;
		String socialType;
		// 记录日志
		TSocialSoldierLog socialLog;
		// 初始化继续办理
		ygsHandleStatus = CommonConstants.TWO_STRING;
		ysdHandleStatus = CommonConstants.TWO_STRING;
		title = "社保";

		updateSocial = new TSocialInfo();
		auditRemark = info.getCwxx();
		if (typeFlag && (CommonConstants.ONE_STRING.equals(socialInfo.getYgsHandleStatus())
				|| CommonConstants.TWO_STRING.equals(socialInfo.getYgsHandleStatus())
				|| CommonConstants.THREE_STRING.equals(socialInfo.getYgsHandleStatus()))) {
			updateSocial.setId(socialInfo.getId());
			// 空、待审核、撤回或作废数据、审核不通过、审核通过
			if (CommonConstants.TWO_STRING.equals(info.getZt())) {
				ygsHandleStatus = CommonConstants.SIX_STRING;
				ygsList = new ArrayList<>();
				ygsList.add(socialInfo.getDispatchId());
				handleRemark = "税友自动办理成功！";
				remark = handleRemark;
				updateSocial.setYgsRemark(handleRemark);
				updateSocial.setYgsRemarkOld(auditRemark);
			} else if (CommonConstants.THREE_STRING.equals(info.getZt())) {
				// 如果找到了失败原因配置：
				failConfig = getConfig(auditRemark, errorMap);
				if (failConfig != null) {
					updateSocial.setYgsRemark(failConfig.getSimpleReason());
					// failConfig.getReplay() 1 继续办理 2 中止办理 3 人工办理
					// setYgsHandleStatus 3继续办理、4终止办理、5人工处理
					if (CommonConstants.ONE_STRING.equals(failConfig.getReplay())) {
						ygsHandleStatus = CommonConstants.THREE_STRING;
						// 新增流程进展明细
						if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
							title += "派增";
						} else {
							title += "派减";
						}
						title += "养老、工伤、失业办理不通过！继续办理：" + failConfig.getSimpleReason();
						this.doSocialTAuditInfo(socialInfo, title, title, failConfig.getSimpleReason(), user);
					} else if (CommonConstants.TWO_STRING.equals(failConfig.getReplay())) {
						ygsHandleStatus = CommonConstants.FOUR_STRING;
						ygsFailList = new ArrayList<>();
						ygsFailList.add(socialInfo.getDispatchId());
						handleRemark = "中止办理：" + failConfig.getSimpleReason();
						remark = handleRemark;
					} else if (CommonConstants.THREE_STRING.equals(failConfig.getReplay())) {
						ygsHandleStatus = CommonConstants.FIVE_STRING;

						// 新增流程进展明细
						if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
							title += "派增";
						} else {
							title += "派减";
						}
						title += "养老、工伤、失业办理不通过！人工处理：" + failConfig.getSimpleReason();
						this.doSocialTAuditInfo(socialInfo, title, title, failConfig.getSimpleReason(), user);
					}
				} else {
					handleRemark = "税友办理不通过转人工处理！";
					remark = auditRemark;
					handleRemark += remark;
					updateSocial.setYgsRemark(handleRemark);
					updateSocial.setYgsRemarkOld(auditRemark);
					ygsHandleStatus = CommonConstants.FIVE_STRING;
					// 新增流程进展明细
					if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
						title += "派增";
					} else {
						title += "派减";
					}
					title += "养老、工伤、失业" + handleRemark;
					this.doSocialTAuditInfo(socialInfo, title, title, title, user);
				}
			}
			updateSocial.setYgsHandleStatus(ygsHandleStatus);
			// 拉取审核结果，加日志
			if (Common.isNotNull(ygsHandleStatus)) {
				socialLog = tSocialSoldierLogService.getSocialFriendLog(socialInfo, "拉取", "社保"
						, getStatusName(Integer.parseInt(ygsHandleStatus)));
				tSocialSoldierLogService.save(socialLog);
			}
		} else if (!typeFlag && (CommonConstants.ONE_STRING.equals(socialInfo.getYsdHandleStatus())
				|| CommonConstants.TWO_STRING.equals(socialInfo.getYsdHandleStatus())
				|| CommonConstants.THREE_STRING.equals(socialInfo.getYsdHandleStatus()))) {
			title = "医保";
			updateSocial.setId(socialInfo.getId());
			// 空、待审核、撤回或作废数据、审核不通过、审核通过
			if (CommonConstants.TWO_STRING.equals(info.getZt())) {
				ysdHandleStatus = CommonConstants.SIX_STRING;
				ysdList.add(socialInfo.getDispatchId());
				handleRemark = "税友自动办理成功！";
				remark = handleRemark;
				updateSocial.setYsdRemark(handleRemark);
				updateSocial.setYsdRemarkOld(auditRemark);
			} else if (CommonConstants.THREE_STRING.equals(info.getZt())) {

				// 如果找到了失败原因配置：
				failConfig = getConfig(auditRemark, errorMap);
				if (failConfig != null) {
					updateSocial.setYsdRemark(failConfig.getSimpleReason());
					// failConfig.getReplay() 1 继续办理 2 中止办理 3 人工办理
					// ysdHandleStatus 3继续办理、4终止办理、5人工处理
					if (CommonConstants.ONE_STRING.equals(failConfig.getReplay())) {
						// 医保起缴月顺延：
						if ("已核定过基本医疗保险".equals(failConfig.getReasonKey())) {
							Date nextDate;
							Date nextMonth = DateUtil.addMonthByDate(new Date(), CommonConstants.ONE_INT);
							if (Common.isNotNull(socialInfo.getYsdSocialStartDateNext())) {
								nextDate = DateUtil.addMonthByDateToOne(socialInfo.getYsdSocialStartDateNext(), CommonConstants.ONE_INT);
								if (nextDate.before(nextMonth)) {
									updateSocial.setYsdSocialStartDateNext(nextDate);
								}
							} else if (Common.isNotNull(socialInfo.getSocialStartDate())) {
								nextDate = DateUtil.addMonthByDateToOne(socialInfo.getSocialStartDate(), CommonConstants.ONE_INT);
								if (nextDate.before(nextMonth)) {
									updateSocial.setYsdSocialStartDateNext(nextDate);
								}
							}
						}
						ysdHandleStatus = CommonConstants.THREE_STRING;

						// 新增流程进展明细
						if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
							title += "派增";
						} else {
							title += "派减";
						}
						title += "医疗、生育、大病办理不通过！继续办理：" + failConfig.getSimpleReason();
						this.doSocialTAuditInfo(socialInfo, title, title, failConfig.getSimpleReason(), user);
					} else if (CommonConstants.TWO_STRING.equals(failConfig.getReplay())) {
						ysdHandleStatus = CommonConstants.FOUR_STRING;
						ysdFailList.add(socialInfo.getDispatchId());
						handleRemark = "中止办理：" + failConfig.getSimpleReason();
						remark = handleRemark;
					} else if (CommonConstants.THREE_STRING.equals(failConfig.getReplay())) {
						ysdHandleStatus = CommonConstants.FIVE_STRING;
						// 新增流程进展明细
						if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
							title += "派增";
						} else {
							title += "派减";
						}
						title += "医疗、生育、大病办理不通过！人工处理：" + failConfig.getSimpleReason();
						this.doSocialTAuditInfo(socialInfo, title, title, failConfig.getSimpleReason(), user);
					}
				} else {
					handleRemark = "税友办理不通过转人工处理！";
					remark = auditRemark;
					handleRemark += remark;
					updateSocial.setYsdRemark(handleRemark);
					updateSocial.setYsdRemarkOld(auditRemark);
					ysdHandleStatus = CommonConstants.FIVE_STRING;
					// 新增流程进展明细
					if (CommonConstants.ZERO_STRING.equals(socialInfo.getDispatchType())) {
						title += "派增";
					} else {
						title += "派减";
					}
					title += "医疗、生育、大病" + handleRemark;
					this.doSocialTAuditInfo(socialInfo, title, title, title, user);
				}
			}
			updateSocial.setYsdHandleStatus(ysdHandleStatus);

			// 拉取审核结果，加日志
			if (Common.isNotNull(ysdHandleStatus)) {
				socialLog = tSocialSoldierLogService.getSocialFriendLog(socialInfo, "拉取", "医保"
						, getStatusName(Integer.parseInt(ysdHandleStatus)));
				tSocialSoldierLogService.save(socialLog);
			}
		}
		// 处理社保办理成功或失败，
		if (Common.isNotNull(updateSocial.getId())) {
			tSocialInfoService.updateById(updateSocial);
		}
		handleStatus = CommonConstants.ONE_STRING;

		// 处理社保办理成功后的状态同步-成功
		if (!ygsList.isEmpty()) {
			socialType = "1,4,3";
			this.doSocialAndDispatch(ygsList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
		if (!ysdList.isEmpty()) {
			socialType = "2,5,6";
			this.doSocialAndDispatch(ysdList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
		// 处理社保办理成功后的状态同步-失败
		handleStatus = CommonConstants.TWO_STRING;
		if (!ygsFailList.isEmpty()) {
			socialType = "1,4,3";
			this.doSocialAndDispatch(ygsFailList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
		if (!ysdFailList.isEmpty()) {
			socialType = "2,5,6";
			this.doSocialAndDispatch(ysdFailList, typeSub, handleStatus, handleRemark, socialType, remark, user);
		}
	}


	/**
	 * @param status
	 * @Description: 返回对应文字
	 * @Author: hgw
	 * @Date: 2024/9/2 19:38
	 * @return: java.lang.String
	 **/
	private String getStatusName(int status) {
		String[] arr = {"空", "待办理", "自动办理中", "继续办理", "中止办理", "人工处理", "成功", "提交成功"};
		return arr[status];
	}

	/**
	 * @Description: 查找失败原因的关键字
	 * @Author: hgw
	 * @Date: 2024/5/14 17:55
	 * @return: com.yifu.cloud.plus.v1.yifu.social.entity.FailReasonConfig
	 **/
	private FailReasonConfig getConfig(String msg, Map<String, FailReasonConfig> errorMap) {
		if (errorMap != null && Common.isNotNull(msg)) {
			FailReasonConfig configTemp;
			FailReasonConfig configReturn;
			for (Map.Entry<String, FailReasonConfig> config : errorMap.entrySet()) {
				if (msg.contains(config.getKey())) {
					configTemp = config.getValue();
					// 有截取且截取左右标识都在：
					if (Common.isNotNull(configTemp.getIsReplace())
							&& CommonConstants.ONE_STRING.equals(configTemp.getIsReplace())
							&& Common.isNotNull(configTemp.getReplaceLeft())
							&& Common.isNotNull(configTemp.getReplaceRight())
					) {
						String[] leftRes = msg.split(configTemp.getReplaceLeft());
						if (leftRes.length > 1) {
							String result = null;
							for (int i = 1; i < leftRes.length; i++) {
								if (leftRes[i].contains(configTemp.getReplaceRight())) {
									String[] rightRes = leftRes[i].split(configTemp.getReplaceRight());
									result = rightRes[0];
									break;
								}
							}
							if (Common.isNotNull(result) && leftRes.length > 2
									&& configTemp.getReplaceLeft().equals(configTemp.getReplaceRight())) {
								result = leftRes[1];
							}
							if (Common.isNotNull(result)) {
								configReturn = new FailReasonConfig();
								BeanUtil.copyProperties(configTemp, configReturn);
								configReturn.setSimpleReason(configReturn.getSimpleReason()
										+ configReturn.getReplaceLeft() + result + configReturn.getReplaceRight());
								return configReturn;
							}
						}
					}
					return configTemp;
				}
			}
		}
		return null;
	}

	/**
	 * 调用成功的社保办理
	 *
	 * @param handleStatus 1 办理成功 2 办理失败
	 * @param handleRemark
	 * @param typeSub      0 社保 1  公积金
	 * @param socialType   （1养老 2医疗 3失业 4工伤 5生育 6大病）
	 * @return
	 * @Author hgw
	 * @Date 2024-5-11 17:03:12
	 **/
	private void doSocialAndDispatch(List<String> idList, String typeSub, String handleStatus
			, String handleRemark, String socialType, String remark, YifuUser user) {
		tDispatchInfoService.addApplyHandle(idList, typeSub, handleStatus, handleRemark, socialType, remark, user, true);
	}

	/**
	 * 加办理记录
	 *
	 * @param handleRemark
	 * @Author hgw
	 * @Date 2024-5-16 11:43:33
	 **/
	public void doSocialTAuditInfo(TSocialInfo social, String title, String handleRemark, String remark, YifuUser user) {
		TAuditInfo auditInfo = new TAuditInfo();
		auditInfo.setType(CommonConstants.ONE_STRING);
		auditInfo.setId(null);
		auditInfo.setAuditStatus(CommonConstants.TWO_STRING);
		auditInfo.setAuditRemark(handleRemark);
		if (Common.isNotNull(title) && title.length() > 255) {
			title = title.substring(0, 255);
		}
		auditInfo.setTitle(title);
		auditInfo.setOrganName(user.getDeptName());
		auditInfo.setAuditUser(user.getNickname());
		auditInfo.setAuditTime(new Date());
		auditInfo.setRemark(remark);
		auditInfo.setIsCommision(CommonConstants.ONE_STRING);
		auditInfo.setDispatchInfoId(social.getDispatchId());
		auditInfo.setEmpIdcard(social.getEmpIdcard());
		auditInfo.setSocialId(social.getId());
		tAuditInfoService.save(auditInfo);
	}

}
