package com.red.circle.order.app.command.pay.web.strategy;

import com.google.common.collect.Lists;
import com.red.circle.component.pay.paypal.PayPalAmountBreakdownParam;
import com.red.circle.component.pay.paypal.PayPalApplicationContextParam;
import com.red.circle.component.pay.paypal.PayPalLinkResult;
import com.red.circle.component.pay.paypal.PayPalPlaceAnOrderParam;
import com.red.circle.component.pay.paypal.PayPalPurchaseUnitAmountParam;
import com.red.circle.component.pay.paypal.PayPalPurchaseUnitParam;
import com.red.circle.component.pay.paypal.service.PayPalResponse;
import com.red.circle.component.pay.paypal.service.PaypalService;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.order.app.dto.clientobject.pay.PlaceAnOrderResponseCO;
import com.red.circle.order.inner.asserts.OrderErrorCode;
import com.red.circle.tool.core.json.JacksonUtils;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * pay pal web 支付
 * <p>
 * 商家l收款单笔手续费:https://www.paypal.com/c2/webapps/mpp/merchant-fees#domestic
 *
 * @author pengshigang on 2022/11/02
 */
@Slf4j
@Component("PAY_PAL_PLACE_AN_ORDER")
@RequiredArgsConstructor
public class PayPalWebPayPlaceAnOrderStrategyV2 implements
    PayWebPlaceAnOrderStrategyV2 {

  private final PaypalService paypalService;
  // 收货地址种类
  public static final String SET_PROVIDED_ADDRESS = "GET_FROM_FILE";

  @Override
  public PlaceAnOrderResponseCO doOperation(PayPlaceAnOrderDetailsV2 details) {

    Long customId = Long.valueOf(details.getOrderId());
    PayPalPlaceAnOrderParam param = buildRequestBody(details, customId);
    // 构建请求参数并访问paypal支付订单创建
    PayPalResponse payPalResponse = requestApi(details, param);

    // 第三方支付创建订单失败
    ResponseAssert.isTrue(OrderErrorCode.CREATE_ORDER_ERROR, payPalResponse.isSuccess());

    // 返回paypal支付链接给页面,页面则直接进入paypal官方支付页面.
    String link = payPalResponse.getLinks().stream()
        .filter(s -> Objects.equals(s.getRel(), "approve"))
        .map(PayPalLinkResult::getHref).findAny().orElse("");
    return new PlaceAnOrderResponseCO()
        .setTradeNo(payPalResponse.getId())
        .setOrderId(customId.toString())
        .setRequestUrl(link)
        .setCurrency(details.getCurrency())
        .setCountryCode(details.getCountryCode())
        .setFactoryCode(details.getFactoryCode())
        .setFactoryChannelCode(details.getFactoryChannel())
        .putRequestParam(param)
        .putResponseParam(payPalResponse);
  }

  private PayPalResponse requestApi(PayPlaceAnOrderDetailsV2 details,
      PayPalPlaceAnOrderParam param) {
    try {
      return paypalService.placeAnOrder(param);
    } catch (Exception ex) {
      ex.printStackTrace();
      log.error("订单创建请求失败:details={}、requestParam={}", JacksonUtils.toJson(details),
          JacksonUtils.toJson(param));
    }
    ResponseAssert.failure(OrderErrorCode.CREATE_ORDER_ERROR);
    return null;
  }

  private PayPalPlaceAnOrderParam buildRequestBody(PayPlaceAnOrderDetailsV2 details
      , Long customId) {

    return PayPalPlaceAnOrderParam.builder()
        .intent("CAPTURE")
        .applicationContext(PayPalApplicationContextParam.builder()
            .returnUrl(details.getSuccessRedirectUrl())
            .cancelUrl(details.getCancelRedirectUrl())
            .shippingPreference(SET_PROVIDED_ADDRESS)
            .brandName("Shop")
            .build())
        .purchaseUnits(Lists.newArrayList(PayPalPurchaseUnitParam.builder()
            .customId(customId.toString())
            .amount(PayPalPurchaseUnitAmountParam.builder()
                .value(details.getAmount().toString())
                .currencyCode(details.getCurrency())
                .breakdown(PayPalAmountBreakdownParam.builder()
                    .itemTotal(PayPalPurchaseUnitAmountParam.builder()
                        .currencyCode(details.getCurrency())
                        .value(details.getAmount().toString())
                        .build())
                    .build())
                .build())
//            .items(Lists.newArrayList(PayPalPurchaseProductParam.builder()
//                .description(details.getProductDescriptor())
//                .name("product size * " + details.getProducts().size())
//                .quantity(1L)
//                .unit_amount(PayPalPurchaseUnitAmountParam.builder()
//                    .value(details.getAmount().toString())
//                    .currency_code(details.getCurrency())
//                    .build())
//                .build()))
            .build()))
        .build();
  }

}
