package com.sckw.payment.controller;

import com.sckw.core.web.response.HttpResult;
import com.sckw.payment.model.dto.Id;
import com.sckw.payment.model.vo.req.*;
import com.sckw.payment.model.vo.req.page.MoneyPage;
import com.sckw.payment.model.vo.req.page.PrePayPage;
import com.sckw.payment.model.vo.req.page.RefundPage;
import com.sckw.payment.service.WalletService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 钱包
 *
 * @author xucaiqin
 * @date 2023-08-28 15:36:48
 */
@Tag(name = "钱包管理", description = "提供钱包相关操作接口")
@Validated
@RestController
@RequestMapping("/wallet")
@Slf4j
public class WalletController {
    @Resource
    private WalletService walletService;

    /**
     * 开户
     *
     * @param createUserReq 开户请求参数
     * @return 操作结果
     */
    @Operation(summary = "开户", description = "为用户开通钱包账户")
    @PostMapping("createUser")
    public HttpResult createUser(@RequestBody @Valid CreateUserReq createUserReq) {
        return HttpResult.ok(walletService.createUser(createUserReq));
    }

    /**
     * 渠道用户开通信息
     *
     * @param uid     用户ID
     * @param channel 渠道
     * @return 用户开通信息
     */
    @Operation(summary = "查询渠道用户开通信息", description = "查询指定用户在指定渠道的开通信息")
    @Parameter(name = "uid", description = "用户ID", required = true)
    @Parameter(name = "channel", description = "渠道", required = true)
    @GetMapping("userInfo")
    public HttpResult userInfo(@NotBlank(message = "uid不能为空") @RequestParam("uid") String uid,
                               @NotBlank(message = "channel不能为空") @RequestParam("channel") String channel) {
        return HttpResult.ok(walletService.userInfo(uid, channel));
    }

    /**
     * 钱包总览信息
     *
     * @param queryChannel 是否查询渠道信息
     * @return 钱包总览信息
     */
    @Operation(summary = "钱包总览信息", description = "获取当前用户的钱包总览信息")
    @Parameter(name = "queryChannel", description = "是否查询渠道信息")
    @GetMapping("overview")
    public HttpResult overview(boolean queryChannel) {
        return HttpResult.ok(walletService.walletOverview(queryChannel));
    }

    /**
     * 渠道开通情况
     *
     * @return 渠道开通情况列表
     */
    @Operation(summary = "渠道开通情况", description = "查询所有渠道的开通情况")
    @GetMapping("channel")
    public HttpResult channel() {
        return HttpResult.ok(walletService.channel());
    }

    /**
     * 查询资金明细
     *
     * @param walletDetailReq 查询参数
     * @return 资金明细列表
     */
    @Operation(summary = "查询资金明细", description = "根据条件查询资金明细")
    @GetMapping("detail")
    public HttpResult detail(WalletDetailReq walletDetailReq) {
        return HttpResult.ok(walletService.walletDetail(walletDetailReq));
    }

    /**
     * 查询资金明细-按渠道统计数量
     *
     * @param entName 企业名称
     * @return 统计结果
     */
    @Operation(summary = "资金明细按渠道统计", description = "按渠道统计资金明细数量")
    @Parameter(name = "entName", description = "企业名称")
    @GetMapping("detailCount")
    public HttpResult count(String entName) {
        return HttpResult.ok(walletService.walletCount(entName));
    }

    /**
     * 新增账目
     *
     * @param addWalletReq 新增账目参数
     * @return 操作结果
     */
    @Operation(summary = "新增账目", description = "新增一笔账目")
    @PostMapping("add")
    public HttpResult add(@RequestBody @Valid AddWalletReq addWalletReq) {
        return HttpResult.ok(walletService.addWallet(addWalletReq));
    }

