package com.yifu.cloud.plus.v1.ekp.service.impl;

import com.alibaba.excel.EasyExcelFactory;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.icbc.api.DefaultIcbcClient;
import com.icbc.api.IcbcApiException;
import com.icbc.api.IcbcConstants;
import com.icbc.api.UiIcbcClient;
import com.icbc.api.request.JftApiPayrollQueryDetailRequestV1;
import com.icbc.api.request.JftUiPayrollComfirmSubmitRequestV1;
import com.icbc.api.request.MybankEnterpriseAccountQuerybankinfoRequestV1;
import com.icbc.api.response.JftApiPayrollQueryDetailResponseV1;
import com.icbc.api.response.MybankEnterpriseAccountQuerybankinfoResponseV1;
import com.icbc.api.utils.IcbcSignature;
import com.icbc.api.utils.WebUtils;
import com.jcraft.jsch.*;
import com.yifu.cloud.plus.v1.ekp.config.IcbcIssueConfigProperties;
import com.yifu.cloud.plus.v1.ekp.config.ZhaoHangConfigProperties;
import com.yifu.cloud.plus.v1.ekp.entity.*;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpSocialInfoMapper;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpZhaoHangDetailLogMapper;
import com.yifu.cloud.plus.v1.ekp.mapper.EkpZhaoHangDetailMapper;
import com.yifu.cloud.plus.v1.ekp.service.*;
import com.yifu.cloud.plus.v1.ekp.vo.EkpBankAttaReturnVo;
import com.yifu.cloud.plus.v1.ekp.vo.EkpBankCodeConfiglVo;
import com.yifu.cloud.plus.v1.ekp.vo.EkpBankExcelVo;
import com.yifu.cloud.plus.v1.ekp.vo.EkpBankResultVo;
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 lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 * 聚富通到账通知交易流水查询
 *
 * @author huyc
 * @date 2024-05-23 11:21:56
 */
@Log4j2
@Service
@RequiredArgsConstructor
@EnableConfigurationProperties(ZhaoHangConfigProperties.class)
public class ZhaoHangServiceImpl extends ServiceImpl<EkpSocialInfoMapper, EkpSocialInfo> implements ZhaoHangService {

	@Autowired
	private ZhaoHangConfigProperties zhaoHangConfigProperties;

	@Autowired
	private EkpZhaoHangDetailService ekpZhaoHangDetailService;

	@Autowired
	private EkpZhaoHangDetailLogMapper ekpZhaoHangDetailLogMapper;

	private RestTemplate restTemplate = new RestTemplate();

	/**
	 * @Description: 代发任务确认提交
	 * @Author: huyc
	 * @Date: 2024-11-12
	 * @return: R
	 **/
	@Override
	public R<String> doGetZhaoHangInfo() {
		// 每日都查前7天的
		for (int i=-7; i<0; i++) {
			doGetZhaoHangCore(DateUtil.addDay(i));
		}
		return R.ok();
	}

	@Override
	public R<String> doGetZhaoHangCore(String postDate) {
		JSONObject paramJson = new JSONObject();
		JSONObject json = new JSONObject();
		json.put("clientId", zhaoHangConfigProperties.getClientId());
		json.put("clientSecret", zhaoHangConfigProperties.getClientSecret());
		json.put("corNum", zhaoHangConfigProperties.getCorNum());
		json.put("postDate", postDate);
		int currPage = 1;
		json.put("currPage", currPage);
		paramJson.put("paraMap", json);
		HttpHeaders headers = new HttpHeaders();
		MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
		headers.setContentType(type);
		headers.add("Accept", MediaType.APPLICATION_JSON.toString());

		// 加日志：
		EkpZhaoHangDetailLog detailLog = new EkpZhaoHangDetailLog();
		detailLog.setFdParam(paramJson.toString());
		detailLog.setFdDatePush(LocalDateTime.now());
		ekpZhaoHangDetailLogMapper.insert(detailLog);

		HttpEntity<String> formEntity = new HttpEntity<>(paramJson.toString(), headers);
		String url = "https://esp.cc.cmbchina.com/DataTransferPortal/BusiTranDataQuery.getTransData.do";
		String dataResultList = restTemplate.postForEntity(url, formEntity, String.class).getBody();
		log.debug("拉取招行dataResultList=" + dataResultList);
		if (Common.isEmpty(dataResultList)) {
			// 返回时，更新日志
			detailLog.setFdData("获取招行数据失败，dataResultList为空");
			detailLog.setFdDateBack(LocalDateTime.now());
			ekpZhaoHangDetailLogMapper.updateById(detailLog);
			throw new AuthenticationServiceException("获取招行数据失败");
		}
		// 返回时，更新日志
		detailLog.setFdData(dataResultList);
		detailLog.setFdDateBack(LocalDateTime.now());
		ekpZhaoHangDetailLogMapper.updateById(detailLog);


		JSONObject jsonObject = JSON.parseObject(dataResultList);
		String success = jsonObject.getString("success");
		String message = jsonObject.getString("message");
		String msgCode = jsonObject.getString("msgCode");
		String sumPage = jsonObject.getString("sumPage");
		JSONArray dataArray = jsonObject.getJSONArray("object");
		if (!"true".equals(success) || !"0000".equals(msgCode)) {
			return R.failed(message);
		}
		int sumPageNum = 1;
		if (Common.isNotNull(sumPage)) {
			try {
				sumPageNum = Integer.parseInt(sumPage);
			} catch (Exception e) {
				log.error("获取招行数据失败,sumPage无法转化为整数", sumPage);
				sumPageNum = 1;
			}
		}

		Map<String, String> ekpId = ekpZhaoHangDetailService.getAccountIdAndUserId();
		// 处理数据
		this.doSetZhaoHangInfoCore(dataArray, ekpId);

		if (sumPageNum > 1) {
			// 如果一次没取全，循环取
			while (currPage <= sumPageNum) {
				json.put("currPage", ++currPage);

				// 加日志：
				detailLog = new EkpZhaoHangDetailLog();
				detailLog.setFdParam(paramJson.toString());
				detailLog.setFdDatePush(LocalDateTime.now());
				ekpZhaoHangDetailLogMapper.insert(detailLog);

				formEntity = new HttpEntity<>(paramJson.toString(), headers);
				dataResultList = restTemplate.postForEntity(url, formEntity, String.class).getBody();
				if (Common.isEmpty(dataResultList)) {
					// 返回时，更新日志
					detailLog.setFdData("获取招行数据失败，dataResultList为空");
					detailLog.setFdDateBack(LocalDateTime.now());
					ekpZhaoHangDetailLogMapper.updateById(detailLog);
					throw new AuthenticationServiceException("获取招行数据失败");
				}
				// 返回时，更新日志
				detailLog.setFdData(dataResultList);
				detailLog.setFdDateBack(LocalDateTime.now());
				ekpZhaoHangDetailLogMapper.updateById(detailLog);

				jsonObject = JSON.parseObject(dataResultList);
				success = jsonObject.getString("success");
				message = jsonObject.getString("message");
				msgCode = jsonObject.getString("msgCode");
				if (!"true".equals(success) || !"0000".equals(msgCode)) {
					return R.failed(message);
				}
				dataArray = jsonObject.getJSONArray("object");
				this.doSetZhaoHangInfoCore(dataArray, ekpId);
			}
		}
		return R.ok();
	}

