package com.bizzan.bitrade.controller;

import com.bizzan.bitrade.entity.CoinNetwork;
import com.bizzan.bitrade.entity.CoinNetworkConfig;
import com.bizzan.bitrade.entity.Coin;
import com.bizzan.bitrade.service.CoinNetworkConfigService;
import com.bizzan.bitrade.service.CoinNetworkService;
import com.bizzan.bitrade.service.CoinService;
import com.bizzan.bitrade.util.MessageResult;
import com.bizzan.bitrade.vo.CoinChildWithNetworkVO;
import com.bizzan.bitrade.vo.CoinRechargeConfigVO;
import com.bizzan.bitrade.vo.CoinWithdrawConfigVO;
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.web.bind.annotation.*;

import java.util.List;

/**
 * 主网与币种主网配置查询接口（用户端）
 * 提供主网列表查询、指定币种可用主网查询等功能，供充值/提币流程选择网络使用。
 *
 * @author auto
 * @date 2026-05-13
 */
@Api(value = "CoinNetworkController", tags = "主网与币种主网配置接口")
@RestController
@RequestMapping("coin-network")
@Slf4j
public class CoinNetworkController extends BaseController {

    @Autowired
    private CoinNetworkService coinNetworkService;

    @Autowired
    private CoinNetworkConfigService coinNetworkConfigService;

    @Autowired
    private CoinService coinService;

    /**
     * 查询所有启用的主网列表
     *
     * @return 主网列表
     */
    @ApiOperation(value = "查询所有启用的主网列表", notes = "返回状态正常的主网，按排序升序")
    @GetMapping("list")
    public MessageResult listNetworks() {
        List<CoinNetwork> networks = coinNetworkService.findAllEnabled();
        return success(networks);
    }

