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

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.yifu.cloud.plus.v1.yifu.common.core.constant.CommonConstants;
import com.yifu.cloud.plus.v1.yifu.common.core.exception.CheckedException;
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.social.entity.TSocialFriendBackLog;
import com.yifu.cloud.plus.v1.yifu.social.vo.FriendResult;
import com.yifu.cloud.plus.v1.yifu.social.vo.SociaFriendYgsAddVo;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.web.client.RestTemplate;

import java.security.SignatureException;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.TreeMap;

/**
 * @Author: hgw
 * @Date: 2024-12-6 17:01:23
 * @Description:
 * @return: 税友配置
 **/
@Configuration
@Data
@Slf4j
public class SocialFriendConfig {

	// appKey
	@Value("${socialFriend.appKey}")
	private String appKey;
	// appSecret
	@Value("${socialFriend.appSecret}")
	private String appSecret;
	// url前缀
	@Value("${socialFriend.urlPre}")
	private String urlPre;
	// url推 增加
	@Value("${socialFriend.urlPushAdd}")
	private String urlPushAdd;
	// url拉结果数据 增加
	@Value("${socialFriend.urlGetInfoAdd}")
	private String urlGetInfoAdd;
	// url推 增加
	@Value("${socialFriend.urlPushReduce}")
	private String urlPushReduce;
	// url拉结果数据 增加
	@Value("${socialFriend.urlGetInfoReduce}")
	private String urlGetInfoReduce;
	// url拉结果数据
	@Value("${socialFriend.urlUpload}")
	private String urlUpload;


	private static final String APP_KEY = "appKey";
	private static final String TIMESTAMP = "timestamp";
	private static final String X_REQ_NONCE = "xReqNonce";
	private static final String VERSION = "version";

	/**
	 * @param : type 1社保增 2社保减 3医保增 4医保减
	 * @Description: 推送任务接口
	 * @Author: hgw
	 * @Date: 2024-12-9 16:54:31
	 * @return: java.lang.String
	 **/
	public String pushFriendByInfo(RestTemplate restTemplate, SociaFriendYgsAddVo vo, int type, String thisTime
			, TSocialFriendBackLog backLog) {
		String addId = "";
		String appAddUrl = urlPre;
		if (type == 1 || type == 3) {
			appAddUrl += urlPushAdd;
		} else {
			appAddUrl += urlPushReduce;
		}
		String version = "1.0.0";
		String timestamp = String.valueOf(new Date().getTime());
		String xReqNonce = "1";
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		// */*
		headers.add("accept", MediaType.ALL_VALUE);
		headers.add(APP_KEY, appKey);
		headers.add(TIMESTAMP, timestamp);
		try {

			String signature = SocialFriendSign.qianMing(getMapParam(appKey, appSecret, xReqNonce, version, timestamp, null));
			headers.add("signature", signature);
		} catch (SignatureException e) {
			log.error("税友签名失败", e);
			return addId;
		}
		headers.add(X_REQ_NONCE, xReqNonce);
		headers.add(VERSION, version);

		JSONObject json = new JSONObject();
		// 外部业务订单号
		json.put("bizNo", vo.getSocialId() + thisTime);
		// 企业名称——户名
		json.put("qymc", vo.getSocialHouseholdName());
		// 税号——户配置的“单位统一信用代码”
		json.put("nsrsbh", vo.getUnitCreditCode());
		// 行政区划代码 户里的缴纳地，精确到市 "340100"
		json.put("areaid", vo.getAreaCode());
		JSONArray ywblzhlbArr = new JSONArray();
		if (type < 3) {
			JSONObject jsonYwblzhlbYgs = new JSONObject();
			// 密码
			jsonYwblzhlbYgs.put("mm", vo.getSocialPassword());
			// 办理项目 例如社保、医保等
			jsonYwblzhlbYgs.put("blxm", "社保");
			// 单位编号
			jsonYwblzhlbYgs.put("dwbh", vo.getCustomerNo());
			// 账号
			jsonYwblzhlbYgs.put("zh", vo.getSocialAccount());
			// 密码类型:安徽社保医保都是4：
			jsonYwblzhlbYgs.put("mmlx", "4");
			ywblzhlbArr.add(jsonYwblzhlbYgs);
		} else {
			JSONObject jsonYwblzhlbYsd = new JSONObject();
			jsonYwblzhlbYsd.put("mm", vo.getMediclPassword());
			jsonYwblzhlbYsd.put("blxm", "医保");
			jsonYwblzhlbYsd.put("dwbh", vo.getCustomerNo());
			jsonYwblzhlbYsd.put("zh", vo.getMediclAccount());
			jsonYwblzhlbYsd.put("mmlx", "4");
			ywblzhlbArr.add(jsonYwblzhlbYsd);
		}
		json.put("ywblzhlb", ywblzhlbArr);
		// type 1社保增 2社保减 3医保增 4医保减
		setEmpInfo(json, vo, type);

		HttpEntity<String> formEntity = new HttpEntity<>(json.toString(), headers);
		System.out.println("推的接送=" + json);
		String dataResultList = restTemplate.postForObject(appAddUrl, formEntity, String.class);
		// {"head":{"code":"00000000","description":"成功","msg":"成功","time":"2024-12-06 17:10:26","status":"Y"
		// ,"body":{"requestId":"85440b327d71466abcd9c5c81d5bb172"
		if (Common.isNotNull(dataResultList)) {
			backLog.setLogInfo(dataResultList);
			backLog.setCreateTime(LocalDateTime.now());
			JSONObject dataObject = JSON.parseObject(dataResultList);
			String head = dataObject.getString("head");
			if (Common.isNotNull(head)) {
				JSONObject headObject = JSON.parseObject(head);
				String status = headObject.getString("status");
				if ("Y".equals(status)) {
					String body = dataObject.getString("body");
					JSONObject bodyObject = JSON.parseObject(body);
					addId = bodyObject.getString("requestId");
				}
			}
		}
		return addId;
	}