	/**
	 * @Description: 处理数据
	 * @Author: hgw
	 * @Date: 2025/9/9 15:24
	 * @return: void
	 **/
	public void doSetZhaoHangInfoCore(JSONArray dataArray, Map<String, String> ekpId) {
		List<EkpZhaoHangDetail> cpList = new ArrayList<>();
		List<String> noList = new ArrayList<>();
		if (ekpId == null) {
			ekpId = new HashMap<>();
		}
		if (dataArray != null) {
			JSONObject jsonObject;
			// 内部唯一交易流水号 "CCAP1T8ELTL105CJ506P"
			String globalSerialNo;
			// 卡号 "6225819355162461"
			String crdNum;
			// 交易日期 "2025-07-01"
			String trsDte;
			// 交易时间 "174709"
			String trxTim;
			// 交易金额 "769.00"
			String oriCurAmt;
			// 商户名称 "支付宝-（固话）中国电信集团"
			String acpName;
			String fdAccountId;
			String fdEmpName;
			// 循环遍历array
			EkpZhaoHangDetail detail;
			for (int i = 0; i < dataArray.size(); i++) {
				detail = new EkpZhaoHangDetail();
				jsonObject = dataArray.getJSONObject(i);
				globalSerialNo = jsonObject.getString("globalSerialNo");
				crdNum = jsonObject.getString("crdNum");
				trsDte = jsonObject.getString("trsDte");
				trxTim = jsonObject.getString("trxTim");
				oriCurAmt = jsonObject.getString("oriCurAmt");
				acpName = jsonObject.getString("acpName");
				fdAccountId = jsonObject.getString("acctNbr");
				fdEmpName = jsonObject.getString("actChiNam");

				detail.setFdNo(globalSerialNo);
				noList.add(globalSerialNo);
				if (Common.isNotNull(trxTim) && trxTim.length()==6) {
					detail.setFdDate(trsDte + " " + trxTim.substring(0,2) + ":" + trxTim.substring(2,4) + ":" + trxTim.substring(4,6));
				} else {
					detail.setFdDate(trsDte + " " + trxTim);
				}
				detail.setFdAcpName(acpName);
				detail.setFdAccountId(fdAccountId);
				detail.setFdUserId(ekpId.get(fdAccountId));
				detail.setFdEmpName(fdEmpName);
				detail.setFdBankNo(crdNum);
				try {
					detail.setFdMoney(new BigDecimal(oriCurAmt));
				} catch (Exception e) {
					detail.setFdMoney(new BigDecimal("0"));
				}
				detail.setCreateTime(LocalDateTime.now());
				cpList.add(detail);
			}
			// 所有需要保存的，删除已存在的
			if (!cpList.isEmpty() && !noList.isEmpty()) {
				// 获取已存在的
				List<String> curList = ekpZhaoHangDetailService.getByNo(noList);
				if (!curList.isEmpty()) {
					Map<String ,Integer> curMap = new HashMap<>();
					for (String cur : curList) {
						curMap.put(cur, CommonConstants.ONE_INT);
					}
					// 删除已存在的
					List<EkpZhaoHangDetail> canSaveList = new ArrayList<>();
					for (EkpZhaoHangDetail cp : cpList) {
						if (curMap.get(cp.getFdNo()) == null) {
							canSaveList.add(cp);
						}
					}
					cpList = canSaveList;
				}
				// 保存
				if (!cpList.isEmpty()) {
					ekpZhaoHangDetailService.saveBatch(cpList);
				}
			}
		}
	}


}