    /**
     * 查询指定币种下可用的主网配置列表（用于充提网络选择）
     *
     * @param coinName 币种名称，如 USDT
     * @return 该币种下状态正常的主网配置列表
     */
    @ApiOperation(value = "查询指定币种的可用主网配置", notes = "供充值/提币流程选择网络，返回状态正常的配置")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "coinName", value = "币种名称，如 USDT", required = true, dataType = "string", paramType = "query")
    })
    @GetMapping("configs")
    public MessageResult listConfigsByCoin(@RequestParam("coinName") String coinName) {
        if (StringUtils.isBlank(coinName)) {
            return error("币种名称不能为空");
        }
        // 校验币种是否存在
        Coin coin = coinService.findOne(coinName);
        if (coin == null) {
            return error("币种不存在：" + coinName);
        }
        List<CoinNetworkConfig> configs = coinNetworkConfigService.findByCoinName(coinName);
        return success(configs);
    }

    /**
     * 查询指定币种在指定主网下的配置详情
     *
     * @param coinName  币种名称
     * @param networkId 主网ID
     * @return 配置详情
     */
    @ApiOperation(value = "查询某币种在某主网下的配置详情")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "coinName",  value = "币种名称", required = true, dataType = "string", paramType = "query"),
        @ApiImplicitParam(name = "networkId", value = "主网ID",  required = true, dataType = "long",   paramType = "query")
    })
    @GetMapping("config")
    public MessageResult getConfig(@RequestParam("coinName") String coinName,
                                   @RequestParam("networkId") Long networkId) {
        if (StringUtils.isBlank(coinName) || networkId == null) {
            return error("参数不能为空");
        }
        CoinNetworkConfig config = coinNetworkConfigService.findByCoinAndNetwork(coinName, networkId);
        if (config == null) {
            return error("未找到对应主网配置");
        }
        return success(config);
    }

    /**
     * 查询某币种及其所有子币种（parentCoinName = coinName）的主网配置
     * 适用于显示一个币种在所有主网上的充提入口
     *
     * @param coinName 上级币种名称，如 USDT
     * @return 子币种列表（各主网对应的子币种）
     */
    @ApiOperation(value = "查询某币种的所有子币种", notes = "返回 parentCoinName=coinName 的所有子币种信息")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "coinName", value = "上级币种名称", required = true, dataType = "string", paramType = "query")
    })
    @GetMapping("children")
    public MessageResult listChildCoins(@RequestParam("coinName") String coinName) {
        if (StringUtils.isBlank(coinName)) {
            return error("币种名称不能为空");
        }
        List<Coin> children = coinService.findByParentCoinName(coinName);
        return success(children);
    }

    /**
     * 查询可充值的顶级币种列表（无上级、canRecharge=true、状态正常）
     * 用于充值流程第一步：让用户选择要充值的币种
     *
     * @return 顶级可充值币种列表
     */
    @ApiOperation(value = "查询可充值的顶级币种列表", notes = "返回 canRecharge=true 且 parentCoinName 为空的顶级币种，按 sort 升序")
    @GetMapping("recharge-parents")
    public MessageResult listRechargeParentCoins() {
        List<Coin> coins = coinService.findAllRechargeParentCoins();
        return success(coins);
    }

    /**
     * 充值：查询顶级币种下已在 coin_network_config 配置的可选主网
     */
    @ApiOperation(value = "充值可选主网", notes = "按 coin_network_config + coin 表查询，返回该顶级币种下已配置且可充值的主网")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "coinName", value = "顶级币种名称，如 USDT", required = true, dataType = "string", paramType = "query")
    })
    @GetMapping("recharge-networks")
    public MessageResult listRechargeNetworks(@RequestParam("coinName") String coinName) {
        if (StringUtils.isBlank(coinName)) {
            return error("币种名称不能为空");
        }
        Coin parent = coinService.findOne(coinName);
        if (parent == null) {
            return error("币种不存在：" + coinName);
        }
        return success(coinNetworkConfigService.findRechargeNetworksByParent(coinName));
    }

    /**
     * 内部转账：可选主币（与充值一致：无上级且可充值）
     */
    @ApiOperation(value = "内部转账可选主币", notes = "返回 coin 表中 parent_coin_name 为空且 can_recharge=true 的顶级币种")
    @GetMapping("transfer-parents")
    public MessageResult listTransferParentCoins() {
        return success(coinService.findAllRechargeParentCoins());
    }

    /**
     * 提币：可选主网列表（coin_network 表，且存在可提币种配置）
     */
    @ApiOperation(value = "提币可选主网", notes = "来自 coin_network，仅返回已配置可提币种且状态正常的主网")
    @GetMapping("withdraw-networks")
    public MessageResult listWithdrawNetworks() {
        return success(coinNetworkConfigService.findWithdrawNetworks());
    }

    /**
     * 提币：按主网 ID 查询 coin_network_config 下可提子币种
     */
    @ApiOperation(value = "提币可选子币种", notes = "按 networkId 查询 coin_network_config，币种须 canWithdraw=true")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "networkId", value = "主网ID coin_network.id", required = true, dataType = "long", paramType = "query")
    })
    @GetMapping("withdraw-configs")
    public MessageResult listWithdrawConfigs(@RequestParam("networkId") Long networkId) {
        if (networkId == null) {
            return error("networkId 不能为空");
        }
        CoinNetwork network = coinNetworkService.findById(networkId);
        if (network == null) {
            return error("主网不存在");
        }
        List<CoinWithdrawConfigVO> configs = coinNetworkConfigService.findWithdrawConfigsByNetwork(networkId);
        return success(configs);
    }

    /**
     * 充值：按主网 ID 从 coin_network_config 查询子币种列表
     */
    @ApiOperation(value = "充值可选子币种", notes = "按 networkId 查询 coin_network_config，仅返回 parentCoinName=coinName 的可充值子币")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "coinName", value = "顶级币种名称，如 USDT", required = true, dataType = "string", paramType = "query"),
        @ApiImplicitParam(name = "networkId", value = "主网ID coin_network.id", required = true, dataType = "long", paramType = "query")
    })
    @GetMapping("recharge-configs")
    public MessageResult listRechargeConfigs(@RequestParam("coinName") String coinName,
                                             @RequestParam("networkId") Long networkId) {
        if (StringUtils.isBlank(coinName) || networkId == null) {
            return error("参数不能为空");
        }
        Coin parent = coinService.findOne(coinName);
        if (parent == null) {
            return error("币种不存在：" + coinName);
        }
        CoinNetwork network = coinNetworkService.findById(networkId);
        if (network == null) {
            return error("主网不存在");
        }
        List<CoinRechargeConfigVO> configs =
                coinNetworkConfigService.findRechargeConfigsByParentAndNetwork(coinName, networkId);
        return success(configs);
    }

    @GetMapping("children-with-network")
    public MessageResult listChildrenWithNetwork(@RequestParam("coinName") String coinName) {
        if (StringUtils.isBlank(coinName)) {
            return error("币种名称不能为空");
        }
        // 1. 校验顶级币种是否存在
        Coin parent = coinService.findOne(coinName);
        if (parent == null) {
            return error("币种不存在：" + coinName);
        }
        // 2. 查询子币种列表
        List<Coin> children = coinService.findByParentCoinName(coinName);
        // 3. 组合子币种与主网配置
        List<CoinChildWithNetworkVO> result = coinNetworkConfigService.buildChildrenWithNetwork(children);
        return success(result);
    }
}
