/**
 * 账户注册表 - 优雅的账户注入方案
 * 统一管理所有账户的发现、验证、注册和生命周期
 */

import { EventEmitter } from 'events'
import { ExchangeAdapter } from '../exchanges/ExchangeAdapter.js'
import { AdapterFactory } from '../exchanges/AdapterFactory.js'

// 账户发现策略
export type AccountDiscoveryStrategy =
  | 'auto' // 自动发现 (环境变量 + 配置文件)
  | 'env' // 仅环境变量
  | 'config' // 仅配置文件
  | 'registry' // 注册表模式
  | 'vault' // 密钥库模式 (未来扩展)

// 账户提供者接口
export interface AccountProvider {
  name: string
  priority: number
  discover(): Promise<AccountDescriptor[]>
  validate(descriptor: AccountDescriptor): Promise<boolean>
}

// 账户描述符 - 统一的账户抽象
export interface AccountDescriptor {
  // 标识信息
  id: string // 唯一标识符
  name: string // 显示名称
  exchange: string // 交易所类型

  // 认证信息 (动态获取)
  credentials: () => Promise<Record<string, any>>

  // 业务配置
  config: {
    enabled: boolean
    priority: number
    trading: boolean
    hedging: boolean
    limits: {
      maxPosition: number
      maxDailyVolume: number
    }
  }

  // 元数据
  metadata: {
    source: string // 来源 (env/config/registry)
    tags: string[] // 标签
    createdAt: Date
    updatedAt: Date
  }
}

// 账户实例
export interface AccountInstance {
  descriptor: AccountDescriptor
  adapter: ExchangeAdapter
  status: 'initializing' | 'active' | 'inactive' | 'error'
  lastHealthCheck?: Date
  errorCount: number
  lastError?: string
}

export interface AccountRegistryConfig {
  discovery: {
    strategy: AccountDiscoveryStrategy
    providers: string[] // 启用的提供者
    autoRefresh: boolean // 自动刷新
    refreshInterval: number // 刷新间隔(ms)
  }
  validation: {
    strictMode: boolean // 严格模式
    requiredFields: string[] // 必需字段
    timeout: number // 验证超时
  }
  lifecycle: {
    retryAttempts: number // 重试次数
    retryDelay: number // 重试延迟
    healthCheckInterval: number
  }
}

export class AccountRegistry extends EventEmitter {
  private providers = new Map<string, AccountProvider>()
  private descriptors = new Map<string, AccountDescriptor>()
  private instances = new Map<string, AccountInstance>()
  private config: AccountRegistryConfig

  constructor(config: Partial<AccountRegistryConfig> = {}) {
    super()

    this.config = {
      discovery: {
        strategy: 'auto',
        providers: ['env', 'config'],
        autoRefresh: false,
        refreshInterval: 300000, // 5分钟
      },
      validation: {
        strictMode: false,
        requiredFields: ['exchange', 'credentials'],
        timeout: 10000,
      },
      lifecycle: {
        retryAttempts: 3,
        retryDelay: 2000,
        healthCheckInterval: 60000,
      },
      ...config,
    }

    this.setupBuiltinProviders()
  }

  /**
   * 发现所有可用账户
   */
  async discover(): Promise<AccountDescriptor[]> {
    const allDescriptors: AccountDescriptor[] = []
    const enabledProviders = Array.from(this.providers.values())
      .filter(p => this.config.discovery.providers.includes(p.name))
      .sort((a, b) => a.priority - b.priority)

    for (const provider of enabledProviders) {
      try {
        const descriptors = await provider.discover()
        allDescriptors.push(...descriptors)

        this.emit('accounts_discovered', {
          provider: provider.name,
          count: descriptors.length,
          descriptors,
        })
      } catch (error) {
        this.emit('discovery_error', {
          provider: provider.name,
          error,
        })
      }
    }

    // 去重和排序
    const uniqueDescriptors = this.deduplicateDescriptors(allDescriptors)

    // 存储到注册表
    uniqueDescriptors.forEach(desc => {
      this.descriptors.set(desc.id, desc)
    })

    this.emit('discovery_completed', {
      total: uniqueDescriptors.length,
      byExchange: this.groupByExchange(uniqueDescriptors),
    })

    return uniqueDescriptors
  }

