package com.keao.edu.thirdparty.eseal.provider;

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.keao.edu.thirdparty.eseal.ESealPlugin;
import com.keao.edu.thirdparty.exception.ThirdpartyException;
import com.timevale.esign.sdk.tech.bean.AccountProfile;
import com.timevale.esign.sdk.tech.bean.OrganizeBean;
import com.timevale.esign.sdk.tech.bean.PersonBean;
import com.timevale.esign.sdk.tech.bean.PosBean;
import com.timevale.esign.sdk.tech.bean.SignPDFFileBean;
import com.timevale.esign.sdk.tech.bean.result.AddAccountResult;
import com.timevale.esign.sdk.tech.bean.result.AddSealResult;
import com.timevale.esign.sdk.tech.bean.result.FileDigestSignResult;
import com.timevale.esign.sdk.tech.bean.result.GetAccountProfileResult;
import com.timevale.esign.sdk.tech.bean.result.Result;
import com.timevale.esign.sdk.tech.bean.seal.OrganizeTemplateType;
import com.timevale.esign.sdk.tech.bean.seal.PersonTemplateType;
import com.timevale.esign.sdk.tech.bean.seal.SealColor;
import com.timevale.esign.sdk.tech.impl.constants.LegalAreaType;
import com.timevale.esign.sdk.tech.impl.constants.LicenseQueryType;
import com.timevale.esign.sdk.tech.impl.constants.OrganRegType;
import com.timevale.esign.sdk.tech.impl.constants.SignType;
import com.timevale.esign.sdk.tech.service.AccountService;
import com.timevale.esign.sdk.tech.service.SealService;
import com.timevale.esign.sdk.tech.service.SelfSignService;
import com.timevale.esign.sdk.tech.service.UserSignService;
import com.timevale.esign.sdk.tech.v3.client.ServiceClient;
import com.timevale.esign.sdk.tech.v3.client.ServiceClientManager;
import com.timevale.tech.sdk.bean.ProjectConfig;

@Service
public class TsignPlugin implements ESealPlugin, InitializingBean, DisposableBean {

	@Value("${eseal.tsign.projectid:4438776254}")
	public String projectId; // = "1111563517";

	@Value("${eseal.tsign.projectSecret:a94cf63d6361084d232f345d71321691}")
	public String projectSecret; // = "95439b0863c241c63a861b87d1e647b7";

	@Value("${eseal.tsign.apisUrl:http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2}")
	public String apisUrl; // = "http://smlitsm.tsign.cn:8080/tgmonitor/rest/app!getAPIInfo2";

	private ServiceClient serviceClient;

	public static String getName() {
		return "Tsign";
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		ProjectConfig projectconfig = new ProjectConfig();
		projectconfig.setProjectId(projectId);
		projectconfig.setProjectSecret(projectSecret);
		projectconfig.setItsmApiUrl(apisUrl);
		Result result = ServiceClientManager.registClient(projectconfig, null, null);
		if (result.getErrCode() != 0) {
			throw new ThirdpartyException("e签宝客户端注册失败:{}", result.getMsg());
		}

		serviceClient = ServiceClientManager.get(projectId);
		if (serviceClient == null) {
			throw new ThirdpartyException("获取e签宝客户端失败");
		}
	}

	@Override
	public void destroy() throws Exception {
		ServiceClientManager.shutdown(projectId);
	}

	/**
	 * 创建用户账户(个人)
	 * @param realName 姓名
	 * @param idcard 身份证号码
	 * @param mobile 手机号码
	 * @return e签宝账户唯一标识
	 */
	public String createUserAccount(String realName, String idcard, String mobile) {
		PersonBean personbean = new PersonBean();
		personbean.setName(realName);
		personbean.setIdNo(idcard);
		personbean.setMobile(mobile);
		personbean.setPersonArea(LegalAreaType.MAINLAND);
		// personbean.setPersonArea(4);
		AccountService service = serviceClient.accountService();
		AddAccountResult result = service.addAccount(personbean);
		if (result.getErrCode() == 0) {
			return result.getAccountId();
		} else if (result.getErrCode() == 1500012) {
			return queryAccountIdByIdNo(idcard);
		}
		throw new ThirdpartyException(result.getMsg());
	}

