package cn.hmsoft.pay.impl;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;

import com.chinapay.secss.SecssUtil;

import cn.hmsoft.application.SpringHelper;
import cn.hmsoft.frame.exception.BusinessException;
import cn.hmsoft.helper.BeanHelper;
import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.helper.http.HttpHelper;
import cn.hmsoft.helper.http.HttpRequestEntity;
import cn.hmsoft.log.LogHelper;
import cn.hmsoft.pay.constants.BillProcessResult;
import cn.hmsoft.pay.constants.PayBillStatus;
import cn.hmsoft.pay.data.dao.PayBillDao;
import cn.hmsoft.pay.data.model.PayBill;
import cn.hmsoft.pay.impl.newupay.NewUPayOrderRequest;
import cn.hmsoft.pay.impl.newupay.NewUPayOrderResponse;
import cn.hmsoft.pay.impl.newupay.NewUPayQueryRequest;
import cn.hmsoft.pay.impl.newupay.NewUPayQueryResponse;

public class PayNewUPayChannelImpl extends PayChannelAbstract {
	private String configFilePath = null;
	// private com.chinapay.secss.SecssUtil payUtil = null;
	private static Map<String, String> BankMap = null;

	static {
		synchronized (PayNewUPayChannelImpl.class) {
			BankMap = new HashMap<String, String>();
			BankMap.put("700000000000001", "中国银行");
			BankMap.put("700000000000002", "中国农业银行");
			BankMap.put("700000000000003", "中国工商银行");
			BankMap.put("700000000000004", "中国建设银行");
			BankMap.put("700000000000005", "中国光大银行");
			BankMap.put("700000000000006", "中国交通银行");
			BankMap.put("700000000000007", "浦发银行");
			BankMap.put("700000000000008", "民生银行");
			BankMap.put("700000000000009", "兴业银行");
			BankMap.put("700000000000010", "招商银行");
			BankMap.put("700000000000011", "中国邮政储蓄银行");
			BankMap.put("700000000000012", "广州发展银行");
			BankMap.put("700000000000013", "中信银行");
			BankMap.put("700000000000014", "平安银行");
			BankMap.put("700000000000015", "华夏银行");
			BankMap.put("700000000000016", "北京银行");
			BankMap.put("700000000000017", "银联在线支付");
			BankMap.put("700000000000018", "渤海银行");
			BankMap.put("700000000000019", "深圳发展银行");
			BankMap.put("700000000000020", "东亚银行");
			BankMap.put("700000000000021", "杭州银行");
			BankMap.put("700000000000022", "青岛银行");
			BankMap.put("700000000000023", "上海农商行");
			BankMap.put("700000000000024", "北京农商行");
			BankMap.put("700000000000025", "上海银行");
			BankMap.put("700000000000026", "认证支付");
			BankMap.put("700000000000027", "御航宝");
			BankMap.put("700000000000028", "易商旅");
			BankMap.put("700000000000029", "南航易航宝");
			BankMap.put("700000000000030", "国航易商旅");
			BankMap.put("700000000000031", "万事达国际-建行外卡支付");
			BankMap.put("700000000000032", "福建海峡银行");
			BankMap.put("700000000000033", "富滇银行");
			BankMap.put("700000000000034", "广州银行");
			BankMap.put("700000000000035", "汉口银行");
			BankMap.put("700000000000036", "恒发银行");
			BankMap.put("700000000000037", "河北银行");
			BankMap.put("700000000000038", "浙商银行");
			BankMap.put("700000000000039", "鹤壁银行");
			BankMap.put("700000000000040", "星辰银行");
			BankMap.put("700000000000041", "IBK企业银行");
			BankMap.put("700000000000042", "大新银行");
			BankMap.put("700000000000043", "花旗银行");
			BankMap.put("700000000000044", "徽商银行");
			BankMap.put("700000000000045", "渣打银行");
			BankMap.put("700000000000046", "新韩银行");
			BankMap.put("700000000000047", "大华银行");
			BankMap.put("700000000000048", "晋城银行");
			BankMap.put("700000000000049", "法国兴业银行");
			BankMap.put("700000000000050", "南洋商业银行");
			BankMap.put("700000000000051", "韩亚银行");
			BankMap.put("700000000000052", "晋中市商业银行");
			BankMap.put("700000000000053", "美国运通公司");
			BankMap.put("700000000000054", "万事达国际-农行外卡支付");
			BankMap.put("700000000000055", "九江银行");
			BankMap.put("700000000000056", "永德银行");
			BankMap.put("700000000000057", "大连银行");
			BankMap.put("700000000000058", "德州银行");
			BankMap.put("700000000000059", "东莞银行");
			BankMap.put("700000000000060", "漯河银行");
			BankMap.put("700000000000061", "东营银行");
			BankMap.put("700000000000062", "南京银行");
			BankMap.put("700000000000063", "宁波银行");
			BankMap.put("700000000000064", "宁夏银行");
			BankMap.put("700000000000065", "平顶山银行");
			BankMap.put("700000000000066", "齐鲁银行");
			BankMap.put("700000000000067", "齐商银行");
			BankMap.put("700000000000068", "东海证券");
			BankMap.put("700000000000069", "青海银行");
			BankMap.put("700000000000070", "曲靖市商业银行");
			BankMap.put("700000000000071", "日照银行");
			BankMap.put("700000000000072", "重庆市三峡银行");
			BankMap.put("700000000000073", "厦门银行");
			BankMap.put("700000000000074", "上饶银行");
			BankMap.put("700000000000075", "盛京银行");
			BankMap.put("700000000000076", "顺德农商银行");
			BankMap.put("700000000000077", "苏州银行");
			BankMap.put("700000000000078", "泰安市商业银行");
			BankMap.put("700000000000079", "温州银行");
			BankMap.put("700000000000080", "乌鲁木齐市商业银行");
			BankMap.put("700000000000081", "宜宾市商业银行");
			BankMap.put("700000000000082", "玉溪市商业银行");
			BankMap.put("700000000000083", "张家港农村商业银行");
			BankMap.put("700000000000084", "长沙银行");
			BankMap.put("700000000000085", "中国银联互联网B2B");
			BankMap.put("700000000000086", "重庆农村商业银行");
			BankMap.put("700000000000087", "周口银行");
			BankMap.put("700000000000088", "光大证券");
			BankMap.put("700000000000089", "江苏省农村信用社联合社");
			BankMap.put("700000000000090", "湖南农信");
			BankMap.put("700000000000091", "海南省农村信用社联合社");
			BankMap.put("700000000000092", "广西北部湾银行");
			BankMap.put("700000000000093", "驻马店市商业银行");
			BankMap.put("700000000000094", "成都农村商业银行");
			BankMap.put("700000000000095", "深圳农村商业银行");
			BankMap.put("700000000000096", "威海市商业银行");
			BankMap.put("700000000000097", "江苏银行");
			BankMap.put("700000000000098", "三门峡市商业银行");
			BankMap.put("700000000000099", "东方证券");
			BankMap.put("700000000000100", "宜昌市商业银行");
			BankMap.put("700000000000101", "尧都商行");
			BankMap.put("700000000000102", "威士国际组织-建行外卡");
			BankMap.put("700000000000103", "威士国际组织-农行外卡");
			BankMap.put("700000000000104", "威士国际组织-中行外卡");
			BankMap.put("700000000000106", "银商+快捷账户支付 ");
			BankMap.put("700000000000107", "银商账户支付 ");
			BankMap.put("700000000000108", "快捷账户支付 ");
			BankMap.put("700000000000109", "广发证券 ");
			BankMap.put("700000000000110", "恒泰证券 ");
			BankMap.put("700000000000111", "中投证券 ");
			BankMap.put("700000000000112", "中信证券 ");
			BankMap.put("700000000000121", "珠海农村信用社");
			BankMap.put("700000000000122", "翼支付");
			BankMap.put("700000000000123", "中银通");
			BankMap.put("700000000000124", "银商新一代支付");
			BankMap.put("700000000000125", "商旅平台手机支付");
			BankMap.put("700000000000126", "上海金融IC卡 ");
			BankMap.put("700000000000129", "UPOP2.0前台");
			BankMap.put("700000000000131", "网易商城便民支付");
			BankMap.put("700000000000132", "平安付");
			BankMap.put("700000000000133", "珠海农商银行");
			BankMap.put("700000000000134", "广东南粤银行");
			BankMap.put("700000000000153", "银联全渠道");
		}
	}

