import {
  AfterViewInit,
  Component,
  ElementRef,
  OnDestroy,
  ViewChild,
  inject,
  input,
  output,
  signal
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { NgIcon, provideIcons } from '@ng-icons/core';
import {
  lucideDownload,
  lucideRefreshCw,
  lucideX
} from '@ng-icons/lucide';

import {
  ExperimentalVlcPlayerHandle,
  ExperimentalVlcRuntimeService
} from '../../infrastructure/services/experimental-vlc-runtime.service';

@Component({
  selector: 'app-experimental-vlc-player',
  standalone: true,
  imports: [CommonModule, NgIcon],
  viewProviders: [
    provideIcons({
      lucideDownload,
      lucideRefreshCw,
      lucideX
    })
  ],
  templateUrl: './experimental-vlc-player.component.html'
})
export class ExperimentalVlcPlayerComponent implements AfterViewInit, OnDestroy {
  @ViewChild('playerMount') playerMount?: ElementRef<HTMLDivElement>;

  src = input.required<string>();
  filename = input.required<string>();
  mime = input.required<string>();
  sizeLabel = input<string>('');

  closed = output<void>();
  downloadRequested = output<void>();

  private readonly runtime = inject(ExperimentalVlcRuntimeService);
  private playerHandle: ExperimentalVlcPlayerHandle | null = null;

  readonly status = signal<'loading' | 'ready' | 'error'>('loading');
  readonly errorMessage = signal('');

  ngAfterViewInit(): void {
    void this.loadPlayer();
  }

  ngOnDestroy(): void {
    this.destroyPlayer();
  }

  retry(): void {
    this.destroyPlayer();
    void this.loadPlayer();
  }

  close(): void {
    this.closed.emit();
  }

  requestDownload(): void {
    this.downloadRequested.emit();
  }

  private async loadPlayer(): Promise<void> {
    const container = this.playerMount?.nativeElement;

    if (!container) {
      return;
    }

    this.status.set('loading');
    this.errorMessage.set('');
    container.replaceChildren();

    try {
      this.playerHandle = await this.runtime.createPlayer({
        container,
        sourceUrl: this.src(),
        filename: this.filename(),
        mime: this.mime()
      });
      this.status.set('ready');
    } catch (error) {
      this.status.set('error');
      this.errorMessage.set(error instanceof Error ? error.message : 'Experimental VLC.js playback failed to start.');
    }
  }

  private destroyPlayer(): void {
    try {
      this.playerHandle?.destroy?.();
    } catch {}

    this.playerHandle = null;
    this.playerMount?.nativeElement.replaceChildren();
  }
}
