import { Component, OnInit, OnDestroy, signal, computed, effect, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { CantiService, Canto } from '../../services/canti.service';
import { LyricsParserService, ParsedSection } from '../../services/lyrics-parser.service';
import { ComunitaService } from '../../services/comunita.service';

@Component({
  selector: 'app-display',
  templateUrl: './display.page.html',
  styleUrls: ['./display.page.scss'],
  standalone: false
})
export class DisplayPage implements OnInit, OnDestroy {
  public canto = signal<Canto | null>(null);
  public activeSongId = signal<string | null>(null);
  public showChords = signal<boolean>(false);
  public fontSize = signal<number>(1.0);
  public currentLineIndex = signal<number>(0);
  public transposeAmount = signal<number>(0);

  public parsedSections = computed<ParsedSection[]>(() => {
    const c = this.canto();
    if (!c) return [];

    let sections: ParsedSection[];
    const hasChordsInText = !c.accordi && c.testo?.includes('[');
    
    if ((this.showChords() && c.accordi) || (this.showChords() && hasChordsInText)) {
      sections = this.lyricsParser.parseAccordi(c.accordi || c.testo);
    } else {
      sections = this.lyricsParser.parseText(c.testo);
    }

    if (sections.length === 0 && c.testo) {
      const fallbackLines = c.testo.split('\n')
        .filter(l => l.trim().length > 0)
        .map(l => ({
          text: l.trim(),
          segments: [{ text: l.trim() }]
        }));
      
      if (fallbackLines.length > 0) {
        sections = [{
          type: 'verse',
          lines: fallbackLines
        }];
      }
    }

    if (this.showChords()) {
      return this.lyricsParser.transposeSections(sections, this.transposeAmount());
    }

    return sections;
  });

  /** Get the current line text and surrounding lines from flat index */
  public displayLines = computed(() => {
    const sections = this.parsedSections();
    const idx = this.currentLineIndex();
    const allLines: { text: string; segments: any[]; sectionType: string }[] = [];

    for (const section of sections) {
      for (const line of section.lines) {
        allLines.push({ text: line.text, segments: line.segments, sectionType: section.type });
      }
    }

    return {
      prev: idx > 0 ? allLines[idx - 1] : null,
      current: allLines[idx] || null,
      next: idx < allLines.length - 1 ? allLines[idx + 1] : null
    };
  });

  private channel = new BroadcastChannel('karaoke_sync');
  
  private readonly MIN_FONT = 0.6;
  private readonly MAX_FONT = 5.0;
  private initialPinchDistance: number | null = null;
  private initialFontSize: number = 1.0;

  private route = inject(ActivatedRoute);
  private cantiService = inject(CantiService);
  public lyricsParser = inject(LyricsParserService);
  private comunitaService = inject(ComunitaService);

  constructor() {
    effect(() => {
      const id = this.activeSongId();
      const allCanti = this.cantiService.canti();
      const comunitaCantiPers = this.comunitaService.comunitaCantiPersonali();
      if (id) {
        let found: any = null;
        if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) {
          found = comunitaCantiPers.find(c => c.id === id);
        }
        if (!found) {
          found = allCanti.find(c => c.id === id);
        }
        if (!found) {
          found = comunitaCantiPers.find(c => c.id === id);
        }
        if (found) {
          this.canto.set(found);
        }
      }
    }, { allowSignalWrites: true });
  }

  ngOnInit() {
    this.route.queryParams.subscribe(params => {
      const id = params['id'];
      if (id) {
        this.activeSongId.set(id);
      }
    });

    this.channel.onmessage = (event) => {
      if (event.data.type === 'SYNC_INDEX') {
        this.currentLineIndex.set(event.data.index);
      }
      if (event.data.type === 'SYNC_CANTO') {
        this.activeSongId.set(event.data.id);
        this.transposeAmount.set(0);
      }
      if (event.data.type === 'SYNC_CHORDS') {
        this.showChords.set(event.data.showChords);
      }
      if (event.data.type === 'SYNC_FONT') {
        this.fontSize.set(event.data.fontSize);
      }
      if (event.data.type === 'SYNC_TRANSPOSE') {
        this.transposeAmount.set(event.data.amount);
      }
    };
  }

  ngOnDestroy() {
    this.channel.close();
  }

  // --- Touch Gestures for Pinch-to-Zoom ---
  onTouchStart(event: TouchEvent) {
    if (event.touches.length === 2) {
      this.initialPinchDistance = this.getDistance(event.touches[0], event.touches[1]);
      this.initialFontSize = this.fontSize();
    }
  }

  onTouchMove(event: TouchEvent) {
    if (event.touches.length === 2 && this.initialPinchDistance !== null) {
      event.preventDefault(); // Prevent browser zoom/scroll
      const currentDistance = this.getDistance(event.touches[0], event.touches[1]);
      const ratio = currentDistance / this.initialPinchDistance;
      let newSize = this.initialFontSize * ratio;
      
      // Clamp values
      newSize = Math.max(this.MIN_FONT, Math.min(this.MAX_FONT, newSize));
      
      if (Math.abs(newSize - this.fontSize()) > 0.01) {
        this.fontSize.set(newSize);
        // Sync back to player if display is touched
        this.channel.postMessage({ type: 'SYNC_FONT', fontSize: this.fontSize() });
      }
    }
  }

  onTouchEnd() {
    this.initialPinchDistance = null;
  }

  private getDistance(t1: Touch, t2: Touch): number {
    return Math.sqrt(Math.pow(t1.clientX - t2.clientX, 2) + Math.pow(t1.clientY - t2.clientY, 2));
  }
  // ----------------------------------------
}