	/**
	 * 创建用户账户(企业)
	 * @param orgName  机构名称
	 * @param organCode 统一社会信用代码
	 * @return e签宝账户唯一标识
	 */
	public String createOrganAccount(String orgName, String organCode) {
		OrganizeBean organizeBean = new OrganizeBean();
		organizeBean.setName(orgName);
		organizeBean.setOrganCode(organCode);
		organizeBean.setRegType(OrganRegType.MERGE);
		organizeBean.setUserType(0);

		AccountService service = serviceClient.accountService();
		AddAccountResult result = service.addAccount(organizeBean);
		if (result.getErrCode() == 0) {
			return result.getAccountId();
		}
		throw new ThirdpartyException("创建企业账户接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
	}

	/**
	 * 创建印章
	 * @param accountId e签宝账户唯一标识
	 * @return 电子印章数据
	 */
	public String createUserSeal(String accountId) {
		// 生成模板印章的颜色
		SealColor color = SealColor.RED;
		SealService service = serviceClient.sealService();
		AddSealResult result = service.addTemplateSeal(accountId, PersonTemplateType.RECTANGLE, color);
		if (0 == result.getErrCode()) {
			return result.getSealData();
		}
		throw new ThirdpartyException("个人模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
	}

	@Override
	public String createOrganSeal(String accountId, String hText, String qText) {
		// 生成模板印章的颜色
		SealColor color = SealColor.RED;
		SealService service = serviceClient.sealService();
		AddSealResult result = service.addTemplateSeal(accountId, OrganizeTemplateType.STAR, color, hText, qText);
		if (0 == result.getErrCode()) {
			return result.getSealData();
		}
		throw new ThirdpartyException("企业模板印章接口调用失败code=" + result.getErrCode() + "msg=" + result.getMsg());
	}

	/**
	 * 平台自身PDF摘要签署（印章标识）
	 * @param srcPdfPath 源文件
	 * @param destPdfPath 签名后的目标文件
	 * @return
	 */
	public boolean platformSign(String srcPdfPath, String destPdfPath) {
		PosBean posBean = new PosBean();
		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
		SignType signType = SignType.Key;
		// 接口调用方(平台方)的印章,请在www.tsign.cn官网中设置默认印章其sealId值为0
		int sealId = 0;
		// 设置接口调用方(平台方)签章位置信息
		posBean.setPosPage("1");// 签署页码，若为多页签章，支持页码格式“1-3,5,8“，若为坐标定位时，不可空
		posBean.setKey("甲方签章");
		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
		posBean.setPosX(100);
		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
		posBean.setPosY(0);
		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
		posBean.setWidth(100);
		SignPDFFileBean PDFbean = new SignPDFFileBean();
		PDFbean.setSrcPdfFile(srcPdfPath);
		PDFbean.setDstPdfFile(destPdfPath);

		SelfSignService service = serviceClient.selfSignService();
		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealId, signType);
		if (0 != result.getErrCode()) {
			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败！Code=" + result.getErrCode() + "MSG=" + result.getMsg());
		}
		return true;
	}

	/**
	 * 企业PDF摘要签署（印章图片）
	 * @param sealData 电子印章数据
	 * @param srcPdfPath 源文件
	 * @param destPdfPath 签名后的目标文件
	 * @return
	 */
	public boolean organSign(String sealData, String srcPdfPath, String destPdfPath) {
		PosBean posBean = new PosBean();
		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
		SignType signType = SignType.Key;
		// 设置接口调用方(平台方)签章位置信息
		posBean.setPosPage("1");// 签署页码，若为多页签章，支持页码格式“1-3,5,8“，若为坐标定位时，不可空
		posBean.setKey("甲方签章");
		// 签署位置X坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面左端的横向移动距离,单位为px
		posBean.setPosX(100);
		// 签署位置Y坐标,默认值为0,以pdf页面的左下角作为原点,控制距离页面底端的纵向移动距离,单位为px
		posBean.setPosY(0);
		// 印章图片在PDF文件中的等比缩放大小,公章标准大小为4.2厘米即159px
		posBean.setWidth(100);
		SignPDFFileBean PDFbean = new SignPDFFileBean();
		PDFbean.setSrcPdfFile(srcPdfPath);
		PDFbean.setDstPdfFile(destPdfPath);

		SelfSignService service = serviceClient.selfSignService();
		FileDigestSignResult result = service.localSignPdf(PDFbean, posBean, sealData, signType);
		if (0 != result.getErrCode()) {
			throw new ThirdpartyException("平台自身PDF摘要签署接口调用失败！Code=" + result.getErrCode() + "MSG=" + result.getMsg());
		}
		return true;
	}

	/**
	 * 用户签名
	 * @param accountId e签宝账户唯一标识
	 * @param sealData 电子印章数据
	 * @param srcPdfPath 平台签名后的源文件
	 * @param destPdfPath 平台、用户都签名后的文件地址
	 * @return
	 */
	public boolean userSign(String accountId, String sealData, String srcPdfPath, String destPdfPath) {

		SignPDFFileBean signPDFStreamBean = new SignPDFFileBean();
		// C:test_signed.pdf为平台自身签署后路径
		signPDFStreamBean.setSrcPdfFile(srcPdfPath);
		signPDFStreamBean.setDstPdfFile(destPdfPath);
		PosBean posBean = new PosBean();
		posBean.setPosPage("1");
		posBean.setPosType(1);
		posBean.setWidth(80);
		posBean.setKey("乙方签章");
		posBean.setPosX(100);
		posBean.setPosY(0);

		// 签章类型,Single-单页签章、Multi-多页签章、Edges-骑缝章、Key-关键字签章
		SignType signtype = SignType.Key;
		UserSignService service = serviceClient.userSignService();
		FileDigestSignResult result = service.localSignPDF(accountId, sealData, signPDFStreamBean, posBean, signtype);
		if (result.getErrCode() == 0) {
			return true;
		}
		throw new ThirdpartyException("平台用户PDF摘要签署接口调用失败" + result.getErrCode() + "msg=" + result.getMsg());
	}

	private String queryAccountIdByIdNo(String idcardNo) {

		AccountService service = serviceClient.accountService();

		GetAccountProfileResult result = service.getAccountInfoByIdNo(idcardNo, LicenseQueryType.MAINLAND);

		if (result != null) {
			AccountProfile accountProfile = result.getAccountInfo();
			if (accountProfile != null) {
				return accountProfile.getAccountUid();
			}
		}

		return null;
	}
}