	/**
	 * @param : type 1社保增 2社保减 3医保增 4医保减
	 * @Description: 推送任务接口
	 * @Author: hgw
	 * @Date: 2024-12-9 16:54:31
	 * @return: java.lang.String
	 **/
	public String uploadPng(RestTemplate restTemplate, String fileName, String file, TSocialFriendBackLog backLog) {
		String urlStr = "";
		String appAddUrl = urlPre + urlUpload;
		String version = "1.0.0";
		String timestamp = String.valueOf(new Date().getTime());
		String xReqNonce = "1";
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		// */*
		headers.add("accept", MediaType.ALL_VALUE);
		headers.add(APP_KEY, appKey);
		headers.add(TIMESTAMP, timestamp);
		try {
			String signature = SocialFriendSign.qianMing(getMapParam(appKey, appSecret, xReqNonce, version, timestamp, null));
			headers.add("signature", signature);
		} catch (SignatureException e) {
			log.error("税友签名失败", e);
			return urlStr;
		}
		headers.add(X_REQ_NONCE, xReqNonce);
		headers.add(VERSION, version);

		JSONObject json = new JSONObject();
		// 文件名称
		json.put("wjmc", fileName);
		// 	文件内容
		json.put("wjnr", file);
		// 业务类型 参保、停保、参保业务签名、停保业务签名、人员补缴、缴费工资变更、缴费工资业务签名
		// json.put("ywlx", vo.getUnitCreditCode())
		// 行政区划代码 户里的缴纳地，精确到市 "340100"

		HttpEntity<String> formEntity = new HttpEntity<>(json.toString(), headers);
		String dataResultList = restTemplate.postForObject(appAddUrl, formEntity, String.class);
		// {"head":{"code":"00000000","description":"成功","msg":"成功","time":"2024-12-06 17:10:26","status":"Y"
		// ,"body":{"requestId":"85440b327d71466abcd9c5c81d5bb172"
		if (Common.isNotNull(dataResultList)) {
			backLog.setLogInfo(dataResultList);
			backLog.setCreateTime(LocalDateTime.now());
			JSONObject dataObject = JSON.parseObject(dataResultList);
			String head = dataObject.getString("head");
			if (Common.isNotNull(head)) {
				JSONObject headObject = JSON.parseObject(head);
				String status = headObject.getString("status");
				if ("Y".equals(status)) {
					String body = dataObject.getString("body");
					JSONObject bodyObject = JSON.parseObject(body);
					urlStr = bodyObject.getString("wjlj");
				}
			}
		}
		return urlStr;
	}

