// Weft Sandbox - Action Logger

import { ActionLog } from './types';

export class ActionLogger {
  private logs: ActionLog[] = [];
  private maxLogs: number = 1000;
  private listeners: Set<(action: ActionLog) => void> = new Set();

  constructor(maxLogs: number = 1000) {
    this.maxLogs = maxLogs;
  }

  // Add an action to the log
  log(action: ActionLog): void {
    this.logs.push(action);
    
    // Trim if over limit
    if (this.logs.length > this.maxLogs) {
      this.logs = this.logs.slice(-this.maxLogs);
    }

    // Notify listeners
    for (const listener of this.listeners) {
      listener(action);
    }
  }

  // Get all logs
  getLogs(): ActionLog[] {
    return [...this.logs];
  }

  // Get logs filtered by type
  getLogsByType(type: ActionLog['actionType']): ActionLog[] {
    return this.logs.filter(log => log.actionType === type);
  }

  // Get logs in time range
  getLogsInRange(start: Date, end: Date): ActionLog[] {
    return this.logs.filter(log => 
      log.timestamp >= start && log.timestamp <= end
    );
  }

  // Get API calls only
  getApiCalls(): ActionLog[] {
    return this.logs.filter(log => log.actionType === 'API_CALL');
  }

  // Get recent N logs
  getRecent(n: number = 10): ActionLog[] {
    return this.logs.slice(-n);
  }

  // Clear all logs
  clear(): void {
    this.logs = [];
  }

  // Subscribe to new actions
  subscribe(listener: (action: ActionLog) => void): () => void {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }

  // Export logs as formatted string
  exportAsText(): string {
    return this.logs.map(log => {
      const time = log.timestamp.toISOString().split('T')[1].split('.')[0];
      const type = log.actionType.padEnd(10);
      
      let details = '';
      if (log.actionType === 'API_CALL') {
        details = `${log.wouldTrigger.method} ${log.wouldTrigger.endpoint}`;
        if (log.duration) details += ` (${log.duration}ms)`;
      } else if (log.actionType === 'CLICK') {
        details = log.element.text || log.element.selector;
        if (log.wouldTrigger.navigation) details += ` → ${log.wouldTrigger.navigation}`;
      } else if (log.actionType === 'INPUT' || log.actionType === 'SELECT') {
        details = `${log.element.selector}: ${log.element.value}`;
      } else if (log.actionType === 'SUBMIT') {
        details = `→ ${log.wouldTrigger.method} ${log.wouldTrigger.endpoint}`;
      }

      return `${time} | ${type} | ${details}`;
    }).join('\n');
  }

  // Export logs as JSON
  exportAsJson(): string {
    return JSON.stringify(this.logs, null, 2);
  }

  // Generate summary statistics
  getSummary(): {
    totalActions: number;
    byType: Record<string, number>;
    apiCallCount: number;
    uniqueEndpoints: string[];
    averageApiLatency: number;
  } {
    const byType: Record<string, number> = {};
    const endpoints = new Set<string>();
    let totalLatency = 0;
    let latencyCount = 0;

    for (const log of this.logs) {
      byType[log.actionType] = (byType[log.actionType] || 0) + 1;
      
      if (log.actionType === 'API_CALL' && log.wouldTrigger.endpoint) {
        endpoints.add(log.wouldTrigger.endpoint);
        if (log.duration) {
          totalLatency += log.duration;
          latencyCount++;
        }
      }
    }

    return {
      totalActions: this.logs.length,
      byType,
      apiCallCount: byType['API_CALL'] || 0,
      uniqueEndpoints: Array.from(endpoints),
      averageApiLatency: latencyCount > 0 ? Math.round(totalLatency / latencyCount) : 0
    };
  }
}
