package cn.hmsoft.pay.impl;

import java.io.File;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;

import com.unionpay.acp.sdk.AcpService;
import com.unionpay.acp.sdk.SDKConfig;

import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.helper.StringHelper;
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;

public class PayUPayAcpChannelImpl extends PayChannelAbstract {

	// private static String configFilePath = null;

	// private com.chinapay.secss.SecssUtil payUtil = null;

	// 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();

		try {
			prop.put("acpsdk.frontTransUrl", this.getChannel().getPay_url());
			prop.put("acpsdk.backTransUrl", this.getChannel().getRefund_url());
			prop.put("acpsdk.version", this.getChannel().getPublic_version());
			prop.put("acpsdk.signMethod", "01");
			if (this.payMerchantChannel.getNotice_url() != null)
				prop.put("acpsdk.backUrl", this.payMerchantChannel.getNotice_url());
			if (this.payMerchantChannel.getPage_url() != null)
				prop.put("acpsdk.frontUrl", this.payMerchantChannel.getPage_url());

			prop.put("acpsdk.signCert.path", this.payMerchantChannel.getPrivate_key_path());

			prop.put("acpsdk.signCert.pwd", this.payMerchantChannel.getBank_merchant_pass());
			prop.put("acpsdk.signCert.type", "PKCS12");
			prop.put("acpsdk.validateCert.dir", this.payMerchantChannel.getPublic_key_path());

			prop.put("acpsdk.rootCert.path",
					this.payMerchantChannel.getPublic_key_path() + File.separator + "acp_prod_root.cer");
			prop.put("acpsdk.encryptCert.path",
					this.payMerchantChannel.getPublic_key_path() + File.separator + "acp_prod_enc.cer");

			prop.put("acpsdk.middleCert.path",
					this.payMerchantChannel.getPublic_key_path() + File.separator + "acp_prod_middle.cer");

			prop.put("acpsdk.signCert.path", this.payMerchantChannel.getPrivate_key_path());
		} catch (Exception e) {
			e.printStackTrace();
			return error("未知错误，" + e.getMessage());
		}
		SDKConfig.getConfig().loadProperties(prop);
		return true;
	}

	@Override
	public String makeBillNo(PayBill bill) {
		String v = StringHelper.leftPadding(bill.getBusiness_id(), 7, '0');
		return LocalDateHelper.formatMilliseconds(LocalDateTime.now()) + v;
		// return "NUPay_" + bill.getBusiness_type() + "_"
		// + DateHelper.format(DateHelper.LongDateStringWithoutSplit)
		// + "_" + v;
	}

	@Override
	public Map<String, String> makeRequestAttr(PayBill bill) {
		// 前台页面传过来的
		String merId = this.getPayMerchantChannel().getBank_merchant_id();
		String txnAmt = bill.getBill_amount() + "";
		String orderId = bill.getBill_no();
		String txnTime = LocalDateHelper.formatLongNoSplit(LocalDateTime.now());

		Map<String, String> requestData = new HashMap<String, String>();

		/*** 银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改 ***/
		requestData.put("version", SDKConfig.getConfig().getVersion()); // 版本号，全渠道默认值
		requestData.put("encoding", "UTF-8"); // 字符集编码，可以使用UTF-8,GBK两种方式
		requestData.put("signMethod", SDKConfig.getConfig().getSignMethod()); // 签名方法
		requestData.put("txnType", "01"); // 交易类型 ，01：消费
		requestData.put("txnSubType", "01"); // 交易子类型， 01：自助消费
		requestData.put("bizType", "000201"); // 业务类型，B2C网关支付，手机wap支付
		requestData.put("channelType", "07"); // 渠道类型，这个字段区分B2C网关支付和手机wap支付；07：PC,平板
												// 08：手机

		/*** 商户接入参数 ***/
		requestData.put("merId", merId); // 商户号码，请改成自己申请的正式商户号或者open上注册得来的777测试商户号
		requestData.put("accessType", "0"); // 接入类型，0：直连商户
		requestData.put("orderId", orderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
		/// 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
		requestData.put("txnTime", txnTime); // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
		requestData.put("currencyCode", "156"); // 交易币种（境内商户一般是156 人民币）
		requestData.put("txnAmt", txnAmt); // 交易金额，单位分，不要带小数点

		requestData.put("reqReserved", bill.getBill_id() + "");

		requestData.put("frontUrl", SDKConfig.getConfig().getFrontRequestUrl());
		requestData.put("backUrl", SDKConfig.getConfig().getBackUrl());

		requestData.put("payTimeout",
				new SimpleDateFormat("yyyyMMddHHmmss").format(new Date().getTime() + 15 * 60 * 1000));

		/** 请求参数设置完毕，以下对请求参数进行签名并生成html表单，将表单写入浏览器跳转打开银联页面 **/
		Map<String, String> submitFromData = AcpService.sign(requestData, "UTF-8"); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。

		return submitFromData;
	}

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

		if (!"00".equals(paramMap.get("respCode"))) {
			return null;
		}
		// 验证
		// AcpService.validate(getRequestMap(request), "UTF-8");

		LocalDateTime reply_time = null;
		try {
			reply_time = LocalDateTime.now();
		} catch (Exception e) {

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

		if (bill.getBill_status().equals(PayBillStatus.Request)) {
			try {
				daoBill.completeBill(bill.getBill_id(), reply_time, reply_time,
						paramMap.get("origQryId") == null ? "" : paramMap.get("origQryId").toString(), null);
			} catch (Exception e) {
				this.logReply(BillProcessResult.DatabaseError, bill.getBill_id() + "", request);
			}
			bill.setBill_status(PayBillStatus.Complete);
			bill.setReply_time(reply_time);
			return bill;
		}
		return null;
	}

	@Override
	public PayBill queryBill(PayBillDao daoBill, PayBill bill) {

		return null;
	}

}
