package cn.novalon.gym.manage.payment.handler;

import cn.novalon.gym.manage.payment.dto.ApiResponse;
import cn.novalon.gym.manage.payment.dto.CreatePaymentRequest;
import cn.novalon.gym.manage.payment.dto.PaymentResponse;
import cn.novalon.gym.manage.payment.service.PaymentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
import reactor.core.publisher.MonoSink;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付处理器
 * 提供支付宝App支付相关接口
 */
@Slf4j
@Component
@Tag(name = "支付管理", description = "支付宝App支付接口")
public class PaymentHandler {

    private final PaymentService paymentService;

    public PaymentHandler(PaymentService paymentService) {
        this.paymentService = paymentService;
    }

    @Operation(summary = "创建支付订单", description = "创建支付宝App支付订单")
    public Mono<ServerResponse> createPayment(ServerRequest request) {
        return request.bodyToMono(CreatePaymentRequest.class)
                .flatMap(createReq -> {
                    log.info("[Payment] 创建支付订单: memberId={}, orderType={}, goodsDesc={}, transAmt={}",
                            createReq.getMemberId(), createReq.getOrderType(), createReq.getGoodsDesc(), createReq.getTransAmt());

                    PaymentResponse result = paymentService.alipayAppPay(createReq);

                    if ("FAIL".equals(result.getStatus())) {
                        return ServerResponse.ok()
                                .bodyValue(ApiResponse.error(result.getErrorMsg()));
                    }

                    return ServerResponse.ok()
                            .bodyValue(ApiResponse.success(result));
                })
                .onErrorResume(e -> {
                    log.error("[Payment] 创建支付订单异常", e);
                    return ServerResponse.ok()
                            .bodyValue(ApiResponse.error("创建支付订单失败: " + e.getMessage()));
                });
    }

    @Operation(summary = "创建扫码支付订单", description = "创建支付宝扫码支付订单，返回二维码链接")
    public Mono<ServerResponse> createQrCodePayment(ServerRequest request) {
        return request.bodyToMono(CreatePaymentRequest.class)
                .flatMap(createReq -> {
                    log.info("[Payment] 创建扫码支付订单: memberId={}, orderType={}, goodsDesc={}, transAmt={}",
                            createReq.getMemberId(), createReq.getOrderType(), createReq.getGoodsDesc(), createReq.getTransAmt());

                    PaymentResponse result = paymentService.alipayQrCodePay(createReq);

                    if ("FAIL".equals(result.getStatus())) {
                        return ServerResponse.ok()
                                .bodyValue(ApiResponse.error(result.getErrorMsg()));
                    }

                    return ServerResponse.ok()
                            .bodyValue(ApiResponse.success(result));
                })
                .onErrorResume(e -> {
                    log.error("[Payment] 创建扫码支付订单异常", e);
                    return ServerResponse.ok()
                            .bodyValue(ApiResponse.error("创建扫码支付订单失败: " + e.getMessage()));
                });
    }

    @Operation(summary = "查询支付状态", description = "查询支付订单状态")
    public Mono<ServerResponse> getPaymentStatus(ServerRequest request) {
        String orderId = request.pathVariable("orderId");
        log.info("[Payment] 查询支付状态: orderId={}", orderId);

        PaymentResponse result = paymentService.getPaymentStatus(orderId);
        return ServerResponse.ok()
                .bodyValue(ApiResponse.success(result));
    }

    @Operation(summary = "支付宝异步通知", description = "接收支付宝异步回调通知")
    public Mono<ServerResponse> alipayNotify(ServerRequest request) {
        return request.bodyToMono(Map.class)
                .flatMap(params -> {
                    log.info("[Payment] 收到支付宝异步通知: params={}", params);

                    // 转换Map类型
                    Map<String, String> notifyParams = new HashMap<>();
                    if (params instanceof Map) {
                        ((Map<?, ?>) params).forEach((key, value) ->
                            notifyParams.put(String.valueOf(key), String.valueOf(value)));
                    }

                    String result = paymentService.handleAlipayNotify(notifyParams);
                    return ServerResponse.ok()
                            .bodyValue(result);
                })
                .onErrorResume(e -> {
                    log.error("[Payment] 异步通知处理异常", e);
                    return ServerResponse.ok()
                            .bodyValue("fail");
                });
    }

    @Operation(summary = "申请退款", description = "申请支付退款")
    public Mono<ServerResponse> refundPayment(ServerRequest request) {
        String orderId = request.pathVariable("orderId");

        return request.bodyToMono(Map.class)
                .flatMap(body -> {
                    String refundAmt = String.valueOf(body.get("refundAmt"));
                    log.info("[Payment] 申请退款: orderId={}, refundAmt={}", orderId, refundAmt);

                    boolean success = paymentService.refund(orderId, refundAmt);
                    if (success) {
                        return ServerResponse.ok()
                                .bodyValue(ApiResponse.success("退款申请成功"));
                    } else {
                        return ServerResponse.ok()
                                .bodyValue(ApiResponse.error("退款申请失败"));
                    }
                })
                .onErrorResume(e -> {
                    log.error("[Payment] 退款异常: orderId={}", orderId, e);
                    return ServerResponse.ok()
                            .bodyValue(ApiResponse.error("退款失败: " + e.getMessage()));
                });
    }
}
