package cn.hmsoft.pay.impl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
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.JsonHelper;
import cn.hmsoft.helper.LocalDateHelper;
import cn.hmsoft.helper.SecureHelper;
import cn.hmsoft.helper.StringHelper;
import cn.hmsoft.helper.http.HttpHelper;
import cn.hmsoft.helper.http.HttpRequestEntity;
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.PayChannelAbstract;
import cn.hmsoft.pay.impl.anxinpay.AnxinPayBillParamResponse;
import cn.hmsoft.pay.impl.anxinpay.AnxinPayBillRequest;
import cn.hmsoft.pay.impl.anxinpay.AnxinPayBillResponse;
import cn.hmsoft.pay.impl.anxinpay.AnxinPayOrderNoticeResponse;
import cn.hmsoft.pay.impl.newupay.NewUPayOrderRequest;
import cn.hmsoft.pay.service.PayBillService;

public class PayAnxinUnPayChannelImpl extends PayChannelAbstract {


	@Override
	protected boolean init() throws Exception {
		return true;
	}

	@Override
	public String makeBillNo(PayBill bill) {
		String v = StringHelper.leftPadding(bill.getBusiness_id(), 8, '0');
		return "AXP_" + bill.getBusiness_type() + "_" + LocalDateHelper.formatLongNoSplit(LocalDateTime.now()) + "_" + v;
	}

	@Override
	public Map<String, String> makeRequestAttr(PayBill bill) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("business_channel", this.payMerchantChannel.getBank_merchant_name());
		map.put("pay_channel", this.payMerchantChannel.getPublic_key_path());
		map.put("orderno", bill.getBill_no());
		String amt = new BigDecimal(bill.getBill_amount() + "").divide(new BigDecimal("100")).toPlainString();
		map.put("amt", amt);//银联只支持元单位金额
		map.put("custno", bill.getCustomer_id() + "");//学生ID
		map.put("name", bill.getCustomer_id() + "");
		map.put("feename", "报考缴费");
		map.put("back_notify_url", this.payMerchantChannel.getNotice_url());
		map.put("front_notify_url", "");//bill_param 存放报考学校Id
		
		String json = JsonHelper.fromObject(map);
		String value = JsonHelper.fromObject(map) + "" + this.getPayMerchantChannel().getBank_merchant_pass();
		String md5 = SecureHelper.md5(value);
		
