import { DatePipe } from '@angular/common';
import { ChangeDetectionStrategy, Component, computed, inject, isDevMode, signal } from '@angular/core';

import { DevLogService } from '../../../core/devtools/dev-log.service';

@Component({
  selector: 'app-dev-console',
  imports: [DatePipe],
  templateUrl: './dev-console.html',
  styleUrl: './dev-console.css',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class DevConsoleComponent {
  private readonly logs = inject(DevLogService);
  protected readonly isDev = isDevMode();
  protected readonly collapsed = signal(false);
  protected readonly minimized = signal(true);
  protected readonly entries = this.logs.entries;
  protected readonly count = computed(() => this.entries().length);
  protected readonly expandedIds = signal<Record<number, boolean>>({});

  constructor() {
    if (!this.isDev || typeof window === 'undefined') {
      return;
    }

    window.addEventListener('error', (e) => {
      this.logs.add({
        level: 'error',
        source: 'system',
        message: `${e.message} (${e.filename}:${e.lineno})`,
      });
    });

    window.addEventListener('unhandledrejection', (e: PromiseRejectionEvent) => {
      const reason =
        typeof e.reason === 'string'
          ? e.reason
          : e.reason instanceof Error
            ? e.reason.message
            : 'Unhandled promise rejection';
      this.logs.add({
        level: 'warn',
        source: 'system',
        message: reason,
      });
    });
  }

  protected toggleCollapsed(): void {
    this.collapsed.update((v) => !v);
  }

  protected minimize(): void {
    this.minimized.set(true);
    this.collapsed.set(false);
  }

  protected restore(): void {
    this.minimized.set(false);
  }

  protected clear(): void {
    this.logs.clear();
    this.expandedIds.set({});
  }

  protected toggleExpanded(id: number): void {
    this.expandedIds.update((curr) => ({ ...curr, [id]: !curr[id] }));
  }

  protected isExpanded(id: number): boolean {
    return !!this.expandedIds()[id];
  }

  protected pretty(value: unknown): string {
    if (value === undefined) {
      return '';
    }
    if (typeof value === 'string') {
      return value;
    }
    try {
      return JSON.stringify(value, null, 2);
    } catch {
      return String(value);
    }
  }
}
