package com.fdkankan.pay.alipay.sdk;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayResponse;
import com.alipay.api.domain.TradeFundBill;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.alipay.demo.trade.model.GoodsDetail;
import com.alipay.demo.trade.model.builder.AlipayTradePrecreateRequestBuilder;
import com.alipay.demo.trade.model.builder.AlipayTradeQueryRequestBuilder;
import com.alipay.demo.trade.model.result.AlipayF2FPrecreateResult;
import com.alipay.demo.trade.model.result.AlipayF2FQueryResult;
import com.alipay.demo.trade.service.AlipayTradeService;
import com.alipay.demo.trade.utils.Utils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AlipayService {
    private static Logger log = LoggerFactory.getLogger("programLog");

    @Autowired
    private AlipayTradeService alipayTradeService;

    /**
     * 当面付-扫码付
     *
     * 扫码支付，指用户打开支付宝钱包中的“扫一扫”功能，扫描商户针对每个订单实时生成的订单二维码，并在手机端确认支付。
     *
     * 发起预下单请求，同步返回订单二维码
     *
     * 适用场景：商家获取二维码展示在屏幕上，然后用户去扫描屏幕上的二维码
     * @return
     * @throws AlipayApiException
     */
    public Map<String, String> tradePrecreate(AlipaymentEx alipaymentEx, String notifyUrl) throws AlipayApiException {
        if (StringUtils.isEmpty(alipaymentEx.getOutTradeNo())){
            throw new AlipayApiException("outTradeNo should not be null");
        }else if (StringUtils.isEmpty(alipaymentEx.getSubject())){
            throw new AlipayApiException("subject should not be null");
        }else if (StringUtils.isEmpty(alipaymentEx.getBody())){
            throw new AlipayApiException("body should not be null");
        }else if (alipaymentEx.getTotalAmount() == null){
            throw new AlipayApiException("totalAmout should not be null");
        }else if (StringUtils.isEmpty(alipaymentEx.getStoreId())){
            throw new AlipayApiException("storeid should not be null");
        }else if (alipaymentEx.getGoodsDetailList() == null || alipaymentEx.getGoodsDetailList().size() == 0){
            throw new AlipayApiException("goodsDetailList should not be null");
        }else if (StringUtils.isEmpty(notifyUrl)){
            throw new AlipayApiException("notifyUrl should not be null");
        }

        List<AlipayGoodsDetail> alipayGoodsDetails = alipaymentEx.getGoodsDetailList();
        List<GoodsDetail> goodsDetailList = new ArrayList<>();
        for (AlipayGoodsDetail alipayGoodsDetail : alipayGoodsDetails){
            GoodsDetail goods1 = GoodsDetail.newInstance(alipayGoodsDetail.getGoodsId(),
                    alipayGoodsDetail.getGoodsName(), alipayGoodsDetail.getPrice(), alipayGoodsDetail.getQuantity());
            goodsDetailList.add(goods1);
        }

        AlipayTradePrecreateRequestBuilder builder = new AlipayTradePrecreateRequestBuilder()
                .setSubject(alipaymentEx.getSubject())
                .setTotalAmount(alipaymentEx.getTotalAmount().toString())
                .setOutTradeNo(alipaymentEx.getOutTradeNo())
                .setUndiscountableAmount(alipaymentEx.getUndiscountableAmount() == null ? "" : alipaymentEx.getUndiscountableAmount().toString())
                .setSellerId(alipaymentEx.getSellerId() == null ? "" : alipaymentEx.getSellerId())
                .setBody(alipaymentEx.getBody())
                .setOperatorId(alipaymentEx.getOperatorId() == null ? "" : alipaymentEx.getOperatorId())
                .setStoreId(alipaymentEx.getStoreId())
                .setTimeoutExpress(alipaymentEx.getTimeoutExpress())
                //支付宝服务器主动通知商户服务器里指定的页面http路径,根据需要设置
                .setNotifyUrl(notifyUrl)
                .setGoodsDetailList(goodsDetailList);

        Map<String, String> resp = new HashMap<>();
        AlipayF2FPrecreateResult result = alipayTradeService.tradePrecreate(builder);
        AlipayTradePrecreateResponse res = result.getResponse();
        switch (result.getTradeStatus()) {
            case SUCCESS:
                dumpResponse(res);
                log.info("支付宝预下单成功。");
                resp.put("code", "0");
                resp.put("out_trade_no", res.getOutTradeNo());
                resp.put("qr_code", res.getQrCode());
                break;

            case FAILED:
                log.error("支付宝预下单失败，code:" + res.getCode() + "，msg:" + res.getMsg());
                resp.put("code", "-1");
                break;

            case UNKNOWN:
                log.error("系统异常，预下单状态未知，code:" + res.getCode() + "，msg:" + res.getMsg());
                resp.put("code", "-2");
                break;

            default:
                log.error("不支持的交易状态，交易返回异常，code:" + res.getCode() + "，msg:" + res.getMsg());
                resp.put("code", "-3");
                break;
        }
        return resp;
    }

    public String tradeQuery(String outTradeNo) {
        // (必填) 商户订单号，通过此商户订单号查询当面付的交易状态
        String Type;
        // 创建查询请求builder，设置请求参数
        AlipayTradeQueryRequestBuilder builder = new AlipayTradeQueryRequestBuilder()
                .setOutTradeNo(outTradeNo);
        System.out.println("请求参数:" + builder);
        AlipayF2FQueryResult result = alipayTradeService.queryTradeResult(builder);
        switch (result.getTradeStatus()) {
            case SUCCESS:
                log.info("查询返回该订单支付成功: )");
                Type = "SUCCESS";
                AlipayTradeQueryResponse response = result.getResponse();
                dumpResponse(response);
                log.info(response.getTradeStatus());
                if (Utils.isListNotEmpty(response.getFundBillList())) {
                    for (TradeFundBill bill : response.getFundBillList()) {
                        log.info(bill.getFundChannel() + ":" + bill.getAmount());
                    }
                }
                break;
            case FAILED:
                log.error("查询返回该订单支付失败或被关闭!!!");
                Type = "FAILED";
                break;
            case UNKNOWN:
                log.error("系统异常，订单支付状态未知!!!");
                Type = "UNKNOWN";
                break;
            default:
                log.error("不支持的交易状态，交易返回异常!!!");
                Type = "default";
                break;
        }
        return Type;
    }

    // 简单打印应答
    private void dumpResponse(AlipayResponse response) {
        if (response != null) {
            log.info(String.format("code:%s, msg:%s", response.getCode(), response.getMsg()));
            if (StringUtils.isNotEmpty(response.getSubCode())) {
                log.info(String.format("subCode:%s, subMsg:%s", response.getSubCode(),
                        response.getSubMsg()));
            }
            log.info("body:" + response.getBody());
        }
    }
}