    /**
     * 账目充值
     *
     * @param addWalletReq 充值参数
     * @return 操作结果
     */
    @Operation(summary = "账目充值", description = "为账户充值")
    @PostMapping("recharge")
    public HttpResult recharge(@RequestBody @Valid WalletAppendReq addWalletReq) {
        return HttpResult.ok(walletService.addWalletMoney(addWalletReq));
    }

    /**
     * 提现
     *
     * @param cashWalletReq 提现参数
     * @return 操作结果
     */
    @Operation(summary = "提现", description = "发起提现操作")
    @PostMapping("cashOUt")
    public HttpResult cashOUt(@RequestBody @Valid CashWalletReq cashWalletReq) {
        return HttpResult.ok(walletService.cashOUt(cashWalletReq));
    }

    /**
     * 重新提现
     *
     * @param cashWalletReq 提现参数
     * @return 操作结果
     */
    @Operation(summary = "重新提现", description = "重新发起提现操作")
    @PostMapping("reCashOUt")
    public HttpResult reCashOUt(@RequestBody @Valid CashWalletReq cashWalletReq) {
        return HttpResult.ok(walletService.reCashOUt(cashWalletReq));
    }

    /**
     * 转账
     *
     * @param transferReq 转账参数
     * @return 操作结果
     */
    @Operation(summary = "转账", description = "发起转账操作")
    @PostMapping("transfer")
    public HttpResult transfer(@RequestBody @Valid TransferReq transferReq) {
        return HttpResult.ok(walletService.transfer(transferReq));
    }

    /**
     * 提现记录
     *
     * @param cashPageReq 查询参数
     * @return 提现记录列表
     */
    @Operation(summary = "提现记录", description = "查询提现记录")
    @GetMapping("cashList")
    public HttpResult cashList(CashPageReq cashPageReq) {
        return HttpResult.ok(walletService.cashList(cashPageReq));
    }

    /**
     * 提现记录 分类统计
     *
     * @param cashPageReq 查询参数
     * @return 统计结果
     */
    @Operation(summary = "提现记录分类统计", description = "对提现记录进行分类统计")
    @GetMapping("cashCount")
    public HttpResult cashCount(CashPageReq cashPageReq) {
        return HttpResult.ok(walletService.cashCount(cashPageReq));
    }

    /**
     * 预付列表
     *
     * @param prePayPage 查询参数
     * @return 预付列表
     */
    @Operation(summary = "预付列表", description = "查询预付列表")
    @GetMapping("prePayList")
    public HttpResult prePayList(PrePayPage prePayPage) {
        return HttpResult.ok(walletService.prePayList(prePayPage));
    }


    /**
     * 预付列表-按渠道统计数量
     *
     * @param entName 企业名称
     * @return 统计结果
     */
    @Operation(summary = "预付列表按渠道统计", description = "预付列表-按渠道统计数量")
    @Parameter(name = "entName", description = "企业名称")
    @GetMapping("prePayCount")
    public HttpResult prePayCount(String entName) {
        return HttpResult.ok(walletService.prePayCount(entName));
    }

    /**
     * 预收列表
     *
     * @param prePayPage 查询参数
     * @return 预收列表
     */
    @Operation(summary = "预收列表", description = "查询预收列表")
    @GetMapping("preReceiveList")
    public HttpResult preReceiveList(PrePayPage prePayPage) {
        return HttpResult.ok(walletService.preReceiveList(prePayPage));
    }

    /**
     * 预收列表-按渠道统计数量
     *
     * @param entName 企业名称
     * @return 统计结果
     */
    @Operation(summary = "预收列表按渠道统计", description = "预收列表-按渠道统计数量")
    @Parameter(name = "entName", description = "企业名称")
    @GetMapping("preReceiveCount")
    public HttpResult preReceiveCount(String entName) {
        return HttpResult.ok(walletService.preReceiveCount(entName));
    }

