package com.czg.controller.pay;

import com.czg.annotation.Debounce;
import com.czg.order.entity.OrderPayment;
import com.czg.order.service.OrderPaymentService;
import com.czg.pay.QueryOrderRespDTO;
import com.czg.resp.CzgResult;
import com.czg.service.order.dto.VipMemberPayParamDTO;
import com.czg.service.order.dto.VipPayParamDTO;
import com.czg.service.order.dto.VipRefundDTO;
import com.czg.service.order.service.PayService;
import com.czg.service.order.service.ShopUserPayService;
import com.czg.utils.AssertUtil;
import com.czg.utils.ServletUtil;
import com.mybatisflex.core.query.QueryWrapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

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

/**
 * 会员 支付
 *
 * @author ww
 * @description
 */
@RestController
@RequestMapping("/pay")
public class VipPayController {
    @Resource
    private PayService payService;
    @Resource
    private ShopUserPayService shopUserPayService;

    @Resource
    private OrderPaymentService paymentService;

    /**
     * 现金充值
     * 如果shop_info的 is_member_in_pwd=1 则pwd必填 店铺操作密码
     */
    //@SaStaffCheckPermission("yun_xu_shou_kuan")
    @PostMapping("/cashPayVip")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Object> cashPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.cashPayVip(payParam);
    }

    /**
     * js支付
     * payType 必填  支付方式，ALIPAY 支付宝，WECHAT 微信
     * openId  必填
     */
    @PostMapping("/jsPayVip")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Map<String, Object>> jsPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.jsPayVip(ServletUtil.getClientIP(request), payParam);
    }

    /**
     * 小程序支付
     * payType 必填  支付方式，ALIPAY 支付宝，WECHAT 微信
     * openId  必填
     */
    @PostMapping("/ltPayVip")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Map<String, Object>> ltPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.ltPayVip(ServletUtil.getClientIP(request), payParam);
    }

    /**
     * 智慧充值
     */
    @PostMapping("/recharge")
    @Debounce(value = "#rechargeDTO.shopUserId")
    public CzgResult<Map<String, Object>> recharge(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO rechargeDTO) {
        if (rechargeDTO.getRechargeDetailId() == null && rechargeDTO.getAmount() == null) {
            return CzgResult.failure("充值失败 未指定充值金额");
        }
        rechargeDTO.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.recharge(ServletUtil.getClientIP(request), rechargeDTO, rechargeDTO.getShopUserId());
    }

    /**
     * 会员购买支付
     */
    @PostMapping("/ltPayMember")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Map<String, Object>> ltPayMember(HttpServletRequest request, @Validated @RequestBody VipMemberPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "购买失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.ltPayMember(ServletUtil.getClientIP(request), payParam);
    }


    /**
     * 正扫
     */
    //@SaStaffCheckPermission("yun_xu_shou_kuan")
    @PostMapping("/scanPayVip")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Map<String, Object>> scanPayVip(HttpServletRequest request, @Validated @RequestBody VipPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
        return shopUserPayService.scanPayVip(ServletUtil.getClientIP(request), payParam);
    }

    /**
     * 反扫
     * authCode 必填 扫描码
     */
    //@SaStaffCheckPermission("yun_xu_shou_kuan")
    @PostMapping("/microPayVip")
    @Debounce(value = "#payParam.shopUserId")
    public CzgResult<Map<String, Object>> microPayVip(@Validated @RequestBody VipPayParamDTO payParam) {
        AssertUtil.isNull(payParam.getShopUserId(), "充值失败 未指定店铺用户Id");
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(ServletUtil.getRequest(), "platformType"));
        return shopUserPayService.microPayVip(payParam);
    }

    /**
     * 退款前置
     * 最大退款金额 为 充值金额 inAmount
     */
    //@SaStaffCheckPermission("yun_xu_tui_kuan")
    @PostMapping("/refundVipBefore")
    @Debounce(value = "#payParam.flowId")
    public CzgResult<Map<String, BigDecimal>> refundVipBefore(@Validated @RequestBody VipRefundDTO payParam) {
        return shopUserPayService.refundVipBefore(payParam);
    }

    /**
     * 会员退款
     * cashRefund 是否是现金退款
     * 会员退款(先调用 退款前置接口 refundVipBefore)
     * 最大退款金额为 充值金额 inAmount
     * 理论可退最大金额为
     * 用户余额-赠送金额 >充值金额 则可退充值金额
     * 实际可退最大金额为 充值金额
     * 如果实际 大于 理论 则 需要勾选 outOfRange 超额退款 为true 默认为false
     */
    //@SaStaffCheckPermission("yun_xu_tui_kuan")
    @PostMapping("/refundVip")
    @Debounce(value = "#payParam.flowId")
    public CzgResult<Object> refundVip(HttpServletRequest request, @Validated @RequestBody VipRefundDTO payParam) {
        AssertUtil.isNull(payParam.getRefAmount(), "退款金额不能为空");
        if (payParam.getRefAmount().compareTo(BigDecimal.ZERO) <= 0) {
            return CzgResult.failure("退款金额必须大于0");
        } else if (payParam.getRefAmount().compareTo(new BigDecimal("10001")) > 0) {
            return CzgResult.failure("退款金额过大");
        }
        payParam.setPlatformType(ServletUtil.getHeaderIgnoreCase(request, "platformType"));
        return shopUserPayService.refundVip(payParam);
    }

    /**
     * 获取支付状态
     */
    @GetMapping("/queryPayStatus")
    public CzgResult<String> queryOrderStatus(Long shopId, String payOrderNo) {
        AssertUtil.isNull(shopId, "店铺id不能为空");
        AssertUtil.isBlank(payOrderNo, "支付单号不能为空");

        OrderPayment payment = paymentService.getOne(QueryWrapper.create().eq(OrderPayment::getOrderNo, payOrderNo));
        if (payment == null) {
            return CzgResult.failure("支付单号不存在");
        }

        CzgResult<String> result = CzgResult.success();
        CzgResult<QueryOrderRespDTO> queryPayOrder = payService.queryPayOrder(shopId, null, payOrderNo, payment.getPlatformType());
        if (queryPayOrder.isSuccess() && queryPayOrder.getData() != null) {
            String state = queryPayOrder.getData().getStatus();
            result.setData(state);
            switch (state) {
                case "TRADE_AWAIT" -> result.setMsg("等待用户付款");
                case "TRADE_SUCCESS" -> result.setMsg("支付成功");
                case "TRADE_FAIL" -> result.setMsg("支付失败");
                case "TRADE_CANCEL" -> result.setMsg("交易取消");
                case "REFUND_ING" -> result.setMsg("退款中");
                case "TRADE_CLOSE" -> result.setMsg("订单关闭");
            }
        } else {
            return CzgResult.failure(queryPayOrder.getMsg());
        }
        return result;
    }
}