	// private static String configFilePath = null;
	@Override
	protected boolean init() throws Exception {
		if (StringHelper.isEmpty(this.payMerchantChannel.getBank_merchant_id()))
			return error("客户编号址为空");
		if (StringHelper.isEmpty(this.payMerchantChannel.getPrivate_key_path()))
			return error("私钥地址为空");
		if (StringHelper.isEmpty(this.payMerchantChannel.getPublic_key_path()))
			return error("公钥地址为空");
		File file = new File(this.payMerchantChannel.getPrivate_key_path());
		if (!file.exists())
			return error("未在指定位置[" + this.payMerchantChannel.getPrivate_key_path() + "]找到私钥文件");
		file = new File(this.payMerchantChannel.getPublic_key_path());
		if (!file.exists())
			return error("未在指定位置[" + this.payMerchantChannel.getPublic_key_path() + "]找到公钥文件");
		// #交易证书路径
		// sign.file=D:/cert_cp/000000000000001.pfx
		// #交易证书密码
		// sign.file.password=XXXXXX
		// #交易证书的密钥容器格式
		// sign.cert.type=PKCS12
		// #报文中不参与签名的字段名称，多个字段用逗号进行分隔
		// sign.invalid.fields=Signature,CertId
		// #验签证书路径
		// verify.file=D:/cert_cp/cp_test.cer
		// #签名值字段名称
		// signature.field=Signature

		Properties prop = new Properties();
		prop.put("sign.file", this.payMerchantChannel.getPrivate_key_path());
		prop.put("sign.file.password", this.payMerchantChannel.getBank_merchant_pass());
		prop.put("sign.cert.type", "PKCS12");
		prop.put("sign.invalid.fields", "Signature,CertId");
		prop.put("verify.file", this.payMerchantChannel.getPublic_key_path());
		prop.put("signature.field", "Signature");
		try {
			file = new File(
					SpringHelper.WebServletContext.getRealPath("/") + File.separator + "WEB-INF" + File.separator
							+ "classes" + File.separator + "NewUPay_" + this.merchant.getMerchant_id() + ".properties");
			BufferedWriter out = new BufferedWriter(new FileWriter(file));
			out.write("sign.file=" + this.payMerchantChannel.getPrivate_key_path());
			out.newLine();
			out.write("sign.file.password=" + this.payMerchantChannel.getBank_merchant_pass());
			out.newLine();
			out.write("sign.cert.type=PKCS12");
			out.newLine();
			out.write("sign.invalid.fields=Signature,CertId");
			out.newLine();
			out.write("verify.file=" + this.payMerchantChannel.getPublic_key_path());
			out.newLine();
			out.write("signature.field=Signature");
			out.close();
		} catch (Exception e) {
			return error("无法保存银联配置文件。");
		}

		SecssUtil payUtil = new com.chinapay.secss.SecssUtil();

		if (!payUtil.init(file.getPath())) {
			return error(payUtil.getErrMsg());
		}
		configFilePath = file.getPath();
		return true;
	}