  /**
   * 验证账户描述符
   */
  async validate(descriptor: AccountDescriptor): Promise<boolean> {
    try {
      // 基础字段验证
      for (const field of this.config.validation.requiredFields) {
        if (!this.getNestedValue(descriptor, field)) {
          throw new Error(`缺少必需字段: ${field}`)
        }
      }

      // 获取认证信息
      const credentials = (await Promise.race([
        descriptor.credentials(),
        new Promise((_, reject) =>
          setTimeout(() => reject(new Error('认证信息获取超时')), this.config.validation.timeout),
        ),
      ])) as Record<string, any>

      // 交易所特定验证
      const isValid = await this.validateExchangeCredentials(descriptor.exchange, credentials)

      if (isValid) {
        this.emit('account_validated', { descriptor })
      } else {
        this.emit('account_validation_failed', { descriptor, reason: 'credentials_invalid' })
      }

      return isValid
    } catch (error) {
      this.emit('account_validation_failed', { descriptor, error })
      return false
    }
  }

  /**
   * 注册账户实例
   */
  async register(descriptor: AccountDescriptor): Promise<AccountInstance> {
    const instanceId = descriptor.id

    try {
      // 验证账户
      const isValid = await this.validate(descriptor)
      if (!isValid && this.config.validation.strictMode) {
        throw new Error(`账户验证失败: ${descriptor.name}`)
      }

      // 创建适配器
      const credentials = await descriptor.credentials()
      const adapter = await this.createAdapter(descriptor.exchange, credentials)

      // 创建账户实例
      const instance: AccountInstance = {
        descriptor,
        adapter,
        status: 'initializing',
        errorCount: 0,
      }

      // 测试连接
      await this.testConnection(instance)
      instance.status = 'active'
      instance.lastHealthCheck = new Date()

      // 注册实例
      this.instances.set(instanceId, instance)

      this.emit('account_registered', { instance })
      return instance
    } catch (error: any) {
      const instance: AccountInstance = {
        descriptor,
        adapter: null as any,
        status: 'error',
        errorCount: 1,
        lastError: error.message,
      }

      this.instances.set(instanceId, instance)
      this.emit('account_registration_failed', { descriptor, error })

      if (this.config.validation.strictMode) {
        throw error
      }

      return instance
    }
  }

  /**
   * 批量注册所有发现的账户
   */
  async registerAll(): Promise<{
    successful: AccountInstance[]
    failed: Array<{ descriptor: AccountDescriptor; error: any }>
  }> {
    const descriptors = await this.discover()
    const enabled = descriptors.filter(d => d.config.enabled)

    const results = await Promise.allSettled(enabled.map(desc => this.register(desc)))

    const successful: AccountInstance[] = []
    const failed: Array<{ descriptor: AccountDescriptor; error: any }> = []

    results.forEach((result, index) => {
      if (result.status === 'fulfilled') {
        successful.push(result.value)
      } else {
        failed.push({
          descriptor: enabled[index],
          error: result.reason,
        })
      }
    })

    this.emit('batch_registration_completed', {
      total: enabled.length,
      successful: successful.length,
      failed: failed.length,
    })

    return { successful, failed }
  }

  /**
   * 获取活跃的账户实例
   */
  getActiveInstances(): AccountInstance[] {
    return Array.from(this.instances.values()).filter(instance => instance.status === 'active')
  }

  /**
   * 根据交易所获取账户
   */
  getInstancesByExchange(exchange: string): AccountInstance[] {
    return this.getActiveInstances().filter(instance => instance.descriptor.exchange === exchange)
  }

  /**
   * 获取账户实例
   */
  getInstance(id: string): AccountInstance | undefined {
    return this.instances.get(id)
  }

  /**
   * 移除账户
   */
  async unregister(id: string): Promise<void> {
    const instance = this.instances.get(id)
    if (!instance) return

    try {
      // 清理连接
      if (instance.adapter && typeof instance.adapter.disconnect === 'function') {
        await instance.adapter.disconnect()
      }

      this.instances.delete(id)
      this.descriptors.delete(id)

      this.emit('account_unregistered', { id, descriptor: instance.descriptor })
    } catch (error) {
      this.emit('account_unregister_failed', { id, error })
    }
  }

  /**
   * 注册自定义提供者
   */
  registerProvider(provider: AccountProvider): void {
    this.providers.set(provider.name, provider)
    this.emit('provider_registered', { provider: provider.name })
  }

