package cn.hmsoft.pay.impl;

import java.io.File;
import java.time.LocalDateTime;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.google.gson.internal.LinkedTreeMap;

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.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.weixin.WeiXinPayUtil;
import cn.hmsoft.pay.impl.weixin.entity.GenerateOrderRequestEntity;
import cn.hmsoft.pay.impl.weixin.entity.GenerateOrderResponseEntity;
import cn.hmsoft.pay.impl.weixin.entity.PayBillWeixin;
import cn.hmsoft.pay.impl.weixin.entity.PayNoticeResponse;
import cn.hmsoft.pay.service.PayBillService;

/******************************
 * 
 * @note 微信支付渠道
 * @author revisit@126.com
 * @Company: www.hmsoft.cn
 * @create 2017年8月22日 上午11:17:08
 * @version 4.0.0
 */
public class PayWeiXinChannelImpl extends PayChannelAbstract {

	/*************************
	 * 微信图标文件
	 */
	public File WeiXinImage = null;

	@Override
	protected boolean init() throws Exception {
		if (StringHelper.isEmpty(this.channel.getPay_url())) {
			return error("支付网关未配置");
		}
		if (StringHelper.isEmpty(this.payMerchantChannel.getBank_merchant_id())) {
			return error("AppId为空");
		}
		if (StringHelper.isEmpty(this.payMerchantChannel.getBank_merchant_pass())) {
			return error("支付密钥为空");
		}
		if (StringHelper.isEmpty(this.payMerchantChannel.getBank_merchant_key())) {
			return error("支付API部署地址(IP)为空");
		}
		if (StringHelper.isEmpty(this.payMerchantChannel.getBank_merchant_name())) {
			return error("支付商户为空");
		}
		// 设置微信图标
		if (StringHelper.isNotEmpty(this.payMerchantChannel.getLarge_image())) {
			try {
				File file = new File(
						SpringHelper.WebServletContext.getRealPath("/") + this.payMerchantChannel.getLarge_image());
				if (file.exists() && file.isFile())
					WeiXinImage = file;
			} catch (Exception e) {

			}
		}
		return true;
	}

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

	@Override
	public LinkedTreeMap<String, String> makeRequestAttr(PayBill bill) {
		throw new BusinessException("微信支付暂不支持此支付模式");
	}

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

		PayNoticeResponse entity = (PayNoticeResponse) paramMap.get("ResponseEntity");
		String value = paramMap.get("XmlString").toString();
		try {
			WeiXinPayUtil.checkSign(this.payMerchantChannel, entity, entity.getSign());
		} catch (Exception e) {
			this.logReply(null, BillProcessResult.HamcError, value, request);
			// return null;
		}
		// 20200105164439
		// 记录
		if ("SUCCESS".equals(entity.getReturn_code()) && "SUCCESS".equals(entity.getResult_code())) {
			LocalDateTime reply_time = LocalDateTime.now();
			LocalDateTime pay_time = null;
			try {
				pay_time = LocalDateHelper.parseDateTime(entity.getTime_end(),
						LocalDateHelper.LongDateStringWithoutSplitFormatter);
			} catch (Exception e) {

			}
			bill.setPay_time(pay_time);
			bill.setReply_time(reply_time);
			bill.setBill_status(PayBillStatus.Complete);
			// 首次成交 更新订单
			try {
				int count = daoBill.completeBill(bill.getBill_id(), pay_time, reply_time, entity.getTransaction_id());
				if (count == 0)
					return bill;
				PayBillWeixin wx = BeanHelper.copy(PayBillWeixin.class, entity);
				wx.setBill_id(bill.getBill_id());
				try {
					daoBill.insert(wx);
				} catch (Exception e) {
					e.printStackTrace();
					LogHelper.error(e);
				}
				return bill;
			} catch (Exception e) {
				e.printStackTrace();
				this.logReply(bill, BillProcessResult.DatabaseError, value, request);
				return null;
			}
		} else {
			this.logReply(BillProcessResult.BusiError, value, request);
			return null;
		}
	}

	public PayBill makePayBill(String open_id, int order_amount, String customer_id, String business_type,
			String business_id, String product_name) {
		// 查找最近两个小时，该业务是否有微信订单
		// BankBill bill = SpringHelper.GobalDao.findBySql(BankBill.class,
		// FIND_LAST_BILL, customer_id, business_id,
		// BankCode.WeiXin.toUpperCase(),
		// DateHelper.addValues(Calendar.MINUTE, -120));
		// if (bill != null) {
		// return bill;
		// }
		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);

		GenerateOrderRequestEntity entity = new GenerateOrderRequestEntity(this.payMerchantChannel);

		product_name = StringHelper.isEmpty(product_name)
				? (this.payMerchantChannel.getChannel_goods_name() == null ? "支付费用"
						: this.payMerchantChannel.getChannel_goods_name())
				: product_name;
		try {
			entity.setBody(product_name);
		} catch (Exception e) {
		}
		entity.setOut_trade_no(bill.getBill_no());
		entity.setTotal_fee(order_amount);
		if (StringHelper.isEmpty(open_id))
			entity.setTrade_type("NATIVE");
		else {
			entity.setTrade_type("JSAPI");
			entity.setOpenid(open_id);
		}
		entity.setAttach(bill.getBill_id() + "");

		GenerateOrderResponseEntity response = WeiXinPayUtil.requestMakeOrder(entity, this.payMerchantChannel);
		if (response == null)
			throw new BusinessException("创建微信订单失败，请重试");
		if (!"SUCCESS".equals(response.getReturn_code()))
			throw new BusinessException("创建微信订单失败,失败原因[" + response.getReturn_msg() + "]，请重试");

		if (!"SUCCESS".equals(response.getResult_code()))
			throw new BusinessException("创建微信订单失败,失败原因[" + response.getErr_code_des() + "]，请重试");
		// 下单成功，生成订单
		// 保存二维码信息
		bill.setBill_param(response.getCode_url());
		bill.setChannel_no(response.getPrepay_id());
		try {
			sBill.optrBill(bill);
		} catch (Exception e) {
			throw new BusinessException("创建微信订单失败,失败原因[同一支付提交频率过于频繁]，请重试");
		}
		return bill;
	}

	public File getWeiXinImage() {
		return WeiXinImage;
	}

}
