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

import com.alibaba.fastjson.JSONObject;
import com.bcxin.ins.third.gyx.taibao.util.TbRsaUtils;
import com.bcxin.ins.third.build.taibao.SimplePathResultXMLProcesser;
import com.bcxin.ins.util.DateUtil;
import com.bcxin.ins.util.GlobalResources;
import com.bcxin.ins.util.XMLUtil;
import com.bcxin.ins.vo.*;
import com.bcxin.mybatisplus.toolkit.StringUtils;
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.Date;

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


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

	private static final String AGENCYCODE = "BCX";
	private static final String FUNCTION = "person";
	private static final String PRODUCTCODE = "0200006";

	/**
	 * <b> 请求数据组装 </b>
	 * @author ZXF
	 * @create 2018/03/22 0022 14:43
	 * @version
	 * @注意事项 </b>
	 */
	public static String marshal(GYXPolicyVo policy, OrderFormVo orderVo, String transType, String payType) 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 ( ConstProp.DIGIT_ONE.equals(transType) ) {

				RoleSubjectVo applicants = policy.getRoleSubjectList().get(0);
				RoleSubjectVo insureds = policy.getRoleSubjectList().get(1);
				//项目信息
				Element projectInfo = bodyElement.addElement("project");
				marshalProjectInfo(projectInfo,orderVo);
				//投保人节点
				Element applicant = bodyElement.addElement("applicant");
				marshalApplicants(applicant, applicants);
				//被保险人节点循环
				Element insuredsE = bodyElement.addElement("insureds");
				Element insured = insuredsE.addElement("insured");
				marshalInsureds(insured, insureds);

			} else if( ConstProp.DIGIT_TWO.equals(transType) ){
				//支付信息
				Element payment = bodyElement.addElement("payment");
				marshalPayment(payment,orderVo,payType);
			} else if( ConstProp.DIGIT_FIVE.equals(transType) ){
				//退保信息
				Element endor = bodyElement.addElement("endor");
				marshalEndor(endor,orderVo);
			}
			String requestMsg = requestDocument.asXML();

			return requestMsg;

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

		return null;
	}

	/**
	 * <b> 返回结果报文组装 </b>
	 * @author ZXF
	 * @create 2018/03/22 0022 14:43
	 * @version
	 * @注意事项 </b>
	 */
	public static String marshalResult(OrderFormVo orderVo, JSONObject msgJson) throws Exception {
		if(orderVo == null) {
			return ConstProp.BLANK_CHAR;
		}

		Document requestDocument = DocumentHelper.createDocument();
		requestDocument.setXMLEncoding("UTF-8");
		Element rootElement = requestDocument.addElement("response");
		try {
			//头
			Element headElement = rootElement.addElement("head");
			// 产品代码，必传
			headElement.addElement("productCode").setText(PRODUCTCODE);
			// 订单id，必传
			headElement.addElement("orderNo").setText(orderVo.getTrade_serial_number());
			// 发送时间，必传yyyy-MM-dd HH:mm:ss
			DateFormat dateFormatAll = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			headElement.addElement("transTime").setText(dateFormatAll.format(new Date()));
			// 商户号，必传
			headElement.addElement("agencyCode").setText(AGENCYCODE);
			// 业务类型，必传
			headElement.addElement("businessType").setText("payResult");

			//内容
			Element bodyElement = rootElement.addElement("body");
			//是否成功
			bodyElement.addElement("successInd").setText(String.valueOf(msgJson.get("successInd")));
			//错误代码
			bodyElement.addElement("errorCode").setText(String.valueOf(msgJson.get("errorCode")));
			//错误信息
			bodyElement.addElement("errorMessage").setText(String.valueOf(msgJson.get("errorMessage")));
			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("productCode").setText(PRODUCTCODE);
		// 订单id，必传
		underwrite.addElement("orderNo").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("transTime").setText(dateFormatAll.format(new Date()));
		// 商户号，必传
		underwrite.addElement("agencyCode").setText(AGENCYCODE);
		String bt = ConstProp.BLANK_CHAR;
		if(ConstProp.DIGIT_ONE.equals(transType)){
			// 接口代码，必传
			underwrite.addElement("function").setText(FUNCTION);
			bt = "proposal";
		}else if(ConstProp.DIGIT_TWO.equals(transType)){
			bt = "payRegist";
		}else if(ConstProp.DIGIT_FIVE.equals(transType)){
			bt = "endor";
		}
		// 业务类型，必传
		underwrite.addElement("businessType").setText(bt);
	}
	//项目信息
	private static void marshalProjectInfo(Element underwrite, OrderFormVo orderVo) {
		int days = DateUtil.getDistDates(DateUtil.convertString2Date(orderVo.getInception_date()+ConstProp.DAY_00),DateUtil.convertString2Date(orderVo.getPlanned_end_date()+ConstProp.DAY_23));
		// 承保方案代码
		underwrite.addElement("projectCode").setText(getPCode(days+1));
		// 承保方案名称
		underwrite.addElement("projectName").setText(getPName(days+1));
		// 承保地区
		underwrite.addElement("geographicalArea").setText("00001");
		// 投保时间
		underwrite.addElement("operateDate").setText(orderVo.getStart_time());
		// 起期
		underwrite.addElement("startDate").setText(orderVo.getInception_date()+ConstProp.DAY_00);
		// 止期
		underwrite.addElement("endDate").setText(orderVo.getPlanned_end_date()+ConstProp.DAY_23);
		// 币种
		underwrite.addElement("currency").setText("CNY");
		// 分数
		underwrite.addElement("uwCount").setText("1");
		// 总保额
		underwrite.addElement("sumInsured").setText(orderVo.getInsured_amount());
		// 总保费
		underwrite.addElement("sumPremium").setText(orderVo.getGross_premium());
	}

	/**
	 * <b> 承保方案代码 </b>
	 * @author ZXF
	 * @create 2018/03/06 0006 14:14
	 * @version
	 * @注意事项 </b>
	 */
	private static String getPCode(int days){
		if(days == 1){
			return "0001";
		}else if(days>1&&days<8){
			return "0002";
		}else if(days>7&&days<16){
			return "0003";
		}else if(days>15&&days<31){
			return "0004";
		}else {
			return "";
		}
	}
	private static String getPName(int days){
		if(days == 1){
			return "保安人员极短期个人意险-（1天）";
		}else if(days>1&&days<8){
			return "保安人员极短期个人意险-（2-7天）";
		}else if(days>7&&days<16){
			return "保安人员极短期个人意险-（8-15天）";
		}else if(days>15&&days<31){
			return "保安人员极短期个人意险-（16-30天）";
		}else {
			return "";
		}
	}

	//投保人信息
	private static void marshalApplicants(Element underwrite, RoleSubjectVo applicants) {

		//投保人类型 固定值
		underwrite.addElement("appliType").setText("1");
		//投保人名称(Y)
		underwrite.addElement("appliName").setText(applicants.getName_cn());
		//性别(Y)
		underwrite.addElement("sex").setText("1".equals(applicants.getSex())?"1":"2");
		//证件类型(Y)
		underwrite.addElement("identifyType").setText(getCard(applicants.getId_type()));
		//证件号码(Y)
		underwrite.addElement("identifyNumber").setText(String.valueOf(applicants.getOrganization_code()));
		//出生日期(Y)
		underwrite.addElement("birthDate").setText(String.valueOf(applicants.getBirth_date()));
		//手机号(Y)
		underwrite.addElement("mobilephone").setText(String.valueOf(applicants.getMobile()));
	}
	//支付信息
	private static void marshalPayment(Element underwrite, OrderFormVo orderVo, String payType) {
		//投保单号
		underwrite.addElement("proposalNo").setText(orderVo.getPolicy_serial_number());
		//支付方式（pc 0101,微信 0102）
		underwrite.addElement("payMathod").setText(getPayMathod(payType));
		//支付模板（PC支付：01010001 微信公众号支付：01020001 微信支付: 01020002）
		underwrite.addElement("payModelNo").setText(getPayModelNo(payType));
		//应缴保费金额（单位分，例如，9.99元表示为999）
		underwrite.addElement("amount").setText(String.valueOf((new BigDecimal(orderVo.getGross_premium())).multiply(new BigDecimal("100"))));
		String returnUrl = GlobalResources.DONOW_PATH+"/TBAPI/GYX/syntony-service/"+orderVo.getOid();
		if(ConstProp.BLB.equals(orderVo.getWeb_type())){
			returnUrl = GlobalResources.WEB_URL+"/insurance/gyx/transaction/syntony-service/"+orderVo.getOid();
		}
		//前端回调地址（域名地址）
		underwrite.addElement("pageURL").setText(returnUrl);
	}

	private static String getPayMathod(String pm){
		String result = ConstProp.BLANK_CHAR;
		if("2".equals(pm)){
			result = "0102";
		}else {
			result = "0101";
		}
		return result;
	}
	private static String getPayModelNo(String pm){
		String result = ConstProp.BLANK_CHAR;
		if("2".equals(pm)){
			result = "01020002";
		}else {
			result = "01010001";
		}
		return result;
	}
	//结果信息
	private static void marshalPaymentResult(Element underwrite) {
		//是否成功
		underwrite.addElement("successInd").setText("");
		//错误代码
		underwrite.addElement("errorCode").setText("");
		//错误信息
		underwrite.addElement("errorMessage").setText("");
	}
	//承保信息
	private static void marshalCB(Element underwrite, OrderFormVo orderVo) {
		//投保单号
		underwrite.addElement("proposalNo").setText(orderVo.getPolicy_serial_number());
		//保单号
		underwrite.addElement("policyNo").setText(orderVo.getExternal_reference());
		//电子保单地址
		underwrite.addElement("policyUrl").setText("");
	}
	//退保信息
	private static void marshalEndor(Element underwrite, OrderFormVo orderVo) {
		//保单号
		underwrite.addElement("policyNo").setText(orderVo.getExternal_reference());
		//批改申请单号 TODO?
		underwrite.addElement("applyNo").setText("");
		//批改类型 TODO?
		underwrite.addElement("endorType").setText("0201");
	}
	//被保险人信息
	private static void marshalInsureds(Element underwrite, RoleSubjectVo insureds) {
		//类型 固定值
		underwrite.addElement("insuredType").setText("1");
		//名称(Y)
		underwrite.addElement("insuredName").setText(insureds.getName_cn());
		//性别(Y)
		underwrite.addElement("sex").setText("1".equals(insureds.getSex())?"1":"2");
		//证件类型(Y)
		underwrite.addElement("identifyType").setText(getCard(insureds.getId_type()));
		//证件号码(Y)
		underwrite.addElement("identifyNumber").setText(String.valueOf(insureds.getOrganization_code()));
		/*String ar = "99";
		if(appl.getOrganization_code().equals(insureds.getOrganization_code())){
			ar = "01";
		}*/
		//与投保人的关系
		underwrite.addElement("appliRelation").setText("01");
		//出生日期(Y)
		underwrite.addElement("birthDate").setText(String.valueOf(insureds.getBirth_date()));
		//手机号(Y)
		underwrite.addElement("mobilephone").setText(String.valueOf(insureds.getMobile()));

	}

	/**
	 * 根据我们的证件类型获取太保的证件类型
	 * @param cardType
	 * @return
	 */
	private static String getCard(String cardType){
		if ( "0".equals(cardType) ) {//身份证
			return "01";
		}else if ("3".equals(cardType)) {//护照
			return "02";
		}else if ("4".equals(cardType)) {//台胞证
			return "05";
		}else {
			return "99";
		}
	}

	/**
	 * <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(TbRsaUtils.verifySign(returnXML)){
			String result = xmlProcesser.isGYXSuccess(returnXML);
			logger.info("返回报文解析："+result);
			String[] resultArr = result.split(ConstProp.POUND_SIGN);
			if ( "0000".equals(resultArr[0]) ) {
				if ( ConstProp.DIGIT_ONE.equals(transType) ){
					logger.info(XMLUtil.formatXML(returnXML));
					return "200#"+resultArr[2];
				} else if ( ConstProp.DIGIT_TWO.equals(transType) ){
					logger.info(XMLUtil.formatXML(returnXML));
					return "200#"+resultArr[2]+ConstProp.POUND_SIGN+resultArr[3];
				} else{
					return "300#（APP-TB-002.1）获取业务编码出现异常";
				}
			} else {
				return "300#（APP-GYX-"+resultArr[0]+"）"+resultArr[1];
			}
		} else {
			return "300#（APP-GYX-001）报文签名不匹配";
		}
	}

	/**
	 * <b> 接收报文解析 </b>
	 * @author ZXF
	 * @create 2018/01/30 0030 10:54
	 * @version
	 * @注意事项 </b>
	 */
	public static String resultAnalysisXML(String returnXML, String  transType) throws Exception {
		SimplePathResultXMLProcesser xmlProcesser = new SimplePathResultXMLProcesser();
		if(TbRsaUtils.verifyResultSign(returnXML)){
			String result = xmlProcesser.isGYXResultSuccess(returnXML);
			logger.info("返回报文解析："+result);
			if (StringUtils.isNotEmpty(result)) {
				logger.info(XMLUtil.formatXML(returnXML));
				String[] resultArr = result.split(ConstProp.POUND_SIGN);
				if ( ConstProp.DIGIT_ONE.equals(transType) ){//支付结果
					return "200#"+resultArr[0]+ConstProp.POUND_SIGN+resultArr[3];
				} else if ( ConstProp.DIGIT_TWO.equals(transType) ){//承保结果
					return "200#"+resultArr[0]+ConstProp.POUND_SIGN+resultArr[1]+ConstProp.POUND_SIGN+resultArr[2];
				} else{
					return "300#（APP-TB-002.1）获取业务编码出现异常";
				}
			} else {
				return "300#（APP-GYX-003）报文解析失败";
			}
		} else {
			return "300#（APP-GYX-001）报文签名不匹配";
		}
	}

}