	/**
	 * @param json 总传参json
	 * @param type 1社保增 2社保减 3医保增 4医保减
	 * @Description: 分流塞值
	 * @Author: hgw
	 * @Date: 2024/12/11 10:24
	 * @return: void
	 **/
	private void setEmpInfo(JSONObject json, SociaFriendYgsAddVo vo, int type) {
		if (type == 1 || type == 3) {
			setEmpInfoAdd(json, vo, type);
		} else {
			setEmpInfoReduce(json, vo, type);
		}
	}

	/**
	 * @param json 主json存数据
	 * @Description: 塞人员名单-1社保增
	 * @Author: hgw
	 * @Date: 2024/12/10 18:05
	 * @return: void
	 **/
	private void setEmpInfoAdd(JSONObject json, SociaFriendYgsAddVo vo, int type) {
		// 参保人员名单 数组
		JSONArray cbrymdArr = new JSONArray();
		JSONObject cbrymdOne = new JSONObject();
		// 姓名
		cbrymdOne.put("xm", vo.getEmpName());
		// 证件类型
		cbrymdOne.put("zzlx", "居民身份证");
		// 证件号码"828888200908213819"
		cbrymdOne.put("zzhm", vo.getEmpIdcard());

		// 国籍（地区） "中国"
		cbrymdOne.put("gj", "中国");
		// 性别
		//cbrymdOne.put("xb", "男")
		cbrymdOne.put("xb", getSexName(vo.getEmpIdcard()));
		// 出生日期
		cbrymdOne.put("csrq", getBirthStr(vo.getEmpIdcard()));
		// 民族 空的默认汉族
		cbrymdOne.put("mz", vo.getEmpNational());
		// 手机号码
		cbrymdOne.put("sjhm", vo.getEmpMobile());
		String areaName = "安徽省";
		// 户口地所在行政区
		cbrymdOne.put("hkszdxzq", areaName);
		// 户口所在地地址
		cbrymdOne.put("hkszddz", areaName);
		// 户口性质
		cbrymdOne.put("hkxz", "居民户口（含农业户口、非农业户口）");
		// 居住地址
		cbrymdOne.put("jzdz", areaName);
		// 居住地行政区
		cbrymdOne.put("jzdzxzq", areaName);
		// 社保起缴日期（养老起缴）yyyy-MM-dd
		String startDate = vo.getSocialStartDate();
		// 参加工作日期
		cbrymdOne.put("cjgzrq", startDate);
		// 文化程度 见字典“受教育程度” 空的默认“大学专科”
		//cbrymdOne.put("whcd", "大学专科")
		cbrymdOne.put("whcd", vo.getEducationName());

		// 办理项目列表
		JSONArray blxmlbArr = new JSONArray();
		JSONObject blxmlbOne = new JSONObject();
		String blxm = "社保";
		// 险种类型 例如养老、工伤、医疗等
		String xzlb = "企业职工养老,工伤保险,失业保险";
		if (type > 2) {
			blxm = "医保";
			xzlb = "职工基本医疗保险,生育保险,大额医疗";
		}
		String[] strArr = xzlb.split(",");
		// 办理项目
		blxmlbOne.put("blxm", blxm);
		// 本次参保日期 格式：yyyy-MM-dd
		blxmlbOne.put("bccbrq", startDate);
		// 申报工资 社保派单里的“备案基数”
		blxmlbOne.put("sbgz", vo.getRecordBase());

		// 险种类型 例如养老、工伤、医疗等
		blxmlbOne.put("xzlb", strArr);
		blxmlbArr.add(blxmlbOne);
		cbrymdOne.put("blxmlb", blxmlbArr);

		// 特色字段信息
		JSONObject tszdxx = new JSONObject();
		// 增员年月 社保必填；yyyyMM 社保起缴日期（养老起缴）到月
		tszdxx.put("zyny", vo.getSocialStartMonth());
		// 同步办理用工劳动备案 社保必填；是
		tszdxx.put("tbblygldhtba", "是");
		// 参保模式 新参、续参
		tszdxx.put("cbms", "续参");
		// 就业登记时间 社保必填；yyyy-MM-dd
		tszdxx.put("jydjsj", startDate);
		// 单位就业起始时间  社保必填；yyyy-MM-dd
		tszdxx.put("dwjyqssj", startDate);
		// 安徽非必填！社保个人身份材料 取文件上传后获取的文件路径。图片总大小不超过1M, 材料仅支持图片格式,支持上传jpeg/jpg/png格式。
		// tszdxx.put("sbzycl", url)

		// 用工形式 社保必填 // 盛宇文档对应，只有3种
		tszdxx.put("ygxs", vo.getContractType());
		// 劳动合同签署情况 社保必填 默认"初签"
		tszdxx.put("ldhtqsqk", "初签");
		// 人员类型 默认：在职职工
		tszdxx.put("rylx", "在职职工");
		// 医保个人身份材料 安徽非必填！ 无
		//tszdxx.put("ybzycl", url)
		// 职业工种 社保必填  默认“办事人员和有关人员”
		tszdxx.put("zygz", "办事人员和有关人员");
		// 人员身份 个人身份 社保必填 默认“职员”
		tszdxx.put("grsf", "职员");
		// 工作时间制度 社保必填
		tszdxx.put("gzsjzd", vo.getWorkingHours());
		// 医保用工形式 医保新参必填 默认“原固定职工”
		tszdxx.put("ybygxs", "原固定职工");

		if (type < 3) {
			// 企业职工社会保险增员花名册 安徽非必填！
			// 社保增员必填
			tszdxx.put("qyzgshbxzyhmc", vo.getQyzgshbxzyhmc());
		} else {
			// 企业职工基本医疗保险参保登记表 安徽非必填！ 数组
			String[] arr = {vo.getQyzgjbylbxcbdjb()};
			//  增员、减员必填
			tszdxx.put("qyzgjbylbxcbdjb", arr);
		}
		cbrymdOne.put("tszdxx", tszdxx);

		// 就业信息 社保必填；
		JSONObject jyxx = new JSONObject();
		// 劳动合同类型
		jyxx.put("ldhtlx", vo.getContractTypeTwo());
		// 劳动合同起始日期
		jyxx.put("ldhtqsrq", startDate);
		// 劳动合同截止日期 派单里的“合同截止日期”
		jyxx.put("ldhtjzrq", vo.getContractEnd());
		cbrymdOne.put("jyxx", jyxx);
		cbrymdArr.add(cbrymdOne);
		// 人员名单
		String buyType = "cbrymd";
		json.put(buyType, cbrymdArr);
	}

