import {
  Component,
  HostListener,
  inject,
  input,
  output,
  signal
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
  lucideDownload,
  lucideFilter,
  lucidePause,
  lucidePlay,
  lucideSearch,
  lucideTrash2,
  lucideX
} from '@ng-icons/lucide';
import { AppI18nService, APP_TRANSLATE_IMPORTS } from '../../../../core/i18n';

type DebugLogLevel = 'event' | 'info' | 'warn' | 'error' | 'debug';
type DebugExportFormat = 'csv' | 'txt';

interface DebugNetworkSummary {
  clientCount: number;
  serverCount: number;
  signalingServerCount: number;
  peerConnectionCount: number;
  membershipCount: number;
  messageCount: number;
  typingCount: number;
  speakingCount: number;
  streamingCount: number;
}

@Component({
  selector: 'app-debug-console-toolbar',
  standalone: true,
  imports: [
    CommonModule,
    NgIcon,
    ...APP_TRANSLATE_IMPORTS
  ],
  viewProviders: [
    provideIcons({
      lucideDownload,
      lucideFilter,
      lucidePause,
      lucidePlay,
      lucideSearch,
      lucideTrash2,
      lucideX
    })
  ],
  templateUrl: './debug-console-toolbar.component.html'
})
export class DebugConsoleToolbarComponent {
  readonly activeTab = input.required<'logs' | 'network'>();
  readonly detached = input.required<boolean>();
  readonly searchTerm = input.required<string>();
  readonly selectedSource = input.required<string>();
  readonly sourceOptions = input.required<string[]>();
  readonly levelState = input.required<Record<DebugLogLevel, boolean>>();
  readonly levelCounts = input.required<Record<DebugLogLevel, number>>();
  readonly visibleCount = input.required<number>();
  readonly autoScroll = input.required<boolean>();
  readonly networkSummary = input.required<DebugNetworkSummary>();

  readonly activeTabChange = output<'logs' | 'network'>();
  readonly detachToggled = output<undefined>();
  readonly searchTermChange = output<string>();
  readonly selectedSourceChange = output<string>();
  readonly levelToggled = output<DebugLogLevel>();
  readonly autoScrollToggled = output<undefined>();
  readonly clearRequested = output<undefined>();
  readonly closeRequested = output<undefined>();
  readonly exportLogsRequested = output<DebugExportFormat>();
  readonly exportNetworkRequested = output<DebugExportFormat>();

  readonly exportMenuOpen = signal(false);

  readonly levels: DebugLogLevel[] = [
    'event',
    'info',
    'warn',
    'error',
    'debug'
  ];

  readonly tabs: ('logs' | 'network')[] = ['logs', 'network'];

  private readonly appI18n = inject(AppI18nService);

  @HostListener('document:click', ['$event'])
  onDocumentClick(event: MouseEvent): void {
    if (!this.exportMenuOpen())
      return;

    const target = event.target as HTMLElement;

    if (!target.closest('[data-export-menu]'))
      this.closeExportMenu();
  }

  setActiveTab(tab: 'logs' | 'network'): void {
    this.activeTabChange.emit(tab);
  }

  toggleDetached(): void {
    this.detachToggled.emit(undefined);
  }

  onSearchInput(event: Event): void {
    const input = event.target as HTMLInputElement;

    this.searchTermChange.emit(input.value);
  }

  onSourceChange(event: Event): void {
    const select = event.target as HTMLSelectElement;

    this.selectedSourceChange.emit(select.value);
  }

  toggleLevel(level: DebugLogLevel): void {
    this.levelToggled.emit(level);
  }

  toggleAutoScroll(): void {
    this.autoScrollToggled.emit(undefined);
  }

  clear(): void {
    this.clearRequested.emit(undefined);
  }

  close(): void {
    this.closeRequested.emit(undefined);
  }

  toggleExportMenu(): void {
    this.exportMenuOpen.update((open) => !open);
  }

  closeExportMenu(): void {
    this.exportMenuOpen.set(false);
  }

  exportLogs(format: DebugExportFormat): void {
    this.exportLogsRequested.emit(format);
    this.closeExportMenu();
  }

  exportNetwork(format: DebugExportFormat): void {
    this.exportNetworkRequested.emit(format);
    this.closeExportMenu();
  }

  getDetachLabel(): string {
    return this.detached()
      ? this.appI18n.instant('shared.debugConsole.dock')
      : this.appI18n.instant('shared.debugConsole.undock');
  }

  getTabLabel(tab: 'logs' | 'network'): string {
    return tab === 'logs'
      ? this.appI18n.instant('shared.debugConsole.logsTab')
      : this.appI18n.instant('shared.debugConsole.networkTab');
  }

  getTabButtonClass(tab: 'logs' | 'network'): string {
    const isActive = this.activeTab() === tab;
    const base = 'rounded-full border px-3 py-1.5 text-xs font-medium transition-colors';

    if (!isActive)
      return base + ' border-border bg-transparent text-muted-foreground hover:bg-secondary/60';

    return base + ' border-primary/40 bg-primary/10 text-primary';
  }

  getLevelLabel(level: DebugLogLevel): string {
    return this.appI18n.instant(`shared.debugConsole.levels.${level}`);
  }

  getLevelButtonClass(level: DebugLogLevel): string {
    const isActive = this.levelState()[level];
    const base = 'rounded-full border px-3 py-1 text-xs font-medium transition-colors';

    if (!isActive)
      return base + ' border-border bg-transparent text-muted-foreground hover:bg-secondary/60';

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

    return base + ' border-border bg-transparent text-muted-foreground';
  }
}
