import { Injectable, Logger } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ChainType } from '@/domain/value-objects';
import { ChainTypeEnum } from '@/domain/enums';

export interface ChainConfig {
  chainType: ChainTypeEnum;
  chainId: number;
  rpcUrl: string;
  /** RPC URL 列表（含主端点和备选端点），用于故障转移 */
  rpcUrls: string[];
  usdtContract: string;
  nativeSymbol: string;
  blockTime: number; // 平均出块时间（秒）
  isTestnet: boolean;
}

/**
 * 链配置服务
 *
 * 支持主网/测试网切换，通过 NETWORK_MODE 环境变量控制
 */
@Injectable()
export class ChainConfigService {
  private readonly logger = new Logger(ChainConfigService.name);
  private readonly configs: Map<ChainTypeEnum, ChainConfig>;
  private readonly isTestnet: boolean;
  private readonly networkMode: string;

  constructor(private readonly configService: ConfigService) {
    this.configs = new Map();
    this.networkMode = this.configService.get<string>('blockchain.networkMode', 'mainnet');
    this.isTestnet = this.networkMode === 'testnet';
    this.initializeConfigs();
    this.logger.log(`[INIT] Network mode: ${this.networkMode} (testnet=${this.isTestnet})`);
  }

  private initializeConfigs(): void {
    // KAVA 配置
    this.configs.set(ChainTypeEnum.KAVA, {
      chainType: ChainTypeEnum.KAVA,
      chainId: this.configService.get<number>('blockchain.kava.chainId', this.isTestnet ? 2221 : 2222),
      rpcUrl: this.configService.get<string>(
        'blockchain.kava.rpcUrl',
        this.isTestnet ? 'https://evm.testnet.kava.io' : 'https://evm.kava.io',
      ),
      rpcUrls: this.parseRpcUrls(
        'blockchain.kava.rpcUrls',
        this.configService.get<string>(
          'blockchain.kava.rpcUrl',
          this.isTestnet ? 'https://evm.testnet.kava.io' : 'https://evm.kava.io',
        ),
      ),
      // dUSDT (绿积分) 合约地址 - Durian USDT, 精度6位
      usdtContract: this.configService.get<string>(
        'blockchain.kava.usdtContract',
        this.isTestnet ? '0x0000000000000000000000000000000000000000' : '0xA9F3A35dBa8699c8C681D8db03F0c1A8CEB9D7c3',
      ),
      nativeSymbol: 'KAVA',
      blockTime: 6,
      isTestnet: this.isTestnet,
    });
    this.logger.log(`[INIT] KAVA: chainId=${this.configs.get(ChainTypeEnum.KAVA)?.chainId}, rpc=${this.configs.get(ChainTypeEnum.KAVA)?.rpcUrl}`);

    // BSC 配置
    this.configs.set(ChainTypeEnum.BSC, {
      chainType: ChainTypeEnum.BSC,
      chainId: this.configService.get<number>('blockchain.bsc.chainId', this.isTestnet ? 97 : 56),
      rpcUrl: this.configService.get<string>(
        'blockchain.bsc.rpcUrl',
        this.isTestnet ? 'https://data-seed-prebsc-1-s1.binance.org:8545' : 'https://bsc-dataseed.binance.org',
      ),
      rpcUrls: this.parseRpcUrls(
        'blockchain.bsc.rpcUrls',
        this.configService.get<string>(
          'blockchain.bsc.rpcUrl',
          this.isTestnet ? 'https://data-seed-prebsc-1-s1.binance.org:8545' : 'https://bsc-dataseed.binance.org',
        ),
      ),
      usdtContract: this.configService.get<string>(
        'blockchain.bsc.usdtContract',
        this.isTestnet ? '0x337610d27c682E347C9cD60BD4b3b107C9d34dDd' : '0x55d398326f99059fF775485246999027B3197955',
      ),
      nativeSymbol: 'BNB',
      blockTime: 3,
      isTestnet: this.isTestnet,
    });
    this.logger.log(`[INIT] BSC: chainId=${this.configs.get(ChainTypeEnum.BSC)?.chainId}, rpc=${this.configs.get(ChainTypeEnum.BSC)?.rpcUrl}`);
  }

  /**
   * 获取当前网络模式
   */
  getNetworkMode(): string {
    return this.networkMode;
  }

  /**
   * 是否为测试网
   */
  isTestnetMode(): boolean {
    return this.isTestnet;
  }

  /**
   * 获取链配置
   */
  getConfig(chainType: ChainType): ChainConfig {
    const config = this.configs.get(chainType.value);
    if (!config) {
      throw new Error(`Unsupported chain type: ${chainType.toString()}`);
    }
    return config;
  }

  /**
   * 获取所有支持的链
   *
   * 注意：暂时只支持 KAVA 链，BSC 链暂未启用
   */
  getSupportedChains(): ChainTypeEnum[] {
    // TODO: BSC 链暂时禁用，未来需要时可以恢复
    // return Array.from(this.configs.keys());
    return [ChainTypeEnum.KAVA];
  }

  /**
   * 检查链是否支持
   */
  isSupported(chainType: ChainType): boolean {
    return this.configs.has(chainType.value);
  }

  /**
   * 解析 RPC URL 列表
   *
   * 如果配置了逗号分隔的多 URL（如 KAVA_RPC_URLS），使用它作为完整列表；
   * 否则回退到单个 rpcUrl，行为与之前完全一致。
   */
  private parseRpcUrls(configKey: string, fallbackUrl: string): string[] {
    const urlsStr = this.configService.get<string>(configKey, '');
    if (urlsStr) {
      const urls = urlsStr
        .split(',')
        .map((u) => u.trim())
        .filter((u) => u.length > 0);
      if (urls.length > 0) {
        return urls;
      }
    }
    return [fallbackUrl];
  }
}
