// Weft Sandbox - Action Logger

import { ActionLog, ActionSummary } from './types';

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

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

  createAction(params: Omit<ActionLog, 'id' | 'timestamp'>): ActionLog {
    return {
      id: `action-${++this.actionIdCounter}`,
      timestamp: new Date(),
      ...params
    };
  }

  log(action: ActionLog): void {
    this.logs.push(action);
    
    if (this.logs.length > this.maxLogs) {
      this.logs = this.logs.slice(-this.maxLogs);
    }

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

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

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

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

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

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

  subscribe(listener: (action: ActionLog) => void): () => void {
    this.listeners.add(listener);
    return () => this.listeners.delete(listener);
  }

  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');
  }

  getSummary(): ActionSummary {
    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
    };
  }
}
