/**
 * 基础平台适配器抽象类
 *
 * 按照constitution要求，定义所有平台适配器的基础接口和共同行为
 * 提供统一的认证、代理、错误处理等基础功能
 */

import { EventEmitter } from 'events'

import type { TimeoutConfig, RetryConfig } from '@/types/httpClient'
import type {
  IPlatformAdapter,
  PlatformRequest,
  PlatformResponse,
  PreparedRequest,
  ProxyStatus,
  PlatformHealthStatus,
  PlatformConfig,
  AuthConfig,
  ProxyConfig,
  RawResponse,
} from '@/types/platformAdapter'
import { HttpClient } from '@/utils/httpClient'

/**
 * 基础平台适配器抽象类
 *
 * 所有具体平台适配器都应该继承此类并实现抽象方法
 */
export abstract class BaseAdapter extends EventEmitter implements IPlatformAdapter {
  protected readonly config: PlatformConfig
  protected readonly httpClient: HttpClient
  protected proxyStatus: ProxyStatus

  constructor(config: PlatformConfig) {
    super()
    this.config = config
    this.httpClient = HttpClient.getInstance()

    // 初始化代理状态
    this.proxyStatus = {
      enabled: config.proxyConfig?.enabled || false,
      status: 'disconnected',
      stats: {
        totalRequests: 0,
        successfulRequests: 0,
        failedRequests: 0,
        averageResponseTime: 0,
      },
      health: {
        isHealthy: true,
        consecutiveFailures: 0,
      },
    }
  }

  // 抽象属性 - 必须由子类实现
  abstract readonly platform: string
  abstract readonly baseUrl: string

  // 抽象方法 - 必须由子类实现
  abstract request<T = any>(request: PlatformRequest): Promise<PlatformResponse<T>>
  abstract prepareRequest(request: PlatformRequest): Promise<PreparedRequest>
  abstract processResponse<T>(response: RawResponse): Promise<PlatformResponse<T>>

  /**
   * 获取平台特定配置
   */
  getConfig(): PlatformConfig {
    return { ...this.config }
  }

  /**
   * 验证平台配置
   */
  validateConfig(): boolean {
    try {
      // 基础配置验证
      if (!this.config.name || !this.config.baseUrl) {
        throw new Error('Missing required configuration: name or baseUrl')
      }

      if (!this.config.authConfig || !this.config.authConfig.type) {
        throw new Error('Missing authentication configuration')
      }

      // 认证配置验证
      this.validateAuthConfig(this.config.authConfig)

      // 代理配置验证（如果启用）
      if (this.config.proxyConfig?.enabled) {
        this.validateProxyConfig(this.config.proxyConfig)
      }

      return true
    } catch (error) {
      this.emit('validation:error', { error })
      return false
    }
  }

  /**
   * 设置代理配置
   */
  async setProxyConfig(proxyConfig: ProxyConfig | null): Promise<void> {
    if (proxyConfig) {
      this.config.proxyConfig = proxyConfig
      this.proxyStatus.enabled = proxyConfig.enabled

      if (proxyConfig.enabled) {
        this.proxyStatus.status = 'connecting'

        // 验证代理连接
        try {
          await this.validateProxyConnection(proxyConfig)
          this.proxyStatus.status = 'connected'
          this.proxyStatus.currentProxy = this.buildProxyUrl(proxyConfig)

          this.emit('proxy:connected', { proxyConfig })
        } catch (error) {
          this.proxyStatus.status = 'error'
          this.proxyStatus.lastError = {
            code: 'PROXY_CONNECTION_FAILED',
            message: error instanceof Error ? error.message : String(error),
            timestamp: new Date(),
          }

          this.emit('proxy:error', { error })
          throw error
        }
      } else {
        this.proxyStatus.status = 'disconnected'
        this.proxyStatus.currentProxy = undefined
      }
    } else {
      // 禁用代理
      this.config.proxyConfig = undefined
      this.proxyStatus.enabled = false
      this.proxyStatus.status = 'disconnected'
      this.proxyStatus.currentProxy = undefined
    }
  }

  /**
   * 获取当前代理状态
   */
  async getProxyStatus(): Promise<ProxyStatus> {
    return { ...this.proxyStatus }
  }

  /**
   * 检查平台健康状态
   */
  async checkHealth(): Promise<PlatformHealthStatus> {
    const startTime = Date.now()

    try {
      // 默认健康检查：尝试访问配置的健康检查端点
      const healthEndpoint = this.config.healthCheck?.endpoint || '/ping'
      const timeout = this.config.healthCheck?.timeout || 5000

      const healthRequest: PlatformRequest = {
        accountId: 'health-check',
        method: 'GET',
        path: healthEndpoint,
        options: {
          requiresAuth: false,
          timeout,
        },
      }

      await this.request(healthRequest)

      const responseTime = Date.now() - startTime

      return {
        status: 'up',
        responseTime,
        successRate: this.calculateSuccessRate(),
        lastCheck: new Date(),
        details: {
          httpConnection: true,
          authentication: true,
          rateLimits: {
            limit: 1000,
            remaining: 999,
            resetTime: new Date(Date.now() + 60000),
            resetInterval: 60,
          },
        },
      }
    } catch (error) {
      const responseTime = Date.now() - startTime

      return {
        status: 'down',
        responseTime,
        successRate: this.calculateSuccessRate(),
        lastCheck: new Date(),
        details: {
          httpConnection: false,
          authentication: false,
          rateLimits: {
            limit: 0,
            remaining: 0,
            resetTime: new Date(),
            resetInterval: 0,
          },
        },
      }
    }
  }

