package cn.freemud.controller;

import cn.freemud.base.entity.BaseResponse;
import cn.freemud.entities.vo.*;
import cn.freemud.entities.vo.order.PayConfigVo;
import cn.freemud.entities.vo.order.PaySuccessDataVo;
import cn.freemud.entities.vo.order.VirtualStoreVo;
import cn.freemud.service.ExposureOrderService;
import cn.freemud.service.RefundService;
import cn.freemud.service.impl.OrderQueueService;
import cn.freemud.service.impl.OrderServiceImpl;
import cn.freemud.service.impl.PayServiceImpl;
import cn.freemud.utils.ResponseUtil;
import com.freemud.application.sdk.api.log.ApiAnnotation;
import com.freemud.application.sdk.api.log.LogParams;
import com.freemud.application.sdk.api.ordercenter.request.OrderExtInfoDto;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 暴露订单相关的业务接口,提供给applet项目
 */
@RestController
@RequestMapping("/order/exposure")
@RequiredArgsConstructor
public class ExposureOrderController {

    private final PayServiceImpl payService;
    private final ExposureOrderService exposureOrderService;
    private final OrderServiceImpl orderService;
    private final OrderQueueService orderQueueService;
    private final RefundService refundService;

    /**
     * 创建支付单,查询支付配置
     */
    @ApiAnnotation(logMessage = "创建支付单,查询支付配置")
    @PostMapping("/getPayConfig")
    public BaseResponse<PayConfigVo> getPayConfig(@Validated @LogParams @RequestBody GetPayConfigVo req) {
        return ResponseUtil.success(exposureOrderService.getPayConfig(req));
    }

    /**
     * 生成取餐码
     */
    @ApiAnnotation(logMessage = "生成取餐码")
    @PostMapping("/genTakeCode")
    public BaseResponse<String> genTakeCode(@Validated @LogParams @RequestBody GenTakeCodeRequest req) {
        return ResponseUtil.success(exposureOrderService.genTakeCode(req.getPartnerId(), req.getStoreCode(), req.getOrderType(), req.getOrderClient()));
    }

    /**
     * 创建订单,死信队列
     */
    @ApiAnnotation(logMessage = "创建订单,死信队列")
    @PostMapping("/deadLetterQueue")
    @Deprecated
    public BaseResponse deadLetterQueue(@Validated @LogParams @RequestBody PutDeadLetterVo putDeadLetterVo) {
        payService.putDelMq(putDeadLetterVo.getPartnerId(), putDeadLetterVo.getStoreId(), putDeadLetterVo.getFmId(), putDeadLetterVo.getOrderId(), putDeadLetterVo.getPayChanelType());
        return ResponseUtil.success();
    }


    @ApiAnnotation(logMessage = "获取超时时间, 生成取餐码 废弃")
    @PostMapping("/getPaySuccessDataV2")
    public BaseResponse<PaySuccessDataVo> getPaySuccessDataV2(@Validated @LogParams @RequestBody GetPaySuccessDataV2Request request) {
        return ResponseUtil.success(exposureOrderService.getPaySuccessDataV2(request));
    }


    /**
     * 发送支付成功模板消息
     */
    @ApiAnnotation(logMessage = "发送支付成功模板消息")
    @PostMapping("/sendPayTemplateMessage")
    public BaseResponse sendPayTemplateMessage(@Validated @LogParams @RequestBody SendPaySuccessMessageVo sendPaySuccessMessageVo) {
        return ResponseUtil.success();
    }


    /**
     * 现金支付,设置轮循队列
     */
    @ApiAnnotation(logMessage = "现金支付,设置轮循队列")
    @PostMapping("/putRoundRobin")
    public BaseResponse putRoundRobin(@Validated @LogParams @RequestBody PutRoundRobinVo putRoundRobinVo) {
        payService.putRoundRobin(putRoundRobinVo);
        return ResponseUtil.success();
    }

    /**
     * 回滚订单状态改动
     */
    @ApiAnnotation(logMessage = "回滚订单状态改动")
    @PostMapping("/backOrdersStatusChange")
    public BaseResponse backOrdersStatusChange(@Validated @LogParams @RequestBody BackOrdersStatusChangeVo backOrdersStatusChangeVo) {
        orderQueueService.backOrdersStatusChange(backOrdersStatusChangeVo.getOrderCode(), backOrdersStatusChangeVo.getOrderState(),backOrdersStatusChangeVo.getPartnerId());
        return ResponseUtil.success();
    }

    /**
     * 新商城支付门店配置
     */
    @ApiAnnotation(logMessage = "新商城支付门店配置")
    @PostMapping("/getMallPayConfig")
    public BaseResponse<PayConfigVo> getMallPayConfig(@Validated @LogParams @RequestBody GetMallPayConfigVo req) {
        return ResponseUtil.success(exposureOrderService.getMallPayConfig(req));
    }


    /**
     * 公共支付接口查询mq,死信队列
     * 支付回调的url必须在订单ext里的payCallbackUrl属性
     * @see OrderExtInfoDto#getPayCallbackUrl()
     */
    @ApiAnnotation(logMessage = "支付结果查询mq-(会员，点餐下单公共),死信队列")
    @PostMapping("/payQueryMq")
    public BaseResponse payQueryMq(@Validated @LogParams @RequestBody PayQueryMqVo putDeadLetterVo) {
        payService.putPayQueryDelMq(putDeadLetterVo.getPartnerId(), putDeadLetterVo.getStoreId(), putDeadLetterVo.getFmId(), putDeadLetterVo.getOrderId(), putDeadLetterVo.getPayChanelType());
        return ResponseUtil.success();
    }
    /**
     * 查询支付虚拟门店配置
     */
    @ApiAnnotation(logMessage = "查询支付虚拟门店配置")
    @PostMapping("/getVirtualStore")
    public BaseResponse<String> getVirtualStore(@Validated @LogParams @RequestBody GetVirtualStoreRequest req) {
        return ResponseUtil.success(exposureOrderService.getVirtualStore(req.getAppId(), req.getType()));
    }

    @ApiAnnotation(logMessage = "查询订单宝购买储值卡配置的支付虚拟门店信息")
    @PostMapping("/getPayVirtualStore")
    public BaseResponse<VirtualStoreVo> getPayVirtualStore(@Validated @LogParams @RequestBody GetPayVirtualStoreRequest req) {
        return ResponseUtil.success(exposureOrderService.getPayVirtualStore(req.getPartnerId(), req.getType()));
    }

    /**
     * 查询支付配置paycode
     */
    @ApiAnnotation(logMessage = "查询支付配置paycode")
    @PostMapping("/getPayCode")
    public BaseResponse<String> getPayCode(@Validated @LogParams @RequestBody GetPayCodeVo req) {
        return ResponseUtil.success(exposureOrderService.getPayCode(req));
    }

    /**
     * 退订单金额（仅退款，不会处理订单状态）
     * 返回退款状态， 1-成功 {@link cn.freemud.enums.PayRefundStatus}
     */
    @PostMapping("/refundOrderAmt")
    @ApiAnnotation(logMessage = "退订单金额（仅退款，不会处理订单状态）")
    public BaseResponse<Integer> refundOrderAmt(@Validated @LogParams @RequestBody RefundOrderAmtRequest request) {
        return ResponseUtil.success(refundService.refundOrderAmt(request.getPartnerId(), request.getOrderCode(), request.getReason()));
    }

}
