package com.bizzan.bitrade.controller;

import com.bizzan.bitrade.constant.BooleanEnum;
import com.bizzan.bitrade.entity.Coin;
import com.bizzan.bitrade.entity.CoinNetworkConfig;
import com.bizzan.bitrade.entity.CoinRechargeOrder;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.service.CoinNetworkConfigService;
import com.bizzan.bitrade.service.CoinRechargeOrderService;
import com.bizzan.bitrade.service.CoinService;
import com.bizzan.bitrade.util.MessageResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;

import static com.bizzan.bitrade.constant.SysConstant.SESSION_MEMBER;

/**
 * 链上充值接口（用户端）
 * 流程：创建充值订单 → 前端调用第三方钱包转账 → 回写交易 hash → 等待链上确认
 *
 * @author auto
 * @date 2026-05-13
 */
@Api(value = "CoinRechargeController", tags = "链上充值接口")
@RestController
@RequestMapping("recharge")
@Slf4j
public class CoinRechargeController extends BaseController {

    @Autowired
    private CoinRechargeOrderService coinRechargeOrderService;

    @Autowired
    private CoinService coinService;

    @Autowired
    private CoinNetworkConfigService coinNetworkConfigService;

    /**
     * 创建充值订单
     * 校验子币种和主网配置后生成待支付订单，返回订单号和收款地址供前端使用
     *
     * @param member          当前登录用户
     * @param coinName        子币种名称，如 EUSDT / TUSDT
     * @param networkConfigId 主网配置ID，来自 /coin-network/recharge-configs 接口
     * @param amount          充值金额
     * @return 订单信息（含订单号、收款地址）
     */
    @ApiOperation(value = "创建充值订单", notes = "生成待支付订单，返回订单号和收款地址，前端据此调用第三方钱包")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "coinName",        value = "子币种名称，如 EUSDT", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "networkConfigId", value = "主网配置ID",           required = true, dataType = "long",   paramType = "query"),
            @ApiImplicitParam(name = "amount",          value = "充值金额",             required = true, dataType = "string", paramType = "query")
    })
    @PostMapping("create")
    public MessageResult createOrder(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                     @RequestParam("coinName") String coinName,
                                     @RequestParam("networkConfigId") Long networkConfigId,
                                     @RequestParam("amount") BigDecimal amount) {
        // 1. 参数基础校验
        if (StringUtils.isBlank(coinName)) {
            return error("币种名称不能为空");
        }
        if (networkConfigId == null) {
            return error("主网配置ID不能为空");
        }
        if (amount == null || amount.compareTo(BigDecimal.ZERO) <= 0) {
            return error("充值金额必须大于0");
        }
        // 2. 校验子币种存在且可充值
        Coin coin = coinService.findOne(coinName);
        if (coin == null) {
            return error("币种不存在：" + coinName);
        }
        if (coin.getCanRecharge() != BooleanEnum.IS_TRUE) {
            return error("该币种暂不支持充值");
        }
        // 3. 校验主网配置存在
        CoinNetworkConfig networkConfig = coinNetworkConfigService.findById(networkConfigId);
        if (networkConfig == null) {
            return error("主网配置不存在");
        }
        // 4. 校验主网配置归属于该子币种
        if (!networkConfig.getCoinName().equals(coinName)) {
            return error("主网配置与币种不匹配");
        }
        // 5. 创建订单
        try {
            CoinRechargeOrder order = coinRechargeOrderService.createOrder(
                    member.getId(), coin, networkConfig, amount);
            return success(order);
        } catch (IllegalArgumentException e) {
            return error(e.getMessage());
        }
    }

    /**
     * 回写交易 hash，将订单状态变更为待链上确认
     * 用户通过第三方钱包完成转账后调用此接口提交 hash
     *
     * @param member   当前登录用户
     * @param orderNo  订单号
     * @param txHash   链上交易 hash
     * @return 更新后的订单信息
     */
    @ApiOperation(value = "提交交易 hash", notes = "用户完成链上转账后回写 hash，订单状态变为待链上确认")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "txHash",  value = "链上交易 hash", required = true, dataType = "string", paramType = "query")
    })
    @PostMapping("submit-hash")
    public MessageResult submitHash(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                    @RequestParam("orderNo") String orderNo,
                                    @RequestParam("txHash") String txHash) {
        // 1. 参数校验
        if (StringUtils.isBlank(orderNo)) {
            return error("订单号不能为空");
        }
        if (StringUtils.isBlank(txHash)) {
            return error("交易 hash 不能为空");
        }
        // 2. 回写 hash
        try {
            CoinRechargeOrder order = coinRechargeOrderService.submitTxHash(orderNo, member.getId(), txHash);
            return success(order);
        } catch (IllegalArgumentException e) {
            return error(e.getMessage());
        }
    }

    /**
     * 查询当前用户的充值订单列表（分页）
     *
     * @param member   当前登录用户
     * @param pageNo   页码，从1开始，默认1
     * @param pageSize 每页条数，默认10
     * @return 分页订单列表
     */
    @ApiOperation(value = "查询充值订单列表", notes = "分页查询当前用户的充值订单，按创建时间倒序")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageNo",   value = "页码，从1开始", dataType = "int", paramType = "query", defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize", value = "每页条数",      dataType = "int", paramType = "query", defaultValue = "10")
    })
    @GetMapping("orders")
    public MessageResult listOrders(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                    @RequestParam(value = "pageNo",   defaultValue = "1")  int pageNo,
                                    @RequestParam(value = "pageSize", defaultValue = "10") int pageSize) {
        Page<CoinRechargeOrder> page = coinRechargeOrderService.findByMemberId(
                member.getId(), pageNo, pageSize);
        return success(page);
    }

    /**
     * 查询单笔充值订单详情
     *
     * @param member  当前登录用户
     * @param orderNo 订单号
     * @return 订单详情
     */
    @ApiOperation(value = "查询充值订单详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderNo", value = "订单号", required = true, dataType = "string", paramType = "query")
    })
    @GetMapping("order")
    public MessageResult getOrder(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                  @RequestParam("orderNo") String orderNo) {
        if (StringUtils.isBlank(orderNo)) {
            return error("订单号不能为空");
        }
        try {
            CoinRechargeOrder order = coinRechargeOrderService.findByOrderNoAndMemberId(
                    orderNo, member.getId());
            return success(order);
        } catch (IllegalArgumentException e) {
            return error(e.getMessage());
        }
    }
}