    /**
     * 预付校验
     *
     * @param prePayCheck 校验参数
     * @return 校验结果
     */
    @Operation(summary = "预付校验", description = "预付操作前的校验")
    @PostMapping("prePayCheck")
    public HttpResult prePayCheck(@RequestBody @Valid PrePayCheck prePayCheck) {
        return HttpResult.ok(walletService.prePayCheck(prePayCheck));
    }

    /**
     * 新增预付
     *
     * @param prePay 预付参数
     * @return 操作结果
     */
    @Operation(summary = "新增预付", description = "新增一笔预付")
    @PostMapping("addPrePay")
    public HttpResult addPrePay(@RequestBody @Valid PrePay prePay) {
        return HttpResult.ok(walletService.addPrePay(prePay));
    }

    /**
     * 处理查询
     *
     * @param operateReq 查询参数
     * @return 查询结果
     */
    @Operation(summary = "处理查询", description = "查询处理信息")
    @PostMapping("dealQuery")
    public HttpResult dealQuery(@RequestBody @Valid OperateReq operateReq) {
        return HttpResult.ok(walletService.dealQuery(operateReq));
    }

    /**
     * 提现确认
     * @param cashCheck 提现确认参数
     * @return 操作结果
     */
    @Operation(summary = "提现确认", description = "确认提现操作")
    @PostMapping("cashCheck")
    public HttpResult cashCheck(@RequestBody @Valid CashCheck cashCheck) {
        return HttpResult.ok(walletService.cashCheck(cashCheck));
    }

    /**
     * 预付追加校验
     *
     * @param appendPayCheck 校验参数
     * @return 校验结果
     */
    @Operation(summary = "预付追加校验", description = "预付追加操作前的校验")
    @PostMapping("appendCheck")
    public HttpResult prePayAppendCheck(@RequestBody @Valid AppendPayCheck appendPayCheck) {
        return HttpResult.ok(walletService.appendCheck(appendPayCheck));
    }

    /**
     * 预付追加
     *
     * @param prePay 追加参数
     * @return 操作结果
     */
    @Operation(summary = "预付追加", description = "追加预付金额")
    @PostMapping("prePayAppend")
    public HttpResult prePayAppend(@RequestBody @Valid PrePayAppend prePay) {
        return HttpResult.ok(walletService.prePayAppend(prePay));
    }


    /*退款*/

    /**
     * 申请退款(预付方)
     *
     * @param refundReq 退款参数
     * @return 操作结果
     */
    @Operation(summary = "申请退款", description = "申请退款(预付方)")
    @PostMapping("applyRefund")
    public HttpResult applyRefund(@RequestBody @Valid ApplyRefundReq refundReq) {
        return HttpResult.ok(walletService.applyRefund(refundReq));
    }


    /**
     * 查询退款列表(预收方)
     *
     * @param refundPage 查询参数
     * @return 退款列表
     */
    @Operation(summary = "查询退款列表", description = "查询退款列表(预收方)")
    @PostMapping("refundList")
    public HttpResult refundList(@RequestBody @Valid RefundPage refundPage) {
        return HttpResult.ok(walletService.refundList(refundPage));
    }


    /**
     * 发起退款（预收方）余额查询及校验
     *
     * @param id 退款单id
     * @return 校验结果
     */
    @Operation(summary = "发起退款校验", description = "发起退款（预收方）余额查询及校验")
    @PostMapping("refundCheck")
    public HttpResult refundCheck(@RequestBody @Valid Id id) {
        return HttpResult.ok(walletService.refundCheck(id.getIdLong()));
    }

    /**
     * 确认退款
     *
     * @param refundReq 退款参数
     * @return 操作结果
     */
    @Operation(summary = "确认退款", description = "确认退款操作")
    @PostMapping("refund")
    public HttpResult refund(@RequestBody @Valid RefundReq refundReq) {
        return HttpResult.ok(walletService.launchRefund(refundReq));
    }

    /**
     * 驳回退款
     *
     * @param refundReq 驳回参数
     * @return 操作结果
     */
    @Operation(summary = "驳回退款", description = "驳回退款申请")
    @PostMapping("backRefund")
    public HttpResult back(@RequestBody @Valid RefundBackReq refundReq) {
        return HttpResult.ok(walletService.backRefund(refundReq));
    }



