package com.liquidnet.service.order.controller;

import com.liquidnet.common.third.sqb.biz.SqbBiz;
import com.liquidnet.common.third.sqb.param.callback.CallbackParams;
import com.liquidnet.common.third.sqb.param.callback.CouponCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.OrderCallbackContent;
import com.liquidnet.common.third.sqb.param.callback.RefundCallbackContent;
import com.liquidnet.commons.lang.util.CurrentUtil;
import com.liquidnet.commons.lang.util.JsonUtils;
import com.liquidnet.service.base.ResponseDto;
import com.liquidnet.service.base.codec.vo.EncryptedReq;
import com.liquidnet.service.goblin.dto.manage.GoblinSqbOrderParam;
import com.liquidnet.service.goblin.dto.vo.GoblinSqbOrderCreateVo;
import com.liquidnet.service.goblin.service.IGoblinSqbOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.constraints.NotBlank;

@Slf4j
@Api(tags = "商城-收钱吧支付相关")
@RestController
@RequestMapping("/goblin/sqb")
@Validated
public class GoblinSqbOrderController {

    @Autowired
    private IGoblinSqbOrderService goblinSqbOrderService;
    @Autowired
    private SqbBiz sqbBiz;

    /**
     * 创建收钱吧订单
     */
    @PostMapping("/pre")
    @ApiOperation("创建收钱吧下单-加密")
    public ResponseDto<GoblinSqbOrderCreateVo> preOrder(@RequestBody EncryptedReq<GoblinSqbOrderParam> param) {
        String userId = CurrentUtil.getCurrentUid();
        GoblinSqbOrderParam orderParam = param.getData();
        return goblinSqbOrderService.createOrder(userId, orderParam);
    }

    /**
     * 创建收钱吧订单
     */
    @PostMapping("/fc7bce6d6c2213b866f76493f9222201")
    @ApiOperation("创建收钱吧下单-不加密")
    public ResponseDto<GoblinSqbOrderCreateVo> preOrder(@RequestBody @Validated GoblinSqbOrderParam param) {
        String userId = CurrentUtil.getCurrentUid();
        return goblinSqbOrderService.createOrder(userId, param);
    }

    /**
     * 查询支付状态
     */
    @GetMapping("/pay/status")
    @ApiOperation("查询支付状态")
    @ApiImplicitParam(type = "query", required = true, dataType = "String", name = "orderId", value = "本地订单ID")
    public ResponseDto<Integer> queryPayStatus(@NotBlank(message = "orderId 不能为空")
                                                   @RequestParam("orderId") String orderId) {

        String userId = CurrentUtil.getCurrentUid();
        log.info("[收钱吧支付状态] 接收请求 userId={}, orderId={}", userId, orderId);

        return goblinSqbOrderService.queryPayStatus(userId, orderId);
    }


    /**
     * 再次付款（待支付状态下重新拉起微信支付）
     */
    @PostMapping("/repay")
    @ApiOperation("再次付款")
    @ApiImplicitParam(type = "form", required = true, dataType = "String", name = "orderId", value = "本地订单ID")
    public ResponseDto<GoblinSqbOrderCreateVo> repay(
            @NotBlank(message = "orderId 不能为空") @RequestParam("orderId") String orderId) {
        String userId = CurrentUtil.getCurrentUid();
        log.info("[收钱吧再次付款] 接收请求 userId={}, orderId={}", userId, orderId);
        return goblinSqbOrderService.repay(userId, orderId);
    }


    //******************************** 回调相关 *******************************
    @ApiOperation("下单回调")
    @PostMapping("/order/callback")
    public ResponseDto<String> orderCallback(@RequestBody CallbackParams callbackParams) {
        if (null == callbackParams) {
            log.error("下单回调参数为空");
            return ResponseDto.failure("下单回调参数为空");
        }
        logSqbCallbackRaw("order", callbackParams);
        boolean verified = sqbBiz.verifySignature(callbackParams);
        if (!verified) {
            log.error("下单回调验签失败");
            return ResponseDto.failure("验签失败");
        }

        OrderCallbackContent orderCallbackContent = JsonUtils.fromJson(callbackParams.getContent(), OrderCallbackContent.class);
        // 业务
        return goblinSqbOrderService.handlePayCallback(orderCallbackContent);
    }

    @ApiOperation("退款回调")
    @PostMapping("/refund/callback")
    public ResponseDto<String> refundCallback(@RequestBody CallbackParams callbackParams) {
        if (null == callbackParams) {
            log.error("退款回调参数为空");
            return ResponseDto.failure("退款回调参数为空");
        }
        logSqbCallbackRaw("refund", callbackParams);
        boolean verified = sqbBiz.verifySignature(callbackParams);
        if (!verified) {
            log.error("退款回调验签失败");
            return ResponseDto.failure("验签失败");
        }

        RefundCallbackContent refundCallbackContent = JsonUtils.fromJson(callbackParams.getContent(), RefundCallbackContent.class);
        // 业务
        return goblinSqbOrderService.handleRefundCallback(refundCallbackContent);
    }

    @ApiOperation("券状态回调")
    @PostMapping("/coupon/callback")
    public ResponseDto<String> couponCallback(@RequestBody CallbackParams callbackParams) {
        if (null == callbackParams) {
            log.error("券状态回调参数为空");
            return ResponseDto.failure("券状态回调参数为空");
        }
        logSqbCallbackRaw("coupon", callbackParams);
        boolean verified = sqbBiz.verifySignature(callbackParams);
        if (!verified) {
            log.error("券状态回调验签失败");
            return ResponseDto.failure("验签失败");
        }

        CouponCallbackContent callbackContent = JsonUtils.fromJson(callbackParams.getContent(), CouponCallbackContent.class);
        // 业务

        return goblinSqbOrderService.handleCouponCallback(callbackContent);
    }

    /**
     * 记录收钱吧回调完整报文（eventId/timestamp/nonce/content/signature），便于复测；在验签前打印，验签失败时仍能拿到原始参数。
     */
    private void logSqbCallbackRaw(String scene, CallbackParams p) {
        log.info("[收钱吧回调-{}] 原始参数: {}", scene, JsonUtils.toJson(p));
    }
}
