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

import com.red.circle.component.pay.paymax.service.*;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.ResponseErrorCode;
import com.red.circle.order.app.dto.clientobject.pay.PlaceAnOrderResponseCO;
import com.red.circle.order.domain.payer.PlaceAnOrderPaymentDetail;
import com.red.circle.order.inner.asserts.OrderErrorCode;
import com.red.circle.tool.core.json.JacksonUtils;
import com.red.circle.tool.core.text.StringUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * payer max web 支付.
 *
 * @author pengliang on 2022/11/02
 */
@Slf4j
@Component("PAYER_MAX_PLACE_AN_ORDER")
@RequiredArgsConstructor
public class PayerMaxWebPayPlaceAnOrderStrategyV2 implements
    PayWebPlaceAnOrderStrategyV2 {

  private final PayerMaxService payerMaxService;

  @Override
  public PlaceAnOrderResponseCO doOperation(PayPlaceAnOrderDetailsV2 details) {
    PlaceAnOrderParam param = getPlaceAnOrderParam(details);

    PayMaxResponse payMaxResponse = requestApi(details, param);
    ResponseAssert.notNull(OrderErrorCode.CREATE_ORDER_ERROR, payMaxResponse);

    // 500 支付失败，调用第三方错误
    if (!payMaxResponse.isSuccess()) {
      ResponseAssert.failure(ResponseErrorCode.INTERNAL_SERVER_ERROR, payMaxResponse.getMessage());
    }

    PlaceAnOrderResult result = payMaxResponse.toPlaceAnOrderResult();

    return new PlaceAnOrderResponseCO()
        .setTradeNo(result.getTradeNo())
        .setOrderId(result.getOrderId())
        .setCurrency(details.getCurrency())
        .setCountryCode(details.getCountryCode())
        .setFactoryCode(details.getFactoryCode())
        .setFactoryChannelCode(details.getFactoryChannel())
        .setRequestUrl(result.getRequestUrl())
        .putRequestParam(param)
        .putResponseParam(payMaxResponse);
  }

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

  private PlaceAnOrderParam getPlaceAnOrderParam(PayPlaceAnOrderDetailsV2 details) {
    return PlaceAnOrderParam.builder()
        .bizType(Objects.equals(details.getCountryCode().toUpperCase(), "IN")
            ? "IN_CB"
            : "CUSTOMIZE")
        .version("2.3")
        .orderId(details.getOrderId())
        .reference("")
        .userId(Objects.toString(details.getAcceptUserId()))
        .subject("gold")
        .countryCode(details.getCountryCode())
        .currency(details.getCurrency())
        .totalAmount(details.getAmount().toString())
        .frontCallBackUrl(details.getRechargeUrl())
        .paymentDetail(getPlaceAnOrderPaymentDetailParam(details))
        .build();
  }

  private String getPlaceAnOrderPaymentDetailParam(
      PayPlaceAnOrderDetailsV2 details) {
    if (StringUtils.isBlank(details.getChannelCode())) {
      return null;
    }

    if (StringUtils.isBlank(details.getFactoryChannel())) {
      return null;
    }
    PlaceAnOrderPaymentDetail paymentDetail = new PlaceAnOrderPaymentDetail();
    //PlaceAnOrderPaymentDetailParam paymentDetail = new PlaceAnOrderPaymentDetailParam();
    paymentDetail.setPaymentType(details.getFactoryChannel());
    if (paymentDetail.getPaymentType().equals("PROMPTPAY")) {
      paymentDetail.setPaymentType("REALTIME_PAYMENT");
      paymentDetail.setTargetOrg("PROMPTPAY");
    }
    return paymentDetail.toString();
  }

  private PayMaxResponse placeAnOrder(PlaceAnOrderParam param) {
    return payerMaxService.placeAnOrder(param);
  }

}
