/**
 * 结构化日志和审计跟踪服务
 * 实现 T034 任务：结构化日志和审计跟踪
 */
import { logger } from '../utils/logger.js'
import { MonitoringEventManager, MonitoringEvent } from '../models/MonitoringEvent.js'
import { writeFileSync, appendFileSync, existsSync, mkdirSync } from 'fs'
import { join } from 'path'

export interface AuditLogEntry {
  timestamp: string
  eventId: string
  eventType: string
  service: string
  action: string
  userId?: string
  accountId?: string
  details: any
  result: 'success' | 'failure' | 'warning'
  duration?: number
  metadata?: any
}

export interface StructuredLogConfig {
  enableAuditLogging: boolean
  enablePerformanceLogging: boolean
  enableSecurityLogging: boolean
  enableTradingLogging: boolean
  logLevel: 'debug' | 'info' | 'warn' | 'error'
  logDirectory: string
  maxLogFileSize: number
  retentionDays: number
  enableCompression: boolean
}

export interface LogStats {
  totalLogs: number
  auditLogs: number
  performanceLogs: number
  securityLogs: number
  tradingLogs: number
  errorLogs: number
  lastLogTime: number
  logFileSize: number
}

export class StructuredLoggingService {
  private config: StructuredLogConfig
  private stats: LogStats
  private monitoringManager: MonitoringEventManager
  private logQueue: AuditLogEntry[] = []
  private isProcessing = false

  constructor(
    monitoringManager: MonitoringEventManager,
    config: StructuredLogConfig = {
      enableAuditLogging: true,
      enablePerformanceLogging: true,
      enableSecurityLogging: true,
      enableTradingLogging: true,
      logLevel: 'info',
      logDirectory: './logs',
      maxLogFileSize: 100 * 1024 * 1024, // 100MB
      retentionDays: 30,
      enableCompression: false
    }
  ) {
    this.config = config
    this.monitoringManager = monitoringManager
    this.stats = {
      totalLogs: 0,
      auditLogs: 0,
      performanceLogs: 0,
      securityLogs: 0,
      tradingLogs: 0,
      errorLogs: 0,
      lastLogTime: 0,
      logFileSize: 0
    }

    this.initializeLogging()
  }

  /**
   * 初始化日志系统
   */
  private initializeLogging(): void {
    logger.info('初始化结构化日志系统')

    try {
      // 创建日志目录
      if (!existsSync(this.config.logDirectory)) {
        mkdirSync(this.config.logDirectory, { recursive: true })
      }

      // 启动日志处理队列
      this.startLogProcessing()

      // 记录系统启动日志
      this.logAuditEvent({
        eventType: 'system_startup',
        service: 'StructuredLoggingService',
        action: 'initialize',
        details: { config: this.config },
        result: 'success'
      })

      logger.info('结构化日志系统初始化完成')
    } catch (error: any) {
      logger.error(`结构化日志系统初始化失败: ${error.message}`)
      throw error
    }
  }

  /**
   * 启动日志处理队列
   */
  private startLogProcessing(): void {
    setInterval(() => {
      this.processLogQueue()
    }, 1000) // 每秒处理一次日志队列
  }

  /**
   * 处理日志队列
   */
  private async processLogQueue(): Promise<void> {
    if (this.isProcessing || this.logQueue.length === 0) {
      return
    }

    this.isProcessing = true

    try {
      const logsToProcess = [...this.logQueue]
      this.logQueue = []

      for (const logEntry of logsToProcess) {
        await this.writeLogEntry(logEntry)
      }

      this.stats.totalLogs += logsToProcess.length
      this.stats.lastLogTime = Date.now()

    } catch (error: any) {
      logger.error(`处理日志队列失败: ${error.message}`)
    } finally {
      this.isProcessing = false
    }
  }