  // 受保护的辅助方法

  /**
   * 验证认证配置
   */
  protected validateAuthConfig(authConfig: AuthConfig): void {
    const supportedTypes = ['signature', 'apikey', 'bearer']
    if (!supportedTypes.includes(authConfig.type)) {
      throw new Error(`Unsupported authentication type: ${authConfig.type}`)
    }

    if (authConfig.requiresTimestamp && !authConfig.headerNames.timestamp) {
      throw new Error('Timestamp header name required for timestamp-based authentication')
    }

    if (authConfig.type === 'signature' && !authConfig.headerNames.signature) {
      throw new Error('Signature header name required for signature-based authentication')
    }

    if (authConfig.type === 'apikey' && !authConfig.headerNames.apiKey) {
      throw new Error('API key header name required for API key authentication')
    }
  }

  /**
   * 验证代理配置
   */
  protected validateProxyConfig(proxyConfig: ProxyConfig): void {
    if (!proxyConfig.url && (!proxyConfig.type || !proxyConfig.connection)) {
      throw new Error('Invalid proxy configuration: missing URL or connection details')
    }

    const supportedTypes = ['http', 'https', 'socks4', 'socks5']
    if (proxyConfig.type && !supportedTypes.includes(proxyConfig.type)) {
      throw new Error(`Unsupported proxy type: ${proxyConfig.type}`)
    }
  }

  /**
   * 验证代理连接
   */
  protected async validateProxyConnection(proxyConfig: ProxyConfig): Promise<void> {
    // 简单的代理连接测试
    const testUrl = 'https://httpbin.org/ip'
    const timeout = proxyConfig.connection?.timeout || 5000

    try {
      const response = await this.httpClient.request(testUrl, {
        timeout,
        useProxy: true,
      })

      if (!response.ok) {
        throw new Error(`Proxy connection test failed: ${response.status}`)
      }
    } catch (error) {
      throw new Error(`Proxy validation failed: ${error instanceof Error ? error.message : String(error)}`)
    }
  }

  /**
   * 构建代理URL
   */
  protected buildProxyUrl(proxyConfig: ProxyConfig): string {
    if (proxyConfig.url) {
      return proxyConfig.url
    }

    const protocol = proxyConfig.type || 'http'
    const auth = proxyConfig.auth ? `${proxyConfig.auth.username}:${proxyConfig.auth.password}@` : ''

    return `${protocol}://${auth}${proxyConfig.connection?.toString() || ''}`
  }

  /**
   * 计算成功率
   */
  protected calculateSuccessRate(): number {
    const { totalRequests, successfulRequests } = this.proxyStatus.stats
    return totalRequests > 0 ? (successfulRequests / totalRequests) * 100 : 0
  }

  /**
   * 更新请求统计
   */
  protected updateRequestStats(success: boolean, responseTime: number): void {
    this.proxyStatus.stats.totalRequests++

    if (success) {
      this.proxyStatus.stats.successfulRequests++
      this.proxyStatus.health.consecutiveFailures = 0
    } else {
      this.proxyStatus.stats.failedRequests++
      this.proxyStatus.health.consecutiveFailures++
    }

    // 更新平均响应时间
    const total = this.proxyStatus.stats.totalRequests
    const current = this.proxyStatus.stats.averageResponseTime
    this.proxyStatus.stats.averageResponseTime = (current * (total - 1) + responseTime) / total

    // 更新健康状态
    this.proxyStatus.health.isHealthy = this.proxyStatus.health.consecutiveFailures < 3
    this.proxyStatus.health.lastHealthCheck = new Date()
  }

  /**
   * 应用超时配置
   */
  protected applyTimeoutConfig(baseTimeout: TimeoutConfig): TimeoutConfig {
    const configTimeout = this.config.defaultTimeout

    return {
      connect: baseTimeout.connect || configTimeout.connect || 5000,
      read: baseTimeout.read || configTimeout.read || 30000,
      write: baseTimeout.write || configTimeout.write || 15000,
    }
  }

  /**
   * 应用重试配置
   */
  protected applyRetryConfig(baseRetry: RetryConfig): RetryConfig {
    const configRetry = this.config.retryConfig

    return {
      maxAttempts: baseRetry.maxAttempts || configRetry.maxAttempts || 3,
      delay: baseRetry.delay || configRetry.delay || 1000,
      exponentialBackoff: baseRetry.exponentialBackoff ?? configRetry.exponentialBackoff ?? true,
    }
  }

  /**
   * 清理资源
   */
  async dispose(): Promise<void> {
    // 清理代理连接、关闭WebSocket等
    this.removeAllListeners()

    if (this.proxyStatus.enabled) {
      this.proxyStatus.status = 'disconnected'
    }
  }
}