	/**
	 * @param json 主json存数据
	 * @Description: 塞人员名单-2社保减
	 * @Author: hgw
	 * @Date: 2024/12/10 18:05
	 * @return: void
	 **/
	private void setEmpInfoReduce(JSONObject json, SociaFriendYgsAddVo vo, int type) {
		// 参保人员名单 数组
		// 参保人员名单 数组
		JSONArray cbrymdArr = new JSONArray();
		JSONObject cbrymdOne = new JSONObject();
		// 姓名
		cbrymdOne.put("xm", vo.getEmpName());
		// 证件类型
		cbrymdOne.put("zzlx", "居民身份证");
		// 证件号码"828888200908213819"
		cbrymdOne.put("zzhm", vo.getEmpIdcard());
		// 办理项目列表
		JSONArray blxmlbArr = new JSONArray();
		JSONObject blxmlbOne = new JSONObject();
		String blxm = "社保";
		if (type > 2) {
			blxm = "医保";
		}
		// 办理项目
		blxmlbOne.put("blxm", blxm);
		// 中断原因 除死亡以外，其他停保原因默认：“在职人员解除/终止劳动合同” 死亡对应“死亡或失踪”
		blxmlbOne.put("tbyy", vo.getTbyy());
		// 中断时间 yyyy-MM-dd 默认当前时间
		blxmlbOne.put("tbsj", DateUtil.getLastDay());
		blxmlbArr.add(blxmlbOne);
		cbrymdOne.put("blxmlb", blxmlbArr);

		// 特色字段信息
		JSONObject tszdxx = new JSONObject();
		// 劳动用工备案解除/终止原因  数据字典文档 法律依据 [社保]必填；
		tszdxx.put("zzyy", vo.getZzyy());
		// 社保个人身份材料 无
		// tszdxx.put("shjycl", )
		// 医保个人身份材料 无
		// tszdxx.put("ybjycl", )
		// 职工社会保险减少花名册 无
		// tszdxx.put("zgshbxjshmc", )
		if (type > 2) {
			// 职工基本医疗保险参保登记表
			String[] arr = {vo.getQyzgjbylbxcbdjb()};
			tszdxx.put("zgjbylbxcbdjb", arr);
		}
		cbrymdOne.put("tszdxx", tszdxx);
		cbrymdArr.add(cbrymdOne);
		// 人员名单
		String buyType = "tbrymd";
		json.put(buyType, cbrymdArr);
	}

