package com.hfkj.service.pay.impl;

import com.hfkj.common.pay.entity.OrderType;
import com.hfkj.common.utils.SpringContextUtil;
import com.hfkj.service.pay.NotifyService;
import com.hfkj.service.pay.PayRecordService;
import com.hfkj.service.pay.PayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Map;

@Service(value = "notifyService")
public class NotifyServiceImpl implements NotifyService {

    private static Logger log = LoggerFactory.getLogger(NotifyServiceImpl.class);

    @Resource
    private PayRecordService payRecordService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String alipayNotify(Map<String, String> params) throws Exception {
        String result = "failure";
        String trade_status = params.get("trade_status");
        if ("TRADE_SUCCESS".equals(trade_status)) {
            // 交易支付成功 默认触发

            String orderType = params.get("passback_params");
            PayService payService = getPayService(orderType);
            if (payService != null) {
                payService.paySuccess(params, "Alipay");    // 商户内部实际的交易业务处理
                log.info("支付宝异步通知 -> 业务处理完成");
                result = "success";
            } else {
                log.info("支付宝异步通知 -> 业务处理：payService获取失败");
            }

        } else if ("TRADE_CLOSED".equals(trade_status)) {
            // 未付款交易超时关闭，或支付完成后全额退款 默认触发

            // todo 业务流程

            log.info("支付宝异步通知 -> 未付款交易超时关闭，或支付完成后全额退款");
            result = "success";
        } else if ("WAIT_BUYER_PAY".equals(trade_status)) {
            // 交易创建，等待买家付款 默认不触发

            // todo 业务流程

            log.info("支付宝异步通知 -> 交易创建，等待买家付款");
            result = "success";
        } else if ("TRADE_FINISHED".equals(trade_status)) {
            // 交易结束，不可退款 默认不触发

            // todo 业务流程

            log.info("支付宝异步通知 -> 交易结束，不可退款");
            result = "success";
        }

        // 增加支付纪录（实际是支付宝回调纪录）
        payRecordService.addPayRecord(params, "Alipay");
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public String wechatNotify(Map<String, String> paramsMap) throws Exception {
        String resXml = null;

        if ("SUCCESS".equals(paramsMap.get("return_code")) && "SUCCESS".equals(paramsMap.get("result_code"))) {
            log.info("微信支付 -> 异步通知：支付成功，进入订单处理");
            // 订单类型
            String orderType = paramsMap.get("attach");
            PayService payService = getPayService(orderType);
            if (payService != null) {
                payService.paySuccess(paramsMap, "WechatPay");    // 商户内部实际的交易业务处理
                log.info("微信支付 -> 异步通知：订单处理完成");
            } else {
                log.error("微信支付 -> 异步通知：业务处理，payService获取失败");
            }

            // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了
            resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                    + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
        } else {
            log.error("微信支付 -> 异步通知：支付失败,错误信息：" + paramsMap.get("err_code_des"));
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA["
                    + paramsMap.get("err_code_des") + "]]></return_msg>" + "</xml> ";
        }

        if ("SUCCESS".equals(paramsMap.get("return_code"))) {
            // 增加支付纪录（实际是微信回调纪录）
            payRecordService.addPayRecord(paramsMap, "WechatPay");
        }
        return resXml;
    }

    /**
     * @desc 根据回调回传参数 选择业务service
     * @param orderType 订单类型（回传参数）
     */
    private PayService getPayService(String orderType) throws Exception{
        PayService payService = null;
        for (OrderType item : OrderType.values()) {
            if (item.getModuleCode().equals(orderType)) {
                payService = (PayService) SpringContextUtil.getBean(item.getService());
                break;
            }
        }

        return payService;
    }

}
