package com.bcxin.ins.third.xyx.taibao;

import com.bcxin.ins.third.xyx.yb_enum.YB_City;
import com.bcxin.ins.third.build.taibao.SimplePathResultXMLProcesser;
import com.bcxin.ins.third.build.taibao.TransType;
import com.bcxin.ins.util.*;
import com.bcxin.ins.vo.*;
import com.bcxin.ins.vo.ConstProp;
import com.bcxin.mybatisplus.toolkit.StringUtils;
import com.google.common.collect.Maps;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <b> 太保-信用险各接口请求数据组装 </b>
 * @author ZXF
 * @create 2018/01/30 0030 10:32
 * @version
 * @注意事项 </b>
 */
public class XYX_PackageMessageTaiBao {


	private static Logger logger = LoggerFactory.getLogger(XYX_PackageMessageTaiBao.class);

	private static final String PARTNERCODE = "XMBCX";//合作方
	private static final String TBUSER = "XMBCX";
	private static final String TBPASS = "+kp0LXaWRRWq2bsb/EJR22O2aqjghfCrGe/OaJJheaJttbKcDxlXiDYfpcxLK1fKm75rGAjtNsTFuxt/v/F+Vw==";

	public static String marshal(MicroExportVo policy, OrderFormVo orderVo, RuleXWCKVo ruleXWCKVo, String tb_code, String transType) throws Exception {
		if(policy == null) {
			return ConstProp.BLANK_CHAR;
		}

		Document requestDocument = DocumentHelper.createDocument();
		requestDocument.setXMLEncoding("UTF-8");
		Element rootElement = requestDocument.addElement("request");


		try {
			//头
			Element headElement = rootElement.addElement("head");
			marshalHead(headElement, orderVo, transType);

			//内容
			Element bodyElement = rootElement.addElement("body");
			if ( TransType.EPIC_INS_XW.getValue().equals(transType) ) {
				Element entityElement = bodyElement.addElement("proposalRequest");

				RoleSubjectVo applicants = policy.getRoleSubjectList().get(0);
				//项目信息
				Element projectInfo = entityElement.addElement("projectInfo");
				marshalProjectInfo(projectInfo,applicants,orderVo);
				//项目信息
				Element enterprises = entityElement.addElement("enterprises");
				marshalEnterprises(enterprises,policy,orderVo,applicants);
				//投保单主要信息
				Element proposalMain = entityElement.addElement("proposalMain");
				marshalProposalMain(proposalMain,policy,orderVo,ruleXWCKVo,tb_code);
				//小微特性信息
				Element proposalCharacterMicro = entityElement.addElement("proposalCharacterMicro");
				marshalProposalCharacterMicro(proposalCharacterMicro,policy,orderVo,tb_code);
				// 再保信息
				Element proposalReins = entityElement.addElement("proposalReins");
				marshalProposalReins(proposalReins,policy,orderVo,tb_code);
				// 投保关系人信息
				Element proposalParties1 = entityElement.addElement("proposalParties");
				//被保关系人信息
				Element proposalParties2 = entityElement.addElement("proposalParties");
				marshalProposalParties(proposalParties1,policy,applicants,"1");
				marshalProposalParties(proposalParties2,policy,applicants,"2");
				// 保险费付款计划
				Element proposalPaymentPlans = entityElement.addElement("proposalPaymentPlans");
				marshalProposalPaymentPlans(proposalPaymentPlans,policy,ruleXWCKVo,orderVo);
				// 特别约定列表信息
				Element proposalSpecialAgrees1 = entityElement.addElement("proposalSpecialAgrees");
				Element proposalSpecialAgrees2 = entityElement.addElement("proposalSpecialAgrees");
				Element proposalSpecialAgrees3 = entityElement.addElement("proposalSpecialAgrees");
				marshalProposalSpecialAgrees(proposalSpecialAgrees1,policy,ruleXWCKVo,1);
				marshalProposalSpecialAgrees(proposalSpecialAgrees2,policy,ruleXWCKVo,2);
				marshalProposalSpecialAgrees(proposalSpecialAgrees3,policy,ruleXWCKVo,3);
			}else if ( TransType.EPIC_YX_XW.getValue().equals(transType) ) {
				Element entityElement = bodyElement.addElement("entity");
				RoleSubjectVo applicants = policy.getRoleSubjectList().get(0);
				List<Map<String,String>> list = new ArrayList<Map<String,String>>();
				Map<String,String> map = Maps.newHashMap();
				map.put("name","BusinessLicense");
				map.put("url",applicants.getApp_business_path());
				list.add(map);
				Map<String,String> map2 = Maps.newHashMap();
				map2.put("name","CopyOfLegalPersonIdCard(positive)");
				map2.put("url",applicants.getApp_idcard_path());
				list.add(map2);
				Map<String,String> map3 = Maps.newHashMap();
				map3.put("name","CopyOfLegalPersonIdCard(reverse)");
				map3.put("url",applicants.getApp_idcard_versa_path());
				list.add(map3);
				entityElement.addElement("businessNo").setText(orderVo.getPolicy_serial_number());
				entityElement.addElement("uploadTime").setText(DateUtil.getCurrentDateTime());
				entityElement.addElement("zipInfo").setText(FileBatchUtil.dealErJinZhiFile(String.valueOf(System.currentTimeMillis()),list));
			}else if ( TransType.EPIC_CB_XW.getValue().equals(transType) ) {
				bodyElement.addElement("proposalNo").setText(orderVo.getPolicy_serial_number());
			}else if ( TransType.EPIC_DZBD_XW.getValue().equals(transType) ) {
				RoleSubjectVo inst = policy.getRoleSubjectList().get(1);
				bodyElement.addElement("epolicyNumber").setText(orderVo.getExternal_reference());
				bodyElement.addElement("idNumber").setText(String.valueOf(inst.getOrganization_code().replace(ConstProp.MINUS,ConstProp.BLANK_CHAR)));
				bodyElement.addElement("servicesType").setText(ConstProp.DIGIT_ONE);
			}
			String requestMsg = requestDocument.asXML();

			return requestMsg;

		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	private static void marshalHead(Element underwrite, OrderFormVo orderVo,String transType) {
		// 合作方编码，必传
		underwrite.addElement("partnerCode").setText(PARTNERCODE);
		// 业务交易码，必传
		underwrite.addElement("transactionCode").setText(transType);
		// 交易流水号，必传
		underwrite.addElement("messageId").setText(orderVo.getTrade_serial_number());
		// 交易时间，必传yyyy-MM-dd HH:mm:ss
		DateFormat dateFormatAll = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		underwrite.addElement("transactionEffectiveDate").setText(dateFormatAll.format(new Date()));
		// 合作方用户，必传
		underwrite.addElement("user").setText(TBUSER);
		// 用户密码，必传
		underwrite.addElement("password").setText(TBPASS);

	}
	//项目信息
	private static void marshalProjectInfo(Element underwrite, RoleSubjectVo applicants, OrderFormVo orderVo) {
		// 项目编号
		underwrite.addElement("projectNo").setText(String.valueOf(System.currentTimeMillis()));
		// 区域
		underwrite.addElement("area").setText(YB_City.fromCode(applicants.getReg_city())+YB_City.fromYBCity(applicants.getReg_city()).getValue());
		// 企业白名单信息编号
		underwrite.addElement("enterpriseWhiteNo").setText(applicants.getCustoms_code());
		// 订单编号
		underwrite.addElement("orderNo").setText(orderVo.getTrade_serial_number());
		// 系统来源
		underwrite.addElement("sourceSys").setText("BAICHUANXIN");
	}
	//投保单主要信息
	private static void marshalProposalMain(Element underwrite, MicroExportVo policy, OrderFormVo orderVo, RuleXWCKVo ruleXWCKVo,String tb_code) {
		// 险种代码
		underwrite.addElement("riskCode").setText("13081500");
		// 险种名称
		underwrite.addElement("riskName").setText("小微企业出口信用保险");
		// 承保方式
		underwrite.addElement("underwritingTypeCode").setText("1");
		// 是否分别管理买家
		underwrite.addElement("separateManageFlag").setText("0");
		// 与被保险人关系
		underwrite.addElement("mainInsurantRelationCode").setText("01");
		// 是否异地承保
		underwrite.addElement("remoteUnderwritingFlag").setText("0");
		// 分公司代码
		underwrite.addElement("branchCode").setText(tb_code);
		// 考核经办人代码
		underwrite.addElement("assessmentManagerCode").setText("1268");
		// 展业方式
		underwrite.addElement("businessNatureCode").setText("12");
		// 保险起期
		underwrite.addElement("startDate").setText(orderVo.getInception_date());
		// 保险止期
		underwrite.addElement("endDate").setText(orderVo.getPlanned_end_date());
		// 投保日期
		underwrite.addElement("proposalDate").setText(orderVo.getStart_time());
		// 起期时刻
		underwrite.addElement("startHour").setText("0");
		// 止期时刻
		underwrite.addElement("endHour").setText("24");
		// 签发日期
		underwrite.addElement("signDate").setText(DateUtil.getCurrentDate());
//		 生效日期
		underwrite.addElement("validDate").setText(orderVo.getInception_date());
		// 承保基础
		underwrite.addElement("underwritingBasisCode").setText("002");
		// 司法管辖
		underwrite.addElement("jurisdictionCode").setText("002");
		String ds = policy.getDisputes().equals("0")?"1":"0";
		// 争议解决方式
		underwrite.addElement("disputeResolutionCode").setText(ds);
		if("0".equals(ds)){//仲裁
			String aiCode = arbitrationInstitutionsCode(policy.getArbitral_institution());
			String aiName = ConstProp.BLANK_CHAR;
			if(aiCode.equals("100")){
				aiCode = "99";
			}
			if(aiCode.equals("99")){
				aiName = "null".equals(policy.getArbitral_institution()) ? ""
						: StringUtils.isEmpty(policy.getArbitral_institution()) ? ""
						: policy.getArbitral_institution();
			}
			// 仲裁机构
			underwrite.addElement("arbitrationInstitutionsCode").setText(aiCode);
			// 仲裁机构其它
			underwrite.addElement("arbitrationInstitutionsOther").setText(String.valueOf(aiName));
		}else{//诉讼
			// 诉讼地址
			underwrite.addElement("lawsuitAddress").setText(String.valueOf(RegionUtils.getRegionNameByALLCode(policy.getLawsuit_province(),policy.getLawsuit_city(),policy.getLawsuit_area())+policy.getLawsuit_address()));
			// 诉讼机构
			underwrite.addElement("lawsuitInstitutions").setText(String.valueOf(policy.getLawsuit_institution()));
		}
		// 是否涉农
		underwrite.addElement("agricultureFlag").setText("0");
		// 系统出单
		underwrite.addElement("systemIssueCode").setText("1");
		// 保单打印方式 TODO ?
		underwrite.addElement("policyPrintTypeCode").setText("0");
		// 是否融资型业务
		underwrite.addElement("provideFinancingFlag").setText("0");
		// 主条款名称
		underwrite.addElement("mainClauseName").setText("小微企业出口贸易短期信用综合保险");
		// 主条款代码
		underwrite.addElement("mainClauseCode").setText("3");
		// 保单计费基础
		underwrite.addElement("quotingBasedCode").setText("01");
		// 预缴保费方式
		underwrite.addElement("prepayPremiumTypeCode").setText("01");
		// 保险期间预估投保营业额
		underwrite.addElement("estimatedInsuredTurnover").setText(policy.getExport_amount());
		BigDecimal medialRate = BigDecimal.valueOf(Double.parseDouble(ruleXWCKVo.getRate()));
		BigDecimal estimatedPremium = ((BigDecimal.valueOf(Double.parseDouble(policy.getExport_amount()))).multiply(medialRate)).setScale(2,BigDecimal.ROUND_HALF_UP);
		// 含税平均费率 TODO ?
//		underwrite.addElement("medialRate").setText(String.valueOf(medialRate));
		// 保险期间预计保险费总额（含税） TODO ?
		underwrite.addElement("estimatedPremium").setText(String.valueOf(estimatedPremium));
		BigDecimal minPremium = (BigDecimal.valueOf(Double.parseDouble(ruleXWCKVo.getPremium_min()))).compareTo(estimatedPremium) >= 0 ? (BigDecimal.valueOf(Double.parseDouble(ruleXWCKVo.getPremium_min()))) : estimatedPremium;
		// 保险期间的最低保险费总额（含税） TODO ?
		underwrite.addElement("minPremium").setText(String.valueOf(minPremium));
		// 是否见费出单
		underwrite.addElement("contractAfterPayFlag").setText("0");
		// 保单币种
		underwrite.addElement("currency").setText(policy.getAnnual_currency().equals("0")?"02":"01");
		// 共保标志
		underwrite.addElement("coinsFlag").setText("0");

	}
	private static String arbitrationInstitutionsCode(String val){
		if(StringUtils.isNotEmpty(val)){
			if(val.equals("中国国际经济贸易仲裁委员会北京分会")){
				return "01";
			}else if(val.equals("中国国际经济贸易仲裁委员会上海分会")){
				return "02";
			}else if(val.equals("中国国际经济贸易仲裁委员会华南分会")){
				return "03";
			}else{
				return "99";
			}
		}else{
			return "100";
		}
	}

	//小微特性信息
	private static void marshalProposalCharacterMicro(Element underwrite, MicroExportVo policy, OrderFormVo orderVo,String tb_code) {
		//增值税承保标志
		underwrite.addElement("addedTaxFlag").setText("0");
		//就逾期欠款向本公司发出通知的最后期限（类型）
		underwrite.addElement("overdueDeadlineTypeCode").setText("01");
		//就逾期欠款向本公司发出通知的最后期限（天数）
		underwrite.addElement("overdueDeadlineDays").setText("30");
		//承保除外（500字）
		underwrite.addElement("excludingInsuredDesc").setText("向古巴、伊朗、北朝鲜、苏丹、利比亚、也门、叙利亚、阿富汗、伊拉克、索马里、布隆迪、科摩罗、刚果民主共和国、俄罗斯、利比里亚、塞拉利昂、津巴布韦、巴勒斯坦、阿尔巴尼亚等国家或地区出口的业务除外");
		//上年海关出口金额币种
		underwrite.addElement("customCurrency").setText(policy.getAnnual_currency().equals("0")?"02":"01");
		//上年海关出口金额
		underwrite.addElement("customAmount").setText(String.valueOf(policy.getExport_amount()));
		//适保范围（300字）
		underwrite.addElement("majorExportCommodities").setText("本保险单有效期内被保险人与买方签订销售合同并以被保险人名义报关出口的全部出口业务");
		//上年出口未收汇币种
		underwrite.addElement("exchangeCurrency").setText(policy.getAnnual_currency().equals("0")?"02":"01");
		//上年出口未收汇金额
		underwrite.addElement("exchangeAmount").setText(String.valueOf(policy.getUncollected_amount()));
		//未收汇原因（300字）
		underwrite.addElement("exDividendReason").setText(String.valueOf(policy.getUncollected_cause()));
		//保险期间内最高责任限额类型（IML）
		underwrite.addElement("maxLiabilityCode").setText("01");
		//保险期间内最高责任限额（IML） TODO ....
		underwrite.addElement("maxLiability").setText(String.valueOf(policy.getInsured_amount()));
		//单一买方/开证行赔付金额上限类型
		underwrite.addElement("maxPaymentCode").setText("01");
		//单一买方/开证行赔付金额上限 TODO ....
		underwrite.addElement("maxPayment").setText(String.valueOf(policy.getPay_limit()));
		//对被保险人自定信用限额的承保比例
		underwrite.addElement("custCreditLimitInsRatio").setText(String.valueOf(((BigDecimal.valueOf(Double.parseDouble(policy.getPro_rata()))).multiply(BigDecimal.valueOf(Double.parseDouble("100"))).setScale(0,BigDecimal.ROUND_HALF_UP))));
	}

	//再保信息
	private static void marshalProposalReins(Element underwrite, MicroExportVo policy, OrderFormVo orderVo,String tb_code) {
		//是否回分标志
		underwrite.addElement("returnFlag").setText("0");
	}
	//投保关系人信息 TODO ?
	private static void marshalProposalParties(Element underwrite, MicroExportVo policy, RoleSubjectVo applicants,String tc) {
		//序列号
		underwrite.addElement("serialNo").setText("1");
		//名称
		underwrite.addElement("partyName").setText(String.valueOf(applicants.getName_cn()));
		//关系人类型
		underwrite.addElement("partyTypeCode").setText(tc);
		//主要参与方标志
		underwrite.addElement("mainInsurantFlag").setText("1");
		//营业地址
		underwrite.addElement("businessAddress").setText(RegionUtils.getRegionNameByALLCode(applicants.getReg_province(),applicants.getReg_city(),applicants.getReg_district())+applicants.getReg_address());

	}
	//保险费付款计划
	private static void marshalProposalPaymentPlans(Element underwrite, MicroExportVo policy, RuleXWCKVo ruleXWCKVo, OrderFormVo orderVo) {
		//交费期次
		underwrite.addElement("payNo").setText("1");
		//币种
		underwrite.addElement("currency").setText(policy.getAnnual_currency().equals("0")?"02":"01");
		//计划交费日期  TODO ?
		underwrite.addElement("plandate").setText(DateUtil.getThisYearLastDay());
		String planFeeRatio = "100";
		//计划缴费比例 (%)
		underwrite.addElement("planFeeRatio").setText(planFeeRatio);
		BigDecimal medialRate = BigDecimal.valueOf(Double.parseDouble(ruleXWCKVo.getRate()));
		BigDecimal estimatedPremium = ((BigDecimal.valueOf(Double.parseDouble(policy.getExport_amount()))).multiply(medialRate)).setScale(2,BigDecimal.ROUND_HALF_UP);
		BigDecimal planFee = estimatedPremium.multiply(BigDecimal.valueOf(Double.parseDouble(planFeeRatio))).divide(BigDecimal.valueOf(Double.parseDouble("100"))).setScale(2,BigDecimal.ROUND_HALF_UP);
		//计划交费金额(计划缴费金额如果按预计保费的话，要等于保险期间的预计保险费总额（含税）* 计划缴费比例)
		underwrite.addElement("planFee").setText(String.valueOf(planFee));
	}
	//特别约定列表信息
	private static void marshalProposalSpecialAgrees(Element underwrite, MicroExportVo policy, RuleXWCKVo ruleXWCKVo,int type) {
		if(type == 1){
			//特别约定名称
			underwrite.addElement("specialClauseName").setText("单一买方/开证行最高赔付上限");
			//特别约定说明
			underwrite.addElement("specialClauseDesc").setText((Integer.parseInt(policy.getPay_limit())/10000)+"万美元，不支持单独申请限额；赔付比例："+((BigDecimal.valueOf(Double.parseDouble(policy.getPro_rata()))).multiply(BigDecimal.valueOf(Double.parseDouble("100")))).setScale(0,BigDecimal.ROUND_HALF_UP)+"%");
		}else if(type == 2){
			//特别约定名称
			underwrite.addElement("specialClauseName").setText("保单最高赔偿限额");
			//特别约定说明
			underwrite.addElement("specialClauseDesc").setText("年度保险费的"+(BigDecimal.valueOf(Double.parseDouble(ruleXWCKVo.getCompensation_multiple())).setScale(0,BigDecimal.ROUND_HALF_UP))+"倍");
		}else if(type == 3){
			//特别约定名称
			underwrite.addElement("specialClauseName").setText("其他");
			//特别约定说明
			underwrite.addElement("specialClauseDesc").setText("依据厦门市小规模出口企业统保相关规定， 本保单项下投保营业额为上年报关出口总金额。");
		}
	}
	//企业信息
	private static void marshalEnterprises(Element underwrite, MicroExportVo policy, OrderFormVo orderVo,RoleSubjectVo applicants) {
		//序号
		underwrite.addElement("serialNo").setText("1");
		//国别
		underwrite.addElement("countryCode").setText("CN");
		//企业名称
		underwrite.addElement("customerName").setText(String.valueOf(applicants.getName_cn()));
		//省
		underwrite.addElement("province").setText(YB_City.fromCode(applicants.getReg_city()));
		//城市
		underwrite.addElement("city").setText(YB_City.fromYBCity(applicants.getReg_city()).getValue());
		//街道
		underwrite.addElement("street").setText(applicants.getReg_address());
		//证件类型
		underwrite.addElement("idTypeCode").setText(ConstProp.DIGIT_ONE.equals(applicants.getId_type()) ? "CN_OCCN"
				: ConstProp.DIGIT_TWO.equals(applicants.getId_type()) ? "CN_USCC" : ConstProp.BLANK_CHAR);
		//证件号码
		underwrite.addElement("idNumber").setText(String.valueOf(applicants.getOrganization_code().replace(ConstProp.MINUS,ConstProp.BLANK_CHAR)));
		//欧盟行业大类
		underwrite.addElement("industryType").setText("0000");
		//海关统计经营单位编码
		underwrite.addElement("customesUnitId").setText(String.valueOf(applicants.getCustoms_code()));
		//注册地址
		underwrite.addElement("registeredAddress").setText(RegionUtils.getRegionNameByALLCode(applicants.getReg_province(),applicants.getReg_city(),applicants.getReg_district())+applicants.getReg_address());
		//法人代表
		underwrite.addElement("legalRepresent").setText(applicants.getLegal_name());
		//电话号码
		underwrite.addElement("telephone").setText(applicants.getLegal_phone());
		//企业上年度总营业额
		underwrite.addElement("enterpriseTurnover").setText(policy.getExport_amount());
		//邮编
		underwrite.addElement("postCode").setText(YB_City.fromYBCity(applicants.getReg_city()).getValue());
		//电子邮件
		underwrite.addElement("email").setText(applicants.getLink_email());
		//雇员人数
		underwrite.addElement("employeesNum").setText(policy.getPerson_num());

	}

	/**
	 * <b> 返回报文解析 </b>
	 * @author ZXF
	 * @create 2018/01/30 0030 10:54
	 * @version
	 * @注意事项 </b>
	 */
	public static String returnAnalysisXML(String returnXML, String  transType) throws Exception {
		SimplePathResultXMLProcesser xmlProcesser = new SimplePathResultXMLProcesser();
		if ( !xmlProcesser.isTBSuccess(returnXML) ) {
			return "300#（APP-XWCK-005）"+xmlProcesser.isTBFailMessage(returnXML);
		}
		if ( TransType.EPIC_INS_XW.getValue().equals(transType) ){
			String result = xmlProcesser.getXYXPolicyMsg(returnXML);
			String[] arr = result.split(ConstProp.POUND_SIGN);
			if(!"0000".equals(arr[0])){
				return "300#（APP-XWCK-"+arr[0]+"）"+arr[1];
			}
			logger.info(XMLUtil.formatXML(returnXML));
			return "200#"+arr[2];
		} else if ( TransType.EPIC_YX_XW.getValue().equals(transType) ){
			logger.info(XMLUtil.formatXML(returnXML));
			return "200#上传成功";
		} else if ( TransType.EPIC_CB_XW.getValue().equals(transType) ){
			String result = xmlProcesser.getXYXPolicyMsgCB(returnXML);
			String[] arr = result.split(ConstProp.POUND_SIGN);
			if(!"000000".equals(arr[0])){
				return "300#（APP-XWCK-"+arr[0]+"）"+arr[1];
			}
			logger.info(XMLUtil.formatXML(returnXML));
			return "200#"+arr[2];
		} else if ( TransType.EPIC_DZBD_XW.getValue().equals(transType) ){
			String result = xmlProcesser.getXYXPolicyDZBD(returnXML);
			String[] arr = result.split(ConstProp.POUND_SIGN);
			if(!ConstProp.DIGIT_ZERO.equals(arr[0])){
				return "300#（APP-XWCK-12004601）"+arr[1];
			}
			logger.info(XMLUtil.formatXML(returnXML));
			return "200#"+arr[2];
		}else{
			return "300#（APP-XWCK-002.1）获取业务编码出现异常";
		}
	}
}