	/**
	 * @param: type 0增加1减少
	 * @param: requestId ： 请求ID
	 * @Description: 任务查询接口
	 * @Author: hgw
	 * @Date: 2024-12-9 16:54:22
	 * @return: java.lang.String
	 **/
	public FriendResult getFriendByRequestId(RestTemplate restTemplate, String requestId, TSocialFriendBackLog backLog, String type) {
		if (Common.isEmpty(requestId)) {
			return null;
		}
		String appAddUrl = urlPre;
		if (CommonConstants.ZERO_STRING.equals(type)) {
			appAddUrl += urlGetInfoAdd;
		} else {
			appAddUrl += urlGetInfoReduce;
		}
		appAddUrl += "?requestId=" + requestId;
		String version = "1.0.0";
		String timestamp = String.valueOf(new Date().getTime());
		String xReqNonce = "1";
		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_JSON);
		headers.add(APP_KEY, appKey);
		headers.add(TIMESTAMP, timestamp);
		try {
			String signature = SocialFriendSign.qianMing(getMapParam(appKey, appSecret, xReqNonce, version, timestamp, requestId));
			headers.add("signature", signature);
		} catch (SignatureException e) {
			log.error("税友签名失败", e);
			return null;
		}
		headers.add(X_REQ_NONCE, xReqNonce);
		headers.add(VERSION, version);
		HttpEntity<String> formEntity = new HttpEntity<>(headers);
		ResponseEntity<String> response = restTemplate.exchange(appAddUrl, HttpMethod.GET, formEntity, String.class);
		if (Common.isEmpty(response) || Common.isEmpty(response.getBody())) {
			throw new CheckedException("获取税友结果失败");
		}
		int statusCode = response.getStatusCodeValue();
		if (statusCode != 200) {
			throw new CheckedException("获取税友结果失败，statusCode=" + statusCode);
		}
		FriendResult result = new FriendResult();
		String dataResultList = response.getBody();

		backLog.setCreateTime(LocalDateTime.now());
		backLog.setLogInfo(dataResultList);


