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

export type DevLogLevel = 'info' | 'warn' | 'error';
export type DevLogStatus = 'pending' | 'ok' | 'error';

export interface DevHttpLogDetails {
  method: string;
  url: string;
  requestHeaders?: Record<string, string | null>;
  requestBody?: unknown;
  statusCode?: number;
  durationMs?: number;
  responseHeaders?: Record<string, string | null>;
  responseBody?: unknown;
  error?: string;
}

export interface DevTelemetryLogDetails {
  rawEventJson: string;
}

export interface DevLogEntry {
  id: number;
  time: string;
  level: DevLogLevel;
  source: 'http' | 'system' | 'telemetry';
  message: string;
  status?: DevLogStatus;
  details?: DevHttpLogDetails;
  telemetryDetails?: DevTelemetryLogDetails;
}

@Injectable({ providedIn: 'root' })
export class DevLogService {
  private seq = 0;
  private readonly max = 300;
  readonly entries = signal<DevLogEntry[]>([]);

  add(entry: Omit<DevLogEntry, 'id' | 'time'>): void {
    const withMeta: DevLogEntry = {
      id: ++this.seq,
      time: new Date().toISOString(),
      ...entry,
    };
    this.entries.update((curr) => [...curr.slice(-(this.max - 1)), withMeta]);
  }

  update(id: number, patch: Partial<Omit<DevLogEntry, 'id' | 'time'>>): void {
    this.entries.update((curr) =>
      curr.map((item) => (item.id === id ? { ...item, ...patch } : item)),
    );
  }

  clear(): void {
    this.entries.set([]);
  }

  clearSource(source: DevLogEntry['source']): void {
    this.entries.update((curr) => curr.filter((e) => e.source !== source));
  }
}