	@Override
	public String makeBillNo(PayBill bill) {
		String v = StringHelper.leftPadding(bill.getBusiness_id(), 7, '0');
		return LocalDateHelper.formatMilliseconds(LocalDateTime.now()) + v;
	}

	@Override
	public Map<String, String> makeRequestAttr(PayBill bill) {
		NewUPayOrderRequest rq = new NewUPayOrderRequest();
		rq.setMerId(this.getPayMerchantChannel().getBank_merchant_id());
		rq.setMerOrderNo(bill.getBill_no());
		rq.setTranDate(LocalDateHelper.formatNoSplit(bill.getBill_time()));
		rq.setTranTime(LocalDateHelper.formatNoSplit(bill.getBill_time()));
		rq.setOrderAmt(bill.getBill_amount() + "");
		rq.setMerBgUrl(this.getPayMerchantChannel().getNotice_url());
		rq.setRemoteAddr(this.payMerchantChannel.getBank_merchant_name());
		rq.setMerResv(bill.getBill_id() + "");
		if (!StringHelper.isNotEmpty(this.getPayMerchantChannel().getChannel_goods_name()))
			rq.setCommodityMsg(this.getPayMerchantChannel().getChannel_goods_name());
		// com.chinapay.secss.SecssUtil util = new
		// com.chinapay.secss.SecssUtil();
		// if (!util.init(configFilePath))
		// throw new BusinessException("初始化银联接口失败，请检查配置信息。");
		Map<String, String> map = BeanHelper.toStringMap(rq);
		SecssUtil payUtil = new com.chinapay.secss.SecssUtil();
		payUtil.init(configFilePath);
		if (!payUtil.init(configFilePath)) {
			throw new BusinessException("初始化银联接口失败，错误信息为-->" + payUtil.getErrMsg());
		}
		payUtil.sign(map);
		if (!"00".equals(payUtil.getErrCode())) {
			throw new BusinessException("签名过程发生错误，错误信息为-->[" + payUtil.getErrCode() + "]" + payUtil.getErrMsg());
		}
		map.put("Signature", payUtil.getSign());
		return map;
	}