		// 组装返回结果
		getResultToVo(dataResultList, result);
		return result;
	}

	// 组装返回结果
	private void getResultToVo(String dataResultList, FriendResult result) {
		if (Common.isNotNull(dataResultList)) {
			JSONObject dataObject = JSON.parseObject(dataResultList);
			String head = dataObject.getString("head");
			if (Common.isNotNull(head)) {
				JSONObject headObject = JSON.parseObject(head);
				String status = headObject.getString("status");
				if ("Y".equals(status)) {
					String body = dataObject.getString("body");
					JSONObject bodyObject = JSON.parseObject(body);
					// 获取核心结果
					getResultToVoCore(result, bodyObject);
				}
			}
		}
	}

	// 提取方法，组装核心结果
	private void getResultToVoCore(FriendResult result, JSONObject bodyObject) {
		if (Common.isNotNull(bodyObject)) {
			// 人员办理项目结果
			JSONArray ryywbljglbArr = (JSONArray) bodyObject.get("ryywbljglb");
			if (Common.isNotNull(ryywbljglbArr)) {
				// 注意：此处可以返回多条身份证，但是我们单条提交
				JSONObject ryywbljglb = (JSONObject) ryywbljglbArr.get(0);
				// 身份证
				String idCard = ryywbljglb.getString("zzhm");
				result.setIdCard(idCard);
				// 办理项目列表
				JSONArray blxmjglbArr = (JSONArray) ryywbljglb.get("blxmjglb");
				if (Common.isNotNull(blxmjglbArr)) {
					// 注意：此处可以返回多条办理，但是我们社保与医保分开提交
					JSONObject blxmjglb = (JSONObject) blxmjglbArr.get(0);
					// 状态1-处理中，2-处理成功，3-处理失败，4-待办(提交成功，待网厅状态流转，上海特有)
					String zt = blxmjglb.getString("zt");
					result.setZt(zt);
					// 明细状态：提交失败、审核失败、审核成功、待确认
					//String mxzt = blxmjglb.getString("mxzt")
					// 提示或者错误信息 SUCCESS
					String cwxx = blxmjglb.getString("cwxx");
					if (Common.isNotNull(cwxx) && cwxx.length()>100 ) {
						cwxx = cwxx.substring(0, 100);
					}
					result.setCwxx(cwxx);
				}
			}
		}
	}

	/*
	 * @Description: 塞请求参数
	 * @Author: hgw
	 * @Date: 2024/12/10 10:38
	 * @return: java.util.TreeMap<java.lang.String,java.lang.String>
	 **/
	private TreeMap<String, String> getMapParam(String appKey, String appSecret, String xReqNonce, String version, String timestamp, String requestId) {
		TreeMap<String, String> treeMap = new TreeMap<>();
		if (Common.isNotNull(requestId)) {
			treeMap.put("requestId", requestId);
		}
		treeMap.put(VERSION, version);
		treeMap.put(TIMESTAMP, timestamp);
		treeMap.put(APP_KEY, appKey);
		treeMap.put(X_REQ_NONCE, xReqNonce);
		treeMap.put("appSecret", appSecret);
		return treeMap;
	}

	/**
	 * @param idNum 身份证
	 * @Description: 获取身份证的性别-汉字（已知身份证正确）
	 * @Author: hgw
	 * @Date: 2024/12/11 17:00
	 * @return: java.lang.String
	 **/
	public static String getSexName(String idNum) {
		String sex = "男";
		if (idNum != null) {
			String sexString = "";
			if (idNum.length() == 18) {
				sexString = idNum.substring(16, 17);
			} else if (idNum.length() == 15) {
				sexString = idNum.substring(14, 15);
			}
			try {
				// 判断性别
				if (Integer.parseInt(sexString) % 2 == 0) {
					sex = "女";
				}
			} catch (Exception e) {
				sex = "男";
			}
		}
		return sex;
	}

	/**
	 * @param idNum 身份证
	 * @Description: 获取身份证的年月日（已知身份证正确）
	 * @Author: hgw
	 * @Date: 2024/12/11 17:07
	 * @return: java.lang.String
	 **/
	public static String getBirthStr(String idNum) {
		String birthStr = "1990-01-01";
		if (idNum != null) {
			if (idNum.length() == 18) {
				birthStr = idNum.substring(6, 10) + "-" + idNum.substring(10, 12) + "-" + idNum.substring(12, 14);
			} else if (idNum.length() == 15) {
				birthStr = "19" + idNum.substring(6, 8) + "-" + idNum.substring(8, 10) + "-" + idNum.substring(10, 12);
			}
		}
		return birthStr;
	}

}