  /**
   * 健康检查
   */
  async performHealthCheck(): Promise<{
    total: number
    healthy: number
    unhealthy: number
    details: Array<{ id: string; status: string; lastCheck: Date }>
  }> {
    const instances = Array.from(this.instances.values())
    const results = await Promise.allSettled(instances.map(instance => this.checkInstanceHealth(instance)))

    let healthy = 0
    let unhealthy = 0
    const details: Array<{ id: string; status: string; lastCheck: Date }> = []

    results.forEach((result, index) => {
      const instance = instances[index]
      const lastCheck = new Date()

      if (result.status === 'fulfilled' && result.value) {
        instance.status = 'active'
        instance.lastHealthCheck = lastCheck
        instance.errorCount = Math.max(0, instance.errorCount - 1)
        healthy++
        details.push({ id: instance.descriptor.id, status: 'healthy', lastCheck })
      } else {
        instance.status = 'error'
        instance.errorCount++
        instance.lastError = result.status === 'rejected' ? result.reason.message : 'Unknown error'
        unhealthy++
        details.push({ id: instance.descriptor.id, status: 'unhealthy', lastCheck })
      }
    })

    const healthReport = {
      total: instances.length,
      healthy,
      unhealthy,
      details,
    }

    this.emit('health_check_completed', healthReport)
    return healthReport
  }

  // ========== 私有方法 ==========

  private setupBuiltinProviders(): void {
    // 注册内置提供者
    this.registerProvider(new EnvironmentAccountProvider())
    this.registerProvider(new ConfigFileAccountProvider())
  }

  private deduplicateDescriptors(descriptors: AccountDescriptor[]): AccountDescriptor[] {
    const seen = new Set<string>()
    return descriptors.filter(desc => {
      const key = `${desc.exchange}:${desc.name}`
      if (seen.has(key)) return false
      seen.add(key)
      return true
    })
  }

  private groupByExchange(descriptors: AccountDescriptor[]) {
    return descriptors.reduce(
      (acc, desc) => {
        acc[desc.exchange] = (acc[desc.exchange] || 0) + 1
        return acc
      },
      {} as Record<string, number>,
    )
  }

  private getNestedValue(obj: any, path: string): any {
    return path.split('.').reduce((current, key) => current?.[key], obj)
  }

  private async validateExchangeCredentials(exchange: string, credentials: Record<string, any>): Promise<boolean> {
    try {
      // 这里可以做更详细的凭证验证
      const adapter = await this.createAdapter(exchange, credentials)
      await adapter.time() // 简单连接测试
      return true
    } catch {
      return false
    }
  }

  private async createAdapter(exchange: string, credentials: Record<string, any>): Promise<ExchangeAdapter> {
    const config = { exchange, ...credentials }
    const result = await AdapterFactory.create(config as any)
    return result.adapter
  }

  private async testConnection(instance: AccountInstance): Promise<void> {
    await instance.adapter.time()
  }

  private async checkInstanceHealth(instance: AccountInstance): Promise<boolean> {
    try {
      await instance.adapter.time()
      return true
    } catch {
      return false
    }
  }
}

// ========== 内置提供者 ==========

class EnvironmentAccountProvider implements AccountProvider {
  name = 'env'
  priority = 1

  async discover(): Promise<AccountDescriptor[]> {
    const descriptors: AccountDescriptor[] = []

    // 自动发现环境变量中的账户配置
    const exchanges = ['pacifica', 'aster', 'binance']

    for (const exchange of exchanges) {
      const accounts = await this.discoverExchangeAccounts(exchange)
      descriptors.push(...accounts)
    }

    return descriptors
  }

  async validate(descriptor: AccountDescriptor): Promise<boolean> {
    const credentials = await descriptor.credentials()
    return Object.keys(credentials).length > 0
  }

  private async discoverExchangeAccounts(exchange: string): Promise<AccountDescriptor[]> {
    // 根据环境变量模式自动发现账户
    // 这里实现具体的发现逻辑
    return []
  }
}

class ConfigFileAccountProvider implements AccountProvider {
  name = 'config'
  priority = 2

  async discover(): Promise<AccountDescriptor[]> {
    // 从配置文件发现账户
    // 这里实现具体的发现逻辑
    return []
  }

  async validate(descriptor: AccountDescriptor): Promise<boolean> {
    return true
  }
}
