import {
  Component,
  ElementRef,
  effect,
  input,
  output,
  signal,
  viewChild
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import { lucideChevronDown, lucideChevronRight } from '@ng-icons/lucide';

import { type DebugLogEntry, type DebugLogLevel } from '../../../../core/services/debugging.service';

@Component({
  selector: 'app-debug-console-entry-list',
  standalone: true,
  imports: [CommonModule, NgIcon],
  viewProviders: [
    provideIcons({
      lucideChevronDown,
      lucideChevronRight
    })
  ],
  templateUrl: './debug-console-entry-list.component.html',
  host: {
    style: 'display: flex; min-height: 0; overflow: hidden;'
  }
})
export class DebugConsoleEntryListComponent {
  readonly entries = input.required<DebugLogEntry[]>();
  readonly autoScroll = input.required<boolean>();
  readonly entryExpanded = output();
  readonly expandedEntryIds = signal<number[]>([]);

  private readonly viewportRef = viewChild<ElementRef<HTMLDivElement>>('viewport');

  constructor() {
    effect(() => {
      this.entries();

      if (!this.autoScroll())
        return;

      requestAnimationFrame(() => this.scrollToBottom());
    });
  }

  toggleExpanded(entryId: number): void {
    const nextExpandedIds = new Set(this.expandedEntryIds());

    if (nextExpandedIds.has(entryId)) {
      nextExpandedIds.delete(entryId);
    } else {
      nextExpandedIds.add(entryId);
      this.entryExpanded.emit();
    }

    this.expandedEntryIds.set(Array.from(nextExpandedIds));
  }

  isExpanded(entryId: number): boolean {
    return this.expandedEntryIds().includes(entryId);
  }

  getRowClass(level: DebugLogLevel): string {
    switch (level) {
      case 'event':
        return 'bg-transparent hover:bg-secondary/20';
      case 'info':
        return 'bg-sky-500/[0.04] hover:bg-sky-500/[0.08]';
      case 'warn':
        return 'bg-yellow-500/[0.05] hover:bg-yellow-500/[0.08]';
      case 'error':
        return 'bg-destructive/[0.05] hover:bg-destructive/[0.08]';
      case 'debug':
        return 'bg-fuchsia-500/[0.05] hover:bg-fuchsia-500/[0.08]';
    }
  }

  getBadgeClass(level: DebugLogLevel): string {
    const base = 'rounded-full px-2 py-0.5 text-[10px] font-semibold uppercase tracking-wide';

    switch (level) {
      case 'event':
        return base + ' bg-primary/10 text-primary';
      case 'info':
        return base + ' bg-sky-500/10 text-sky-300';
      case 'warn':
        return base + ' bg-yellow-500/10 text-yellow-300';
      case 'error':
        return base + ' bg-destructive/10 text-destructive';
      case 'debug':
        return base + ' bg-fuchsia-500/10 text-fuchsia-300';
    }
  }

  getLevelLabel(level: DebugLogLevel): string {
    return level.toUpperCase();
  }

  private scrollToBottom(): void {
    const viewport = this.viewportRef()?.nativeElement;

    if (!viewport)
      return;

    viewport.scrollTop = viewport.scrollHeight;
  }
}