	@Override
	public PayBill processReply(PayBillDao daoBill, PayBill bill, HttpServletRequest request,
			Map<String, Object> paramMap) {

		SecssUtil payUtil = new com.chinapay.secss.SecssUtil();
		if (!payUtil.init(configFilePath)) {
			LogHelper.error("初始化银联接口失败，错误信息为-->" + payUtil.getErrMsg());
			return null;
		}
		payUtil.verify(paramMap);
		if (!"00".equals(payUtil.getErrCode())) {
			LogHelper.error("验签过程发生错误，错误信息为-->[" + payUtil.getErrCode() + "]" + payUtil.getErrMsg());
			return null;
		}
		NewUPayOrderResponse rsq = getRequestEntity(request, NewUPayOrderResponse.class);
		// int bill_id = Integer.parseInt(rsq.getMerResv());
		String OrderStatus = rsq.getOrderStatus();

		if (!OrderStatus.equals("0000")) {
			this.logReply(BillProcessResult.BusiError, bill.getBill_id() + "", request);
			return null;
		}

		LocalDateTime pay_time = null;
		try {
			pay_time = LocalDateHelper.parseDateTimeNoSplit(rsq.getCompleteDate() + rsq.getCompleteTime());
		} catch (Exception e) {

		}
		if (pay_time == null)
			pay_time = LocalDateTime.now();

		String bank_type = rsq.getBankInstNo();
		if (BankMap.containsKey(bank_type))
			bank_type = BankMap.get(bank_type);
		if (bill.getBill_status().equals(PayBillStatus.Request)) {
			try {
				daoBill.completeBill(bill.getBill_id(), pay_time, LocalDateTime.now(), rsq.getAcqSeqId(), bank_type);
			} catch (Exception e) {
				this.logReply(BillProcessResult.DatabaseError, bill.getBill_id() + "", request);
			}
			bill.setBill_status(PayBillStatus.Complete);
			bill.setReply_time(LocalDateTime.now());
			bill.setPay_time(pay_time);
			return bill;
		}
		return null;
	}

	@Override
	public PayBill queryBill(PayBillDao daoBill, PayBill bill) {
		NewUPayQueryRequest rq = new NewUPayQueryRequest();
		rq.setMerId(this.getPayMerchantChannel().getBank_merchant_id());
		rq.setMerOrderNo(bill.getBill_no());
		rq.setTranDate(LocalDateHelper.formatNoSplit(bill.getBill_time()));
		Map<String, Object> map = BeanHelper.toMap(rq);

		com.chinapay.secss.SecssUtil util = new com.chinapay.secss.SecssUtil();
		util.sign(map);
		if (!"00".equals(util.getErrCode())) {
			throw new BusinessException("签名过程发生错误，错误信息为-->" + util.getErrMsg());
		}
		map.put("Signature", util.getSign());
		HttpRequestEntity req = new HttpRequestEntity();
		req.setHttp_url(this.channel.getQuery_url());
		req.setRequestMap(map);

		NewUPayQueryResponse response = HttpHelper.httpRequest(req, NewUPayQueryResponse.class);
		if (!response.getRespCode().equals("0000")) {
			bill.setBill_status(PayBillStatus.QueryError);
			return bill;
		}

		// 判断订单状态
		if (bill.getBill_status().equals(PayBillStatus.Complete)) {
			bill.setBill_status(PayBillStatus.ReComplete);
			return bill;
		}

		LocalDateTime pay_time = null;
		try {
			pay_time = LocalDateHelper.parseDateTimeNoSplit(response.getCompleteDate() + response.getCompleteTime());
		} catch (Exception e) {

		}
		if (pay_time == null)
			pay_time = LocalDateTime.now();

		if (bill.getBill_status().equals(PayBillStatus.Request)) {
			try {
				daoBill.completeBill(bill.getBill_id(), pay_time, LocalDateTime.now(), response.getAcqSeqId());
			} catch (Exception e) {
				e.printStackTrace();
			}
			bill.setBill_status(PayBillStatus.Complete);
			bill.setReply_time(pay_time);
			return bill;
		}
		return null;
	}
}
