package com.jeesharp.business.modules.pay.route;

import com.github.binarywang.wxpay.bean.result.WxPayUnifiedOrderV3Result;
import com.jeesharp.business.modules.pay.dto.BasicPayOrderData;
import com.jeesharp.business.modules.pay.paywechatconfig.enums.WechatPayRouteTypeEnum;
import com.jeesharp.business.modules.pay.route.handler.CombineJsapiRouteHandler;
import com.jeesharp.business.modules.pay.route.handler.DirectJsapiRouteHandler;
import com.jeesharp.business.modules.pay.route.handler.PartnerJsapiRouteHandler;
import com.jeesharp.business.modules.pay.route.handler.PayWechatJsapiRouteHandler;
import com.jeesharp.business.modules.pay.dto.PayWechatPrepayRouteSnapshotDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 微信 JSAPI 预下单路由器：按 {@link PayWechatPayRouteContext} 委托 Direct / Partner / Combine Handler。
 *
 * @author jeesharp
 * @since 2026-06-12
 */
@Component
@RequiredArgsConstructor
public class PayWechatPayRouter {

    private final PayWechatPayRouteResolver routeResolver;
    private final DirectJsapiRouteHandler directJsapiRouteHandler;
    private final PartnerJsapiRouteHandler partnerJsapiRouteHandler;
    private final CombineJsapiRouteHandler combineJsapiRouteHandler;

    public PayWechatPrepayRouteSnapshotDTO previewSnapshot(BasicPayOrderData payOrderData) {
        PayWechatPayRouteContext context = routeResolver.resolve(payOrderData);
        return toRouteDto(context, payOrderData);
    }

    public PayWechatPayRouteResult prepay(BasicPayOrderData payOrderData) throws Exception {
        PayWechatPayRouteContext context = routeResolver.resolve(payOrderData);
        PayWechatJsapiRouteHandler handler = selectHandler(context.getPayRouteType());
        WxPayUnifiedOrderV3Result.JsapiResult jsapi = handler.prepay(context, payOrderData);
        return new PayWechatPayRouteResult(context, jsapi, toRouteDto(context, payOrderData));
    }

    public PayWechatPayRouteContext previewRoute(BasicPayOrderData payOrderData) {
        return routeResolver.resolve(payOrderData);
    }

    private PayWechatJsapiRouteHandler selectHandler(WechatPayRouteTypeEnum routeType) {
        if (routeType == WechatPayRouteTypeEnum.PARTNER) {
            return partnerJsapiRouteHandler;
        }
        if (routeType == WechatPayRouteTypeEnum.COMBINE) {
            return combineJsapiRouteHandler;
        }
        return directJsapiRouteHandler;
    }

    private static PayWechatPrepayRouteSnapshotDTO toRouteDto(PayWechatPayRouteContext context, BasicPayOrderData payOrderData) {
        PayWechatPrepayRouteSnapshotDTO dto = new PayWechatPrepayRouteSnapshotDTO();
        dto.setWechatPayMode(context.getWechatPayMode().getValue());
        dto.setPayRouteType(context.getPayRouteType().getValue());
        if (context.getSubPayItems() != null && context.getSubPayItems().size() == 1) {
            dto.setSubMchId(context.getSubPayItems().get(0).getSubMchId());
        }
        if (context.getPayRouteType() == WechatPayRouteTypeEnum.COMBINE) {
            dto.setCombineOutTradeNo(payOrderData.getOrderNumber());
        }
        return dto;
    }
}
