package com.bizzan.bitrade.service;

import com.bizzan.bitrade.dao.CoinDao;
import com.bizzan.bitrade.dao.CoinNetworkConfigDao;
import com.bizzan.bitrade.dao.CoinNetworkDao;
import com.bizzan.bitrade.entity.Coin;
import com.bizzan.bitrade.entity.CoinNetwork;
import com.bizzan.bitrade.entity.CoinNetworkConfig;
import com.bizzan.bitrade.service.Base.BaseService;
import com.bizzan.bitrade.vo.CoinChildWithNetworkVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 币种主网配置 Service
 *
 * @author auto
 * @date 2026-05-13
 */
@Service
public class CoinNetworkConfigService extends BaseService {

    @Autowired
    private CoinNetworkConfigDao coinNetworkConfigDao;

    @Autowired
    private CoinNetworkDao coinNetworkDao;

    @Autowired
    private CoinDao coinDao;

    /**
     * 某主网下可配置币种（子币且未配置；编辑时可包含当前币种）
     */
    @Transactional(readOnly = true)
    public List<String> findAvailableCoinNames(Long networkId, String includeCoinName) {
        if (StringUtils.hasText(includeCoinName)) {
            return coinDao.findAvailableCoinNamesForNetworkEdit(networkId, includeCoinName.trim());
        }
        return coinDao.findAvailableCoinNamesForNetwork(networkId);
    }

    /**
     * 查询某币种下所有主网配置，按排序升序
     *
     * @param coinName 币种名称
     * @return 配置列表
     */
    @Transactional(readOnly = true)
    public List<CoinNetworkConfig> findByCoinName(String coinName) {
        return coinNetworkConfigDao.findAllByCoinNameOrderBySortAsc(coinName);
    }

    /**
     * 查询某主网下的所有币种配置
     *
     * @param networkId 主网ID
     * @return 配置列表
     */
    @Transactional(readOnly = true)
    public List<CoinNetworkConfig> findByNetworkId(Long networkId) {
        return coinNetworkConfigDao.findAllByNetworkId(networkId);
    }

    /**
     * 查询某币种在某主网下的配置
     *
     * @param coinName  币种名称
     * @param networkId 主网ID
     * @return 配置信息，不存在返回 null
     */
    @Transactional(readOnly = true)
    public CoinNetworkConfig findByCoinAndNetwork(String coinName, Long networkId) {
        return coinNetworkConfigDao.findByCoinNameAndNetworkId(coinName, networkId);
    }

    /**
     * 按ID查询配置
     *
     * @param id 配置ID
     * @return 配置信息
     */
    @Transactional(readOnly = true)
    public CoinNetworkConfig findById(Long id) {
        return coinNetworkConfigDao.findOne(id);
    }

    /**
     * 新增币种主网配置
     *
     * @param config 配置信息（network 字段须含有效 id）
     * @return 保存后的配置
     * @throws IllegalArgumentException 主网不存在或该配置已存在时抛出
     */
    @Transactional(rollbackFor = Exception.class)
    public CoinNetworkConfig save(CoinNetworkConfig config) {
        CoinNetwork network = coinNetworkDao.findOne(config.getNetwork().getId());
        if (network == null) {
            throw new IllegalArgumentException("主网不存在，networkId=" + config.getNetwork().getId());
        }
        if (coinNetworkConfigDao.existsByCoinNameAndNetworkId(config.getCoinName(), network.getId())) {
            throw new IllegalArgumentException("该币种主网配置已存在：" + config.getCoinName() + " / " + network.getName());
        }
        config.setNetwork(network);
        return coinNetworkConfigDao.save(config);
    }

    /**
     * 更新币种主网配置
     *
     * @param config 配置信息（须含有效 id）
     * @return 更新后的配置
     */
    @Transactional(rollbackFor = Exception.class)
    public CoinNetworkConfig update(CoinNetworkConfig config) {
        return coinNetworkConfigDao.save(config);
    }

    /**
     * 批量查询子币种列表及其主网配置，组合为 VO 返回
     * 适用于充值流程：根据顶级币种查询所有子币种及对应主网信息
     *
     * @param children 子币种列表
     * @return 子币种与主网配置组合列表
     */
    @Transactional(readOnly = true)
    public List<CoinChildWithNetworkVO> buildChildrenWithNetwork(List<Coin> children) {
        // 遍历子币种，逐个查询主网配置并组装 VO
        List<CoinChildWithNetworkVO> result = new ArrayList<>();
        for (Coin child : children) {
            CoinChildWithNetworkVO vo = buildChildVO(child);
            result.add(vo);
        }
        return result;
    }

    /**
     * 构建单个子币种的主网配置 VO
     *
     * @param child 子币种
     * @return 组合 VO
     */
    private CoinChildWithNetworkVO buildChildVO(Coin child) {
        CoinChildWithNetworkVO vo = new CoinChildWithNetworkVO();
        vo.setCoin(child);
        List<CoinNetworkConfig> configs = coinNetworkConfigDao.findAllByCoinNameOrderBySortAsc(child.getName());
        vo.setNetworkConfigs(configs);
        return vo;
    }
}
