package shop.alien.store.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import shop.alien.entity.result.R;
import shop.alien.entity.store.PlatformShopMembershipPaymentOrder;
import shop.alien.store.service.PlatformMembershipPaymentQueryService;
import shop.alien.store.service.PlatformShopMembershipPaymentOrderService;
import shop.alien.store.strategy.platformMembershipPayment.PlatformMembershipPaymentStrategy;
import shop.alien.store.strategy.platformMembershipPayment.PlatformMembershipPaymentStrategyFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;

/**
 * 店铺端 — 平台会员卡支付（与 /user/reservation/payment 平行的新接口）
 */
@Slf4j
@Api(tags = {"店铺-平台会员卡支付"})
@RestController
@RequestMapping("/platform-shop-membership/payment")
@RequiredArgsConstructor
public class PlatformShopMembershipPaymentController {

    private final PlatformMembershipPaymentStrategyFactory strategyFactory;
    private final PlatformMembershipPaymentQueryService platformMembershipPaymentQueryService;
    private final PlatformShopMembershipPaymentOrderService platformShopMembershipPaymentOrderService;

    @Value("${platform.shop-membership.payment.test-refund-enabled:false}")
    private boolean testRefundEnabled;

    @ApiOperation("会员卡-创建预支付")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "orderId", value = "会员卡订单ID platform_shop_membership_order.id", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "amountYuan", value = "支付金额（元）", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "subject", value = "订单描述", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "userId", value = "门店用户ID", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "payType", value = "alipay / wechatPay", paramType = "query", dataType = "String")
    })
    @PostMapping("/prePay")
    public R<Map<String, Object>> prePay(
            @RequestParam Integer storeId,
            @RequestParam Integer orderId,
            @RequestParam String amountYuan,
            @RequestParam String subject,
            @RequestParam Integer userId,
            @RequestParam(defaultValue = "alipay") String payType) {
        log.info("PlatformShopMembershipPaymentController.prePay storeId={}, orderId={}, payType={}", storeId, orderId, payType);
        PlatformMembershipPaymentStrategy strategy = strategyFactory.getStrategy(payType);
        return strategy.createPrePay(storeId, orderId, amountYuan, subject, userId);
    }

    @ApiOperation("会员卡-查询支付状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "storeId", value = "门店ID", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "outTradeNo", value = "商户订单号", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "payType", value = "alipay / wechatPay", paramType = "query", dataType = "String")
    })
    @GetMapping("/queryStatus")
    public R<Object> queryStatus(
            @RequestParam Integer storeId,
            @RequestParam String outTradeNo,
            @RequestParam(defaultValue = "alipay") String payType) {
        log.info("PlatformShopMembershipPaymentController.queryStatus storeId={}, outTradeNo={}", storeId, outTradeNo);
        return platformMembershipPaymentQueryService.queryPayStatusWithRetry(storeId, outTradeNo, payType);
    }

    @ApiOperation(value = "会员卡-测试退款", notes = "联调/测试：传会员卡业务订单ID + 支付方式；按支付单全额退款。成功后回写支付单与业务订单为已退款（不自动调整店铺会员到期）。需 platform.shop-membership.payment.test-refund-enabled=true")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "会员卡业务订单ID platform_shop_membership_order.id", required = true, paramType = "query", dataType = "int"),
            @ApiImplicitParam(name = "payType", value = "alipay / wechatPay", required = true, paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "refundReason", value = "退款原因", paramType = "query", dataType = "String"),
            @ApiImplicitParam(name = "outTradeNo", value = "可选；指定该订单下某笔已支付流水；不传则取该支付方式最近一笔已支付单", paramType = "query", dataType = "String")
    })
    @PostMapping("/test/refund")
    public R<String> testRefund(
            @RequestParam Integer orderId,
            @RequestParam String payType,
            @RequestParam(required = false) String refundReason,
            @RequestParam(required = false) String outTradeNo) {
        if (!testRefundEnabled) {
            return R.fail("测试退款未开启，请在配置中设置 platform.shop-membership.payment.test-refund-enabled=true");
        }
        PlatformShopMembershipPaymentOrder po = platformShopMembershipPaymentOrderService.findPaidPaymentForMembershipTestRefund(
                orderId, payType, outTradeNo);
        if (po == null) {
            return R.fail("会员卡订单不存在，或不存在符合条件的已支付流水（可传 outTradeNo 指定具体支付单）");
        }
        if (po.getPayAmount() == null || po.getPayAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return R.fail("支付单金额异常，无法退款");
        }
        String refundAmountYuan = po.getPayAmount().setScale(2, RoundingMode.HALF_UP).toPlainString();
        log.warn("PlatformShopMembershipPaymentController.testRefund storeId={}, orderId={}, outTradeNo={}, payType={}, refundAmountYuan={}",
                po.getStoreId(), orderId, po.getOutTradeNo(), payType, refundAmountYuan);
        PlatformMembershipPaymentStrategy strategy = strategyFactory.getStrategy(payType);
        return strategy.refundForTest(po, refundAmountYuan, refundReason);
    }
}