    /*资金明细-详细记录*/

    /**
     * 充值订单
     *
     * @param moneyPage 查询参数
     * @return 充值订单列表
     */
    @Operation(summary = "充值订单", description = "查询充值订单列表")
    @PostMapping("rechargeOrder")
    public HttpResult rechargeList(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.rechargeList(moneyPage));
    }

    /**
     * 转账订单
     *
     * @param moneyPage 查询参数
     * @return 转账订单列表
     */
    @Operation(summary = "转账订单", description = "查询转账订单列表")
    @PostMapping("transferOrder")
    public HttpResult transferList(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.transferOrder(moneyPage));
    }

    /**
     * 货到付款订单
     *
     * @param moneyPage 查询参数
     * @return 货到付款订单列表
     */
    @Operation(summary = "货到付款订单", description = "查询货到付款订单列表")
    @PostMapping("receiveOrder")
    public HttpResult receiveOrder(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.transferReceiveOrder(moneyPage));
    }

    /**
     * 退款订单
     *
     * @param moneyPage 查询参数
     * @return 退款订单列表
     */
    @Operation(summary = "退款订单", description = "查询退款订单列表")
    @PostMapping("refundOrder")
    public HttpResult refundOrder(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.refundOrder(moneyPage));
    }

    /**
     * 提现订单
     *
     * @param moneyPage 查询参数
     * @return 提现订单列表
     */
    @Operation(summary = "提现订单", description = "查询提现订单列表")
    @PostMapping("cashOrder")
    public HttpResult cashOrder(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.cashOrder(moneyPage));
    }

    /*提现-详细记录*/

    /**
     * 提现详情
     *
     * @param cashDetailReq 查询参数
     * @return 提现详情
     */
    @Operation(summary = "提现详情", description = "查询提现详情")
    @PostMapping("cashDetail")
    public HttpResult cashDetail(@RequestBody @Valid CashDetailReq cashDetailReq) {
        return HttpResult.ok(walletService.cashDetail(cashDetailReq));
    }
    /*预付-详细记录*/

    /**
     * 预付订单
     *
     * @param moneyPage 查询参数
     * @return 预付订单列表
     */
    @Operation(summary = "预付订单", description = "查询预付订单列表")
    @PostMapping("prePayOrder")
    public HttpResult prePayOrder(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.prePayOrder(moneyPage));
    }

    /**
     * 退款记录
     *
     * @param moneyPage 查询参数
     * @return 退款记录列表
     */
    @Operation(summary = "预付退款记录", description = "查询预付退款记录")
    @PostMapping("prePayRefund")
    public HttpResult prePayRefund(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.prePayRefund(moneyPage));
    }

    /**
     * 预付消费日志
     *
     * @param moneyPage 查询参数
     * @return 消费日志列表
     */
    @Operation(summary = "预付消费日志", description = "查询预付消费日志")
    @GetMapping("prePayLogs")
    public HttpResult prePayLogs(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.prePayLogs(moneyPage));
    }
    /*预收-详细记录*/

    /**
     * 预收订单
     *
     * @param moneyPage 查询参数
     * @return 预收订单列表
     */
    @Operation(summary = "预收订单", description = "查询预收订单列表")
    @PostMapping("preReceiveOrder")
    public HttpResult preReceiveOrder(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.preReceiveOrder(moneyPage));
    }

    /**
     * 退款订单
     *
     * @param moneyPage 查询参数
     * @return 退款订单列表
     */
    @Operation(summary = "预收退款订单", description = "查询预收退款订单")
    @PostMapping("preReceiveRefund")
    public HttpResult preReceiveRefund(@RequestBody @Valid MoneyPage moneyPage) {
        return HttpResult.ok(walletService.preReceiveRefund(moneyPage));
    }
}