  /**
   * 写入日志条目
   */
  private async writeLogEntry(logEntry: AuditLogEntry): Promise<void> {
    try {
      // 写入审计日志文件
      if (this.config.enableAuditLogging) {
        await this.writeAuditLog(logEntry)
      }

      // 写入结构化日志文件
      await this.writeStructuredLog(logEntry)

      // 更新统计信息
      this.updateLogStats(logEntry)

      // 发送到监控系统
      await this.sendToMonitoring(logEntry)

    } catch (error: any) {
      logger.error(`写入日志条目失败: ${error.message}`)
    }
  }

  /**
   * 写入审计日志
   */
  private async writeAuditLog(logEntry: AuditLogEntry): Promise<void> {
    const auditLogPath = join(this.config.logDirectory, 'audit.log')
    const logLine = JSON.stringify(logEntry) + '\n'
    
    appendFileSync(auditLogPath, logLine, 'utf8')
  }

  /**
   * 写入结构化日志
   */
  private async writeStructuredLog(logEntry: AuditLogEntry): Promise<void> {
    const logPath = join(this.config.logDirectory, 'structured.log')
    const logLine = JSON.stringify(logEntry) + '\n'
    
    appendFileSync(logPath, logLine, 'utf8')
  }

  /**
   * 更新日志统计信息
   */
  private updateLogStats(logEntry: AuditLogEntry): void {
    switch (logEntry.eventType) {
      case 'audit':
        this.stats.auditLogs++
        break
      case 'performance':
        this.stats.performanceLogs++
        break
      case 'security':
        this.stats.securityLogs++
        break
      case 'trading':
        this.stats.tradingLogs++
        break
    }

    if (logEntry.result === 'failure') {
      this.stats.errorLogs++
    }
  }

  /**
   * 发送到监控系统
   */
  private async sendToMonitoring(logEntry: AuditLogEntry): Promise<void> {
    try {
      const monitoringEvent: MonitoringEvent = {
        eventId: logEntry.eventId,
        type: logEntry.eventType,
        payload: {
          service: logEntry.service,
          action: logEntry.action,
          details: logEntry.details,
          result: logEntry.result,
          duration: logEntry.duration
        },
        severity: this.mapResultToSeverity(logEntry.result),
        createdAt: new Date(logEntry.timestamp)
      }

      this.monitoringManager.addEvent(monitoringEvent)
    } catch (error: any) {
      logger.error(`发送到监控系统失败: ${error.message}`)
    }
  }

  /**
   * 映射结果到严重级别
   */
  private mapResultToSeverity(result: string): 'INFO' | 'WARN' | 'ERROR' {
    switch (result) {
      case 'success':
        return 'INFO'
      case 'warning':
        return 'WARN'
      case 'failure':
        return 'ERROR'
      default:
        return 'INFO'
    }
  }

  /**
   * 记录审计事件
   */
  logAuditEvent(event: {
    eventType: string
    service: string
    action: string
    userId?: string
    accountId?: string
    details: any
    result: 'success' | 'failure' | 'warning'
    duration?: number
    metadata?: any
  }): void {
    const logEntry: AuditLogEntry = {
      timestamp: new Date().toISOString(),
      eventId: `audit-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      ...event
    }

    this.logQueue.push(logEntry)
    
    // 实时记录到控制台
    logger.info(`[AUDIT] ${event.service}: ${event.action} - ${event.result}`, {
      eventId: logEntry.eventId,
      eventType: event.eventType,
      details: event.details
    })
  }

  /**
   * 记录性能事件
   */
  logPerformanceEvent(event: {
    service: string
    action: string
    duration: number
    details: any
    result: 'success' | 'failure' | 'warning'
    metadata?: any
  }): void {
    const logEntry: AuditLogEntry = {
      timestamp: new Date().toISOString(),
      eventId: `perf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      eventType: 'performance',
      ...event
    }

    this.logQueue.push(logEntry)
    
    logger.debug(`[PERF] ${event.service}: ${event.action} - ${event.duration}ms`, {
      eventId: logEntry.eventId,
      details: event.details
    })
  }

