package org.security.imagePlatformDock.imagePlateform;

import cn.hutool.core.date.DateUtil;
import com.sunyard.client.SunEcmClientApi;
import com.sunyard.client.bean.ClientBatchBean;
import com.sunyard.client.bean.ClientBatchFileBean;
import com.sunyard.client.bean.ClientBatchIndexBean;
import com.sunyard.client.bean.ClientFileBean;
import com.sunyard.client.impl.SunEcmClientSocketApiImpl;
import com.sunyard.util.OptionKey;
import com.sunyard.ws.utils.XMLUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.security.common.util.SetFilePermission;
import org.security.config.ImagePlateFormDockProperties;
import org.security.desk.esb.SeqNOFactory;
import org.security.imagePlatformDock.entity.UploadFileRecord;
import org.security.imagePlatformDock.service.IUploadFileRecordService;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Component;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;

/**
 * @author ：wzf
 * @apiNote ：连接影像平台
 * @since ：Created in 2022/9/6 16:49
 */
@Slf4j
@Component
@AllArgsConstructor
public class SunECMClient {

	private final IUploadFileRecordService uploadFileRecordService;
	private final ImagePlateFormDockProperties imagePlateFormDockProperties;

	/**
	 * 上传附件到影像平台
	 *
	 * @param fileName  文件名称
	 * @param filePath  本地文件路径
	 * @param groupName 文件分组标识符
	 * @param fileType  文件类型1-证件，2-合同，3-发票，4-其他，5-贷后检查材料， 6-回单， 7-财务报表 ，8-授权书， 9-承诺书 ，
	 *                  10-协议，
	 *                  11-网贷影像材料，
	 *                  12-马消贷影像材料，
	 *                  13-长安车贷影像材料，
	 *                  14-云按揭材料，
	 *                  15-保险材料，
	 *                  16-ETC材料
	 *                  17-烟叶资金结算签约影像资料
	 *                  18-安全信息化管理系统影像资料
	 * @return
	 */
	public UploadFileRecord uploadSingle(String fileName, String filePath, String groupName, String fileType) {
		SunEcmClientApi sec = new SunEcmClientSocketApiImpl(imagePlateFormDockProperties.getIp(), imagePlateFormDockProperties.getSocketPort());
		log.info("sec [{}]", sec);
		ClientBatchBean clientBatchBean = new ClientBatchBean();
		clientBatchBean.setModelCode(imagePlateFormDockProperties.getModelCode());
		clientBatchBean.setUser(imagePlateFormDockProperties.getUserName());
		clientBatchBean.setPassWord(imagePlateFormDockProperties.getPassWord());
		ClientBatchIndexBean clientBatchIndexBean = new ClientBatchIndexBean();
		// 此处为文件数量，对系统来说与业务上存的AMOUNT字段是不同的信息
		clientBatchIndexBean.setAmount("1");
		String tranDate = DateUtil.format(DateUtil.date(), "yyyyMMdd");
		String tranTm = DateUtil.format(DateUtil.date(), "HHmmss");
		clientBatchIndexBean.addCustomMap("BUSI_SERIAL_NO", SeqNOFactory.getSeqNo(tranDate, tranTm));// 业务流水号
		clientBatchIndexBean.addCustomMap("BUSI_BATCH_NO", SeqNOFactory.getSeqNo(tranDate, tranTm)); // 业务批次号
		clientBatchIndexBean.addCustomMap("BUSI_START_DATE", tranDate);// 业务开始时间
		clientBatchIndexBean.addCustomMap("BUSI_END_DATE", "");// 业务结束时间
		clientBatchIndexBean.addCustomMap("CUST_NAME", AuthUtil.getUser().getUserName());// 客户名称
//		clientBatchIndexBean.addCustomMap("CUST_NAME","");// 客户名称
		clientBatchIndexBean.addCustomMap("CUST_NO", uploadFileRecordService.getUserData(AuthUtil.getUser().getUserId()));// 客户号
//		clientBatchIndexBean.addCustomMap("CUST_ID", uploadFileRecordService.getUserData(AuthUtil.getUser().getUserId()));// 客户证件号
		clientBatchIndexBean.addCustomMap("CUST_ID", "");// 客户证件号
		clientBatchIndexBean.addCustomMap("MOBILE_NO", "");// 手机号
		clientBatchIndexBean.addCustomMap("ORGAN_NO", uploadFileRecordService.getDeptCode(AuthUtil.getDeptId()));// 机构号
//		clientBatchIndexBean.addCustomMap("ORGAN_NO", "99999");// 机构号
		clientBatchIndexBean.addCustomMap("CHANNEL", imagePlateFormDockProperties.getAimChannel());// 渠道号
		log.info("文件上传影像平台参数信息： {[]}" + clientBatchIndexBean.getCustomMap().toString());
		// 这里是索引部件的属性，按照各渠道文档要求传值
		ClientBatchFileBean clientBatchFileBean = new ClientBatchFileBean();
		clientBatchFileBean.setFilePartName(imagePlateFormDockProperties.getFilePartName());
		ClientFileBean fileBean1 = new ClientFileBean();
		fileBean1.setFileName(filePath.concat(fileName));// 本地文件路径
		log.info("文件本地存放路径： {[]}" + fileBean1.getFileName());
		fileBean1.addOtherAtt("FILE_TYPE", fileType);//文件类型--证件
		fileBean1.addOtherAtt("DETAIL_TYPE", fileType);//详细类型 0-身份证  1-户口簿  （具体看文档）
		fileBean1.addOtherAtt("FILE_NAME", fileName);//文件名称
		fileBean1.addOtherAtt("GROUP_NAME", groupName);// ...自定义增加的字段-groupName
		clientBatchFileBean.addFile(fileBean1);
		clientBatchBean.setIndex_Object(clientBatchIndexBean);
		clientBatchBean.addDocument_Object(clientBatchFileBean);
		String result = null;
		try {
			// 输出实际发送的报文
			log.info("上送影像平台对象内容:[{}]" + XMLUtil.bean2XML(clientBatchBean));
			// 成功则输出SUCCESS<<::>>+内容编号
			result = sec.upload(clientBatchBean, imagePlateFormDockProperties.getDM());
			log.info("影像平台返回信息 [{}]" + result);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		//判断上传影像平台返回结果
		String uploadState = "2";
		String contentId = "";
		if (Func.isNotEmpty(result) && result.startsWith("SUCCESS<<::>>")) {
			uploadState = "1";
			contentId = result.substring(13);
			log.info("上传影像成功！影像ID【" + contentId + "】");
		} else {
			log.info("上传影像失败!" + result);
		}
		//封装返回对象
		return UploadFileRecord.builder()
			.platSeqNo(clientBatchIndexBean.getCustomMap().get("BUSI_SERIAL_NO"))
			.busiBeginDate(tranDate)
			.fileName(fileBean1.getFileName().concat(fileBean1.getOtherAtt().get("FILE_NAME")))
			.fileType(fileBean1.getOtherAtt().get("DETIAL_TYPE"))
			.attachName(fileBean1.getOtherAtt().get("FILE_NAME"))
			.groupName(groupName)
			.result(result)
			.uploadState(uploadState)
			.contentId(contentId).build();
	}


	/**
	 * 删除影像平台附件
	 *
	 * @param busiBeginDate 业务开始日期
	 * @param contentId     影像平台附件标识id
	 * @return
	 */
	public R removeFileData(String busiBeginDate, String contentId) {
		log.info("----------------删除影像平台附件开始----------------");
		log.info("删除目标附件的业务开始时间-busiBeginDate为：" + busiBeginDate + ",附件标识id-contentId为：" + contentId);
		SunEcmClientApi sec = new SunEcmClientSocketApiImpl(imagePlateFormDockProperties.getIp(), imagePlateFormDockProperties.getSocketPort());
		ClientBatchBean clientBatchBean = new ClientBatchBean();
		clientBatchBean.setModelCode(imagePlateFormDockProperties.getModelCode());
		clientBatchBean.setUser(imagePlateFormDockProperties.getUserName());
		clientBatchBean.setPassWord(imagePlateFormDockProperties.getPassWord());
		ClientBatchIndexBean indexBean = clientBatchBean.getIndex_Object();
		indexBean.setContentID(contentId);
		// 业务开始时间值，用于确定分表，传同一分表内其他日期将会更新该字段的值，传不同分表的日期将会更新失败（查不到影像）
		indexBean.addCustomMap("BUSI_START_DATE", busiBeginDate);
		// 更新索引表字段直接在customMap中传新值(平台流水号)
		String busiSerialNo = uploadFileRecordService.getBusiSerialNo(busiBeginDate, contentId);
		log.info("该附件上传时产生的平台流水号-BUSI_SERIAL_NO为：" + busiSerialNo);
		indexBean.addCustomMap("BUSI_SERIAL_NO", busiSerialNo);
		ClientBatchFileBean batchFileBean = new ClientBatchFileBean();
		batchFileBean.setFilePartName(imagePlateFormDockProperties.getFilePartName());
		// 删除一个文件
		ClientFileBean clientFileBean3 = new ClientFileBean();
		clientFileBean3.setOptionType(OptionKey.U_DEL);
		clientFileBean3.setFileNO(getFileNo(busiBeginDate, contentId));
		batchFileBean.addFile(clientFileBean3);
		clientBatchBean.addDocument_Object(batchFileBean);
		log.info("调用删除影像平台附件的请求信息:[{}]", clientBatchBean);
		String resultMsg = "";
		try {
			resultMsg = sec.update(clientBatchBean, imagePlateFormDockProperties.getDM(), true);
			log.info("#######删除影像平台附件返回的信息#######");
			log.info(resultMsg);
			log.info("----------------删除影像平台附件结束----------------");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "SUCCESS".equals(resultMsg) ? R.success("删除成功") : R.fail("删除失败");
	}

	/**
	 * 获取删除影像平台附件的fileNo
	 *
	 * @param busiBeginDate 业务开始时间
	 * @param contentId     附件平台id
	 * @return fileNo
	 */
	private String getFileNo(String busiBeginDate, String contentId) {
		//获取FileNo
		String fileResult = getPlateFormFile(busiBeginDate, contentId);
		int index = fileResult.indexOf("FILE_NO=\"");
		String fileNo = fileResult.substring(index + 9, index + 45);
		log.info("附件的FileNo为：" + fileNo);
		return fileNo;
	}

	/**
	 * 获取影像平台附件
	 */
	public String getFileData(String busiBeginDate, String contentId, String fileName) throws IOException {
		log.info("------------------获取影像平台附件开始--------------------");
		String result = getPlateFormFile(busiBeginDate, contentId);
		return analysisResult(result, fileName);
	}

	/**
	 * 获取影像平台附件信息
	 *
	 * @param busiBeginDate 业务开始日期
	 * @param contentId     附件平台id
	 * @return 影像平台请求返回结果
	 */
	private String getPlateFormFile(String busiBeginDate, String contentId) {
		SunEcmClientApi sec = new SunEcmClientSocketApiImpl(imagePlateFormDockProperties.getIp(), imagePlateFormDockProperties.getSocketPort());  //初始化，
		ClientBatchBean clientBatchBean = new ClientBatchBean();
		clientBatchBean.setModelCode(imagePlateFormDockProperties.getModelCode());
		clientBatchBean.setUser(imagePlateFormDockProperties.getUserName());
		clientBatchBean.setPassWord(imagePlateFormDockProperties.getPassWord());
		clientBatchBean.getIndex_Object().setContentID(contentId);
		clientBatchBean.getIndex_Object().addCustomMap("BUSI_START_DATE", busiBeginDate);// 业务开始时间值
		log.info("上送影像平台请求参数：[{}]" + XMLUtil.bean2XML(clientBatchBean));
		String result = "";
		try {
			result = sec.queryBatch(clientBatchBean, imagePlateFormDockProperties.getDM());
			log.info("影像平台返回结果：[{}]" + result);
			log.info("------------------获取影像平台附件开始--------------------");
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/**
	 * 解析result的xml
	 */
	private String analysisResult(String result, String fileName) throws IOException {
		String url = "";
		if (result != null && result.startsWith("0001<<::>>")) {
			String rspXml = result.substring(result.indexOf("<?xml"));
			log.info("影像平台 返回 {}", rspXml);
			rspXml = XMLUtil.removeHeadRoot(rspXml);  //去root 节点
			ClientBatchBean clientBatchBean2 = XMLUtil.xml2Bean(rspXml, ClientBatchBean.class);
			List<ClientBatchFileBean> clientBatchFileBeans = clientBatchBean2.getDocument_Objects();
			for (ClientBatchFileBean clientBatchFileBeas : clientBatchFileBeans) {
				List<ClientFileBean> ClientFileBean = clientBatchFileBeas.getFiles();
				for (ClientFileBean clientFileBean : ClientFileBean) {
					url = clientFileBean.getUrl();

				}
			}
			log.info("影像平台 URL  {}", url);
		}
		downLoadFile(url, fileName);
		return "/file/".concat(fileName);
	}

	/**
	 * 下载影像平台文件到本地文件夹
	 */
	private File downLoadFile(String url, String fileName) throws IOException {
		BufferedInputStream bis = null;
		BufferedOutputStream bos = null;
		//下载影像平台文件到本地
		// if (!ESAPI.validator().isValidFileName("upload", fileName, false)) {
		// 	throw new IOException("非法的文件名");
		// }
		File file = new File(imagePlateFormDockProperties.getService_path() + fileName);
		log.info("------------下载影像平台附件开始------------");
		log.info("影像平台附件url：[{}]", url);
		log.info("影像平台附件名称：[{}]", fileName);
		try {
			URL urlFile = new URL(url);
			HttpURLConnection httpUrl = (HttpURLConnection) urlFile.openConnection();
			log.info("http连接结果：[{}]", httpUrl);
			httpUrl.connect();
			bis = new BufferedInputStream(httpUrl.getInputStream());
			log.info("文件输入流：[{}]", bis);
			bos = new BufferedOutputStream(new FileOutputStream(file));
			log.info("文件输出流：[{}]", bos);
			int len = 2048;
			byte[] b = new byte[len];
			while ((len = bis.read(b)) != -1) {
				bos.write(b, 0, len);
			}
			bos.flush();
			bis.close();
			httpUrl.disconnect();
		} catch (Exception e) {
			log.error("http连接异常，异常原因:" + e);
		} finally {
			try {
				bis.close();
				bos.close();
				SetFilePermission.setPermission(file.getAbsolutePath());
			} catch (IOException e) {
				e.printStackTrace();
				log.error("流关闭异常，异常原因:" + e);
			}
		}
		log.info("------------下载影像平台附件结束------------");
		return file;
	}

}
