import {
  Injectable,
  Signal,
  computed,
  signal
} from '@angular/core';

export type PluginLogLevel = 'debug' | 'error' | 'info' | 'warn';

export interface PluginLogEntry {
  data?: unknown;
  level: PluginLogLevel;
  message: string;
  pluginId: string;
  timestamp: number;
}

@Injectable({ providedIn: 'root' })
export class PluginLoggerService {
  readonly entries: Signal<PluginLogEntry[]>;

  private readonly entriesSignal = signal<PluginLogEntry[]>([]);

  constructor() {
    this.entries = this.entriesSignal.asReadonly();
  }

  entriesFor(pluginId: string): Signal<PluginLogEntry[]> {
    return computed(() => this.entries().filter((entry) => entry.pluginId === pluginId));
  }

  debug(pluginId: string, message: string, data?: unknown): void {
    this.add(pluginId, 'debug', message, data);
  }

  error(pluginId: string, message: string, data?: unknown): void {
    this.add(pluginId, 'error', message, data);
  }

  info(pluginId: string, message: string, data?: unknown): void {
    this.add(pluginId, 'info', message, data);
  }

  warn(pluginId: string, message: string, data?: unknown): void {
    this.add(pluginId, 'warn', message, data);
  }

  clear(pluginId?: string): void {
    this.entriesSignal.update((entries) => pluginId ? entries.filter((entry) => entry.pluginId !== pluginId) : []);
  }

  private add(pluginId: string, level: PluginLogLevel, message: string, data?: unknown): void {
    this.entriesSignal.update((entries) => [
      ...entries,
      {
        data,
        level,
        message,
        pluginId,
        timestamp: Date.now()
      }
    ].slice(-500));
  }
}