  /**
   * 记录安全事件
   */
  logSecurityEvent(event: {
    service: string
    action: string
    details: any
    result: 'success' | 'failure' | 'warning'
    userId?: string
    accountId?: string
    metadata?: any
  }): void {
    const logEntry: AuditLogEntry = {
      timestamp: new Date().toISOString(),
      eventId: `sec-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      eventType: 'security',
      ...event
    }

    this.logQueue.push(logEntry)
    
    logger.warn(`[SEC] ${event.service}: ${event.action} - ${event.result}`, {
      eventId: logEntry.eventId,
      details: event.details
    })
  }

  /**
   * 记录交易事件
   */
  logTradingEvent(event: {
    service: string
    action: string
    accountId?: string
    symbol?: string
    details: any
    result: 'success' | 'failure' | 'warning'
    duration?: number
    metadata?: any
  }): void {
    const logEntry: AuditLogEntry = {
      timestamp: new Date().toISOString(),
      eventId: `trade-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      eventType: 'trading',
      ...event
    }

    this.logQueue.push(logEntry)
    
    logger.info(`[TRADE] ${event.service}: ${event.action} - ${event.result}`, {
      eventId: logEntry.eventId,
      symbol: event.symbol,
      accountId: event.accountId,
      details: event.details
    })
  }

  /**
   * 记录系统事件
   */
  logSystemEvent(event: {
    service: string
    action: string
    details: any
    result: 'success' | 'failure' | 'warning'
    metadata?: any
  }): void {
    const logEntry: AuditLogEntry = {
      timestamp: new Date().toISOString(),
      eventId: `sys-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
      eventType: 'system',
      ...event
    }

    this.logQueue.push(logEntry)
    
    logger.info(`[SYS] ${event.service}: ${event.action} - ${event.result}`, {
      eventId: logEntry.eventId,
      details: event.details
    })
  }

  /**
   * 获取日志统计信息
   */
  getLogStats(): LogStats {
    return { ...this.stats }
  }

  /**
   * 获取日志配置
   */
  getConfig(): StructuredLogConfig {
    return { ...this.config }
  }

  /**
   * 更新配置
   */
  updateConfig(newConfig: Partial<StructuredLogConfig>): void {
    this.config = { ...this.config, ...newConfig }
    
    this.logAuditEvent({
      eventType: 'config_update',
      service: 'StructuredLoggingService',
      action: 'updateConfig',
      details: { newConfig },
      result: 'success'
    })
    
    logger.info('结构化日志配置已更新', newConfig)
  }

  /**
   * 清理旧日志文件
   */
  async cleanupOldLogs(): Promise<void> {
    try {
      // 这里可以实现日志清理逻辑
      // 例如：删除超过保留期的日志文件，压缩日志文件等
      
      this.logAuditEvent({
        eventType: 'maintenance',
        service: 'StructuredLoggingService',
        action: 'cleanupOldLogs',
        details: { retentionDays: this.config.retentionDays },
        result: 'success'
      })
      
      logger.info('旧日志文件清理完成')
    } catch (error: any) {
      this.logAuditEvent({
        eventType: 'maintenance',
        service: 'StructuredLoggingService',
        action: 'cleanupOldLogs',
        details: { error: error.message },
        result: 'failure'
      })
      
      logger.error(`清理旧日志文件失败: ${error.message}`)
    }
  }

  /**
   * 导出日志数据
   */
  async exportLogs(startDate: Date, endDate: Date, eventType?: string): Promise<AuditLogEntry[]> {
    try {
      // 这里可以实现日志导出逻辑
      // 例如：从日志文件中读取指定时间范围的数据
      
      const mockExportedLogs: AuditLogEntry[] = []
      
      this.logAuditEvent({
        eventType: 'export',
        service: 'StructuredLoggingService',
        action: 'exportLogs',
        details: { startDate, endDate, eventType, count: mockExportedLogs.length },
        result: 'success'
      })
      
      return mockExportedLogs
    } catch (error: any) {
      this.logAuditEvent({
        eventType: 'export',
        service: 'StructuredLoggingService',
        action: 'exportLogs',
        details: { error: error.message },
        result: 'failure'
      })
      
      throw error
    }
  }
}