		Map<String, String> reqMap = new HashMap<String, String>();
		reqMap.put("json", json);
		reqMap.put("signature", md5.toLowerCase());
		return reqMap;
	}
	
	@Override
	public String makeRequestString(PayBill bill) {
		// 设置请求参数
		throw new BusinessException("未实现");
	}

	@Override
	public PayBill processReply(PayBillDao daoBill, PayBill bill, HttpServletRequest request,
			Map<String, Object> paramMap) {
		// {"type":"back","status":"00","union_order_no":"2019030413351000134","orderno":"AXP_HmPay_20190304133340_00000001","amt":"0.01","settledate":"20190304","paytime":"20190304133521","pay_channel_name":"\u5FAE\u4FE1\u652F\u4ED8","paychannel":"WxPay"}

		String json = paramMap.get("json").toString();
		AnxinPayOrderNoticeResponse notice = JsonHelper.toObject(json, AnxinPayOrderNoticeResponse.class);
		LocalDateTime reply_time = LocalDateHelper.parseDateTimeNoSplit(notice.getPaytime());
		bill.setReply_time(reply_time);
		bill.setBill_status(PayBillStatus.Complete);
		bill.setChannel_no(notice.getUnion_order_no());
		// 首次成交 更新订单
		try {
			int count = daoBill.completeBill(bill.getBill_id(), reply_time, notice.getUnion_order_no());
			if (count == 0)
				return bill;

			return bill;
		} catch (Exception e) {
			this.logReply(bill, BillProcessResult.DatabaseError, "", request);
			return null;
		}	

	}

	public PayBill makePayBill(int order_amount, String customer_id, String business_type, String business_id,
			String product_name) {

		PayBillService sBill = SpringHelper.getBean(PayBillService.class);
		PayBill bill = new PayBill();
		bill.setBill_amount(order_amount);
		// bill.setBill_param(bill_param);
		bill.setBill_status(PayBillStatus.Request);
		bill.setBill_time(LocalDateTime.now());
		bill.setBusiness_id(business_id);
		bill.setBusiness_type(business_type);
		bill.setChannel_id(this.channel.getChannel_id());
		bill.setCustomer_id(customer_id);
		bill.setMerchant_id(this.merchant.getMerchant_id());
		// 最后生成订单号
		bill.setBill_no(makeBillNo(bill));
		sBill.optrBill(bill);

		AnxinPayBillRequest entity = new AnxinPayBillRequest();
		// business_channel : bank_merchant_name
		entity.setBusiness_channel(this.getPayMerchantChannel().getBank_merchant_name());
		// pay_channel : public_key_path
		entity.setPay_channel(this.getPayMerchantChannel().getPublic_key_path());
		// pay_mode:bank_merchant_key
		entity.setPay_mode(StringHelper.isEmpty(this.getPayMerchantChannel().getBank_merchant_key()) ? "scan"
				: this.getPayMerchantChannel().getBank_merchant_key());

		product_name = StringHelper.isEmpty(product_name)
				? (this.payMerchantChannel.getChannel_goods_name() == null ? "支付费用"
						: this.payMerchantChannel.getChannel_goods_name())
				: product_name;
		entity.setOrderno(bill.getBill_no());
		// DecimalFormat df = new DecimalFormat("0.00");

		entity.setAmt(String.format("%.2f", (((double) bill.getBill_amount()) / 100)));
		entity.setFeename(product_name);
		entity.setBack_notify_url(this.getPayMerchantChannel().getNotice_url());
		String json = JsonHelper.fromObject(entity);
		String value = JsonHelper.fromObject(entity) + "" + this.getPayMerchantChannel().getBank_merchant_pass();
		String md5 = SecureHelper.md5(value);
		HttpRequestEntity rq = new HttpRequestEntity();
		rq.setHttp_url(this.getPayMerchantChannel().getPage_url());
		Map<String, Object> map = new LinkedHashMap<String, Object>();
		map.put("json", json);
		map.put("signature", md5.toLowerCase());
		rq.setRequestMap(map);
		System.out.println(this.getPayMerchantChannel().getPage_url());
		String line = null;
		try {
			line = HttpHelper.URLPost(rq).get(0);
		} catch (Exception e) {
			e.printStackTrace();
		}
		if (StringHelper.isEmpty(line))
			throw new BusinessException("创建订单失败：无法访问安心付服务器！");
		String returnMD5 = line.substring(line.indexOf("&signature=") + "&signature=".length());
		String returnJson = line.replace("json=", "").substring(0, line.replace("json=", "").indexOf("&signature="));
		// 验证
		if (!SecureHelper.md5(returnJson + this.getPayMerchantChannel().getBank_merchant_pass()).toLowerCase()
				.equals(returnMD5))
			throw new BusinessException("创建订单失败：MD5验证失败！");
		AnxinPayBillResponse response = JsonHelper.toObject(returnJson, AnxinPayBillResponse.class);
		if (response != null && "00".equals(response.getRespcode())) {
			if (StringHelper.isEmpty(response.getPayparam()))
				throw new BusinessException("安心付订单创建失败");
			AnxinPayBillParamResponse r = JsonHelper.toObject(response.getPayparam(), AnxinPayBillParamResponse.class);
			if (r == null || StringHelper.isEmpty(r.getQr_data()))
				throw new BusinessException("安心付订单创建失败");
			// 下单成功，生成订单
			bill.setBill_param(r.getQr_data());
			try {
				sBill.optrBill(bill);
			} catch (Exception e) {
				throw new BusinessException("安心付订单创建失败,失败原因[同一支付提交频率过于频繁]，请重试");
			}
			return bill;
		} else {
			throw new BusinessException("安心付订单创建失败");
		}

	}
}
