import { Component, computed, signal, inject, effect, OnDestroy } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { CantiService } from '../services/canti.service';
import { Router, ActivatedRoute } from '@angular/router';
import { AudioEngineService } from '../services/audio-engine.service';
import { ThemeService } from '../services/theme.service';
import { ConnectivityService } from '../services/connectivity.service';
import { PlaylistService } from '../services/playlist.service';
import { SettingsService } from '../services/settings.service';
import { VERSION } from '../version';
import { YoutubePlayerService } from '../services/youtube-player.service';
import { ModalController, AlertController, ToastController, LoadingController } from '@ionic/angular';
import { CdkDragDrop, moveItemInArray } from '@angular/cdk/drag-drop';
import { MyCantiService } from '../services/my-canti.service';
import { QrScannerComponent } from '../components/qr-scanner/qr-scanner.component';
import { CantiLettureService } from '../services/canti-letture.service';
import { ComunitaService } from '../services/comunita.service';

@Component({
  selector: 'app-home',
  templateUrl: 'home.page.html',
  styleUrls: ['home.page.scss'],
  standalone: false,
})
export class HomePage implements OnDestroy {
  public searchQuery = signal<string>('');
  public selectedLiturgico = signal<number | null>(null);
  public selectedTematico = signal<number | null>(null);
  public showOnlyMine = signal<boolean>(false);
  public showTopTen = signal<boolean>(false);
  public showSuggeriti = signal<boolean>(false);
  public isMassCardExpanded = signal<boolean>(false);
  public activeFilterType = signal<'liturgico' | 'tematico' | 'playlist' | null>(null);
  public loadedThumbs = new Set<string>();
  public version = VERSION;
  public isAddingSongs = signal<boolean>(false);
  public reorderList = signal<any[]>([]);
  public limit = signal<number>(30);
  
  public fontSize = signal<number>(1.0);
  public youtubePlayerService = inject(YoutubePlayerService);
  public comunitaService = inject(ComunitaService);
  public isSeeking = false;

  private readonly MIN_FONT = 0.6;
  private readonly MAX_FONT = 5.0;
  private initialPinchDistance: number | null = null;
  private initialFontSize: number = 1.0;
  
  private sanitizer = inject(DomSanitizer);
  public audioEngine = inject(AudioEngineService);
  public themeService = inject(ThemeService);
  public connectivityService = inject(ConnectivityService);
  public cantiService = inject(CantiService);
  public myCantiService = inject(MyCantiService);
  public playlistService = inject(PlaylistService);
  public settingsService = inject(SettingsService);
  public cantiLettureService = inject(CantiLettureService);
  private router = inject(Router);
  private route = inject(ActivatedRoute);
  private modalCtrl = inject(ModalController);
  private alertCtrl = inject(AlertController);
  private toastCtrl = inject(ToastController);
  private loadingCtrl = inject(LoadingController);

  private firstInteraction = true;

  onInteraction() {
    if (this.firstInteraction) {
      this.firstInteraction = false;
    }
  }

  private scrollEffect = effect(() => {
    const activeId = this.youtubePlayerService.currentCantoId();
    const list = this.filteredCanti();
    
    if (activeId) {
      const index = list.findIndex(c => c.id === activeId);
      if (index !== -1 && index >= this.limit()) {
        this.limit.set(index + 15);
      }
      
      // Delay slightly to ensure DOM is updated and classes are applied
      setTimeout(() => {
        const element = document.getElementById('canto-' + activeId);
        if (element) {
          element.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }
      }, 500);
    }
  }, { allowSignalWrites: true });

  private normalize(str: string | undefined): string {
    if (!str) return '';
    return str
      .toLowerCase()
      .replace(/[’'‘’´`]/g, "'")
      .normalize('NFD')
      .replace(/[\u0300-\u036f]/g, '')
      .replace(/hallelujah/g, 'alleluia')
      .replace(/halleluja/g, 'alleluia')
      .replace(/alleluja/g, 'alleluia');
  }

  public filteredCanti = computed(() => {
    const query = this.normalize(this.searchQuery());
    const litId = this.selectedLiturgico();
    const temId = this.selectedTematico();
    const onlyMine = this.showOnlyMine();
    const topTen = this.showTopTen();
    const suggeriti = this.showSuggeriti();
    
    let list = [...this.cantiService.canti(), ...this.myCantiService.myCanti()];

    // Filter by Community if code is set and filter is active
    const comunitaCode = this.comunitaService.comunitaCode();
    const comunitaIds = this.comunitaService.comunitaCantiIds();
    if (comunitaCode && this.comunitaService.isFilterActive()) {
      // Include parish custom/unvalidated canti
      list = [...list, ...this.comunitaService.comunitaCantiPersonali()];
      
      list = list.filter(c => {
        return comunitaIds.includes(c.id_canti) || comunitaIds.includes(c.id);
      });

      // Deduplicate: if a song exists in both validated and unvalidated lists,
      // the NON-VALIDATED (parish-customized) version always takes precedence,
      // so parishes can always personalize their songs even if never validated.
      const seen = new Map<number | string, any>();
      for (const canto of list) {
        const key = canto.id_canti || canto.id;
        const existing = seen.get(key);
        if (!existing) {
          seen.set(key, canto);
        } else {
          // Precedence to non-validated (parish custom) version:
          // overwrite only if current entry is validated and new one is non-validated
          if (!existing.nonValidato && canto.nonValidato) {
            seen.set(key, canto);
          }
        }
      }
      list = Array.from(seen.values());
      
      // Sort list by community song number (num_canto) ASC!
      const cantiInfo = this.comunitaService.comunitaCantiInfo();
      list.sort((a, b) => {
        const infoA = cantiInfo.find(x => x.id_canti === a.id_canti || x.id_canti === Number(a.id));
        const infoB = cantiInfo.find(x => x.id_canti === b.id_canti || x.id_canti === Number(b.id));
        const numA = infoA ? Number(infoA.num_canto) : 999999;
        const numB = infoB ? Number(infoB.num_canto) : 999999;
        return numA - numB;
      });
    }

    if (onlyMine) {
      list = this.myCantiService.myCanti();
    }
    
    if (litId !== null) {
      list = list.filter(c => c.id_momenti?.includes(litId));
    }
    if (temId !== null) {
      list = list.filter(c => c.id_momenti?.includes(temId));
    }

    if (suggeriti) {
      const suggMap = this.cantiLettureService.suggestionsMap();
      list = list.filter(c => suggMap.has(c.id_canti));
    }

    // Special List handling (from QR Code or Saved Playlists)
    const activeIds = this.playlistService.activeListIds();
    const selectionMode = this.playlistService.selectionMode();

    // If we are in selection mode, only show restricted list if NOT adding songs
    if (selectionMode && !this.isAddingSongs()) {
      return this.reorderList();
    }

    // If we have an active playlist and NOT in selection mode, show ONLY those songs
    if (activeIds.length > 0 && !selectionMode) {
      // Filter only songs in the special list and KEEP THE ORDER
      return activeIds
        .map(id => list.find(c => c.id === id))
        .filter((c): c is any => !!c);
    }

    if (suggeriti) {
      const suggMap = this.cantiLettureService.suggestionsMap();
      list = list.sort((a, b) => {
        const pesoA = suggMap.get(a.id_canti) || 0;
        const pesoB = suggMap.get(b.id_canti) || 0;
        return pesoB - pesoA;
      });
    } else if (topTen) {
      const eseguiti = this.cantiService.cantiEseguiti();
      const eseguitiMap = new Map<number, number>();
      eseguiti.forEach(x => eseguitiMap.set(x.id_canti, x.num));

      list = list.sort((a, b) => {
        const numA = eseguitiMap.get(a.id_canti) || 0;
        const numB = eseguitiMap.get(b.id_canti) || 0;
        return numB - numA;
      });
    }

    if (!query) return list;

    // Converte "uno" in "1" per facilitare la ricerca vocale (es. "numero uno")
    const processedQuery = query.replace(/\buno\b/g, '1');

    // Se la ricerca inizia con "numero" o "nr", filtra esattamente per id_canti/comunita number
    const numberMatchPattern = processedQuery.match(/^(?:numero|nr\.?)\s*(\d+)$/);
    if (numberMatchPattern) {
      const targetId = numberMatchPattern[1];
      return list.filter(c => {
        const commNum = this.getCommunitySongNumber(c);
        return commNum ? commNum === targetId : c.id_canti.toString() === targetId;
      });
    }

    return list.filter(c => {
      const titleMatch = this.normalize(c.titolo).includes(query);
      const authorMatch = this.normalize(c.autore).includes(query);
      const commNum = this.getCommunitySongNumber(c);
      const numberMatch = commNum ? commNum.includes(query) : c.id_canti.toString().includes(query);
      
      // Strip tags like {Chorus} and newlines from lyrics before searching
      const lyricsPlain = (c.testo || '')
        .replace(/{.*?}/g, '')
        .replace(/\n/g, ' ');
      const lyricsMatch = this.normalize(lyricsPlain).includes(query);
      
      return titleMatch || authorMatch || lyricsMatch || numberMatch;
    });
  });
  
  public visibleCanti = computed(() => {
    return this.filteredCanti().slice(0, this.limit());
  });

  constructor() {
    // Sync speech recognition results to search query
    effect(() => {
      const transcript = this.audioEngine.searchTranscript();
      if (transcript) {
        this.searchQuery.set(transcript);
      }
    });

    this.route.queryParams.subscribe(params => {
      if (params['import']) {
        this.handleImport(params['import']);
      }
    });

    let prevSelectionMode = false;

    effect(() => {
      const selectionMode = this.playlistService.selectionMode();
      const selectedIds = this.playlistService.selectedIds();
      const activeIds = this.playlistService.activeListIds();

      if (selectionMode) {
        if (!prevSelectionMode) {
          if (activeIds.length === 0) {
            this.isAddingSongs.set(true);
          } else {
            this.isAddingSongs.set(false);
          }
        }
        prevSelectionMode = true;

        const currentIds = this.reorderList().map(c => c.id);
        const newIds = Array.from(selectedIds);
        
        // Use a set of IDs for faster lookup
        const currentIdSet = new Set(currentIds);
        const newIdSet = new Set(newIds);

        // Check if there are differences in the SET of IDs
        const added = newIds.filter(id => !currentIdSet.has(id));
        const removed = currentIds.filter(id => !newIdSet.has(id));

        if (added.length > 0 || removed.length > 0) {
          let updatedList = [...this.reorderList()];
          
          // Remove songs no longer selected
          if (removed.length > 0) {
            updatedList = updatedList.filter(c => newIdSet.has(c.id));
          }
          
          // Add newly selected songs at the end
          if (added.length > 0) {
            const newSongs = added.map(id => this.findCanto(id)).filter((c): c is any => !!c);
            updatedList = [...updatedList, ...newSongs];
          }
          
          this.reorderList.set(updatedList);
        }
      } else {
        prevSelectionMode = false;
        this.isAddingSongs.set(false);
      }
    }, { allowSignalWrites: true });
  }

  handleImport(base64: string) {
    try {
      const decoded = decodeURIComponent(escape(atob(base64)));
      const json = JSON.parse(decoded);
      if (this.playlistService.processImportJson(json)) {
        this.router.navigate([], { queryParams: { import: null }, queryParamsHandling: 'merge' });
      }
    } catch (e) {
      console.error('Failed to import playlist', e);
    }
  }

  ionViewWillLeave() {
  }

  ngOnDestroy() {
    this.audioEngine.stopSearchRecognition();
  }

  onSearch(event: any) {
    this.searchQuery.set(event.detail.value);
    this.limit.set(30);
  }

  async deleteMyCanto(id: string, event: Event) {
    event.stopPropagation();
    const alert = await this.alertCtrl.create({
      header: 'Elimina Canto',
      message: 'Sei sicuro di voler eliminare questo canto dai tuoi brani personali?',
      buttons: [
        { text: 'Annulla', role: 'cancel' },
        { 
          text: 'Elimina', 
          role: 'destructive',
          handler: () => {
            this.myCantiService.deleteCanto(id);
          }
        }
      ]
    });
    await alert.present();
  }

  findCanto(id: string) {
    if (this.comunitaService.comunitaCode() && this.comunitaService.isFilterActive()) {
      const personal = this.comunitaService.comunitaCantiPersonali().find(c => c.id === id);
      if (personal) return personal;
    }
    return [
      ...this.cantiService.canti(),
      ...this.myCantiService.myCanti(),
      ...this.comunitaService.comunitaCantiPersonali()
    ].find(c => c.id === id);
  }

  getPlayingCanto() {
    const id = this.youtubePlayerService.currentCantoId();
    if (!id) return null;
    return this.findCanto(id);
  }

  goToCanto(id: string) {
    const params: any = { id };
    const isPlaying = this.youtubePlayerService.isPlaying();

    if (this.youtubePlayerService.currentCantoId() === id && isPlaying) {
      params.t = Math.floor(this.youtubePlayerService.videoProgress());
    }
    
    this.playlistService.autoPlayPlaylist.set(isPlaying);
    this.router.navigate(['/player'], { queryParams: params });
  }

  toggleOnlyMine() {
    this.showOnlyMine.update(v => !v);
    if (this.showOnlyMine()) {
      this.selectedLiturgico.set(null);
      this.selectedTematico.set(null);
    }
    this.limit.set(10);
  }

  clearOnlyMine(event: Event) {
    event.stopPropagation();
    this.showOnlyMine.set(false);
    this.limit.set(10);
  }

  toggleIndex(id: number, type: 'liturgico' | 'tematico' | 'playlist') {
    if (type === 'liturgico') {
      this.selectedLiturgico.update(cur => cur === id ? null : id);
    } else if (type === 'tematico') {
      this.selectedTematico.update(cur => cur === id ? null : id);
    }
    this.showOnlyMine.set(false);
    this.activeFilterType.set(null);
    this.limit.set(10);
  }

  clearLiturgico(event: Event) {
    event.stopPropagation();
    this.selectedLiturgico.set(null);
    this.activeFilterType.set(null);
    this.limit.set(10);
  }

  clearTematico(event: Event) {
    event.stopPropagation();
    this.selectedTematico.set(null);
    this.activeFilterType.set(null);
    this.limit.set(10);
  }

  isIndexSelected(id: number): boolean {
    return this.selectedLiturgico() === id || this.selectedTematico() === id;
  }

  clearFilters() {
    const type = this.activeFilterType();
    
    if (this.playlistService.activeListIds().length > 0) {
      this.clearSpecialList();
    }

    if (type === 'liturgico') {
      if (this.selectedLiturgico() === null) {
        this.selectedTematico.set(null);
      } else {
        this.selectedLiturgico.set(null);
      }
    } else if (type === 'tematico') {
      if (this.selectedTematico() === null) {
        this.selectedLiturgico.set(null);
      } else {
        this.selectedTematico.set(null);
      }
    } else {
      this.selectedLiturgico.set(null);
      this.selectedTematico.set(null);
    }
    
    this.showOnlyMine.set(false);
    this.searchQuery.set('');
    this.audioEngine.clearSearchTranscript();
  }

  activeFiltersCount(): number {
    let count = 0;
    if (this.selectedLiturgico() !== null) count++;
    if (this.selectedTematico() !== null) count++;
    return count;
  }

  getSelectedLiturgicoLabel(): string | null {
    const id = this.selectedLiturgico();
    if (id === null) return null;
    return this.cantiService.indiceLiturgico().find(m => m.id === id)?.tag_name || null;
  }

  getSelectedTematicoLabel(): string | null {
    const id = this.selectedTematico();
    if (id === null) return null;
    return this.cantiService.indiceTematico().find(m => m.id === id)?.tag_name || null;
  }

  hasActiveFilters(): boolean {
    return this.selectedLiturgico() !== null || 
           this.selectedTematico() !== null || 
           this.showOnlyMine() || 
           this.showTopTen() ||
           this.showSuggeriti() ||
           this.playlistService.activeListName() !== null ||
           this.searchQuery() !== '';
  }

  clearAllFilters() {
    this.selectedLiturgico.set(null);
    this.selectedTematico.set(null);
    this.showOnlyMine.set(false);
    this.showTopTen.set(false);
    this.showSuggeriti.set(false);
    this.playlistService.activeListIds.set([]);
    this.playlistService.activeListName.set(null);
    this.playlistService.activePlaylistId.set(null);
    this.searchQuery.set('');
    this.activeFilterType.set(null);
    this.limit.set(10);
  }

  toggleFilterType(type: 'liturgico' | 'tematico' | 'playlist') {
    if (this.activeFilterType() === type) {
      this.activeFilterType.set(null);
    } else {
      this.activeFilterType.set(type);
    }
  }

  selectPlaylist(pl: any) {
    this.playlistService.activeListIds.set(pl.ids);
    this.playlistService.activeListName.set(pl.name);
    this.playlistService.activePlaylistId.set(pl.id);
    this.activeFilterType.set(null);
    this.limit.set(50);
    // Clear other filters
    this.selectedLiturgico.set(null);
    this.selectedTematico.set(null);
    this.showOnlyMine.set(false);
  }

  toggleTopTen() {
    this.showTopTen.update(v => !v);
    this.limit.set(30);
  }

  clearTopTen(event?: Event) {
    if (event) event.stopPropagation();
    this.showTopTen.set(false);
    this.limit.set(30);
  }

  toggleSuggeriti() {
    this.showSuggeriti.update(v => !v);
    this.limit.set(30);
  }

  clearSuggeriti(event?: Event) {
    if (event) event.stopPropagation();
    this.showSuggeriti.set(false);
    this.limit.set(30);
  }

  getMassSuggestionWeight(id_canti: number): number | null {
    const weight = this.cantiLettureService.suggestionsMap().get(id_canti);
    return weight !== undefined ? weight : null;
  }

  getMassSuggestionMoment(id_canti: number): string | null {
    const moments = this.cantiLettureService.suggestionsMomentsMap().get(id_canti);
    return moments && moments.length > 0 ? moments.join(', ') : null;
  }

  getSelectedMassFormattedDate(): string | null {
    const dateStr = this.cantiLettureService.selectedMassDate();
    if (!dateStr) return null;
    const parts = dateStr.split('-');
    if (parts.length === 3) {
      return `${parts[2]}/${parts[1]}/${parts[0]}`;
    }
    return dateStr;
  }

  getSelectedMassTitle(): string | null {
    const dateStr = this.cantiLettureService.selectedMassDate();
    const data = this.cantiLettureService.data();
    if (dateStr && data && data.masses[dateStr]) {
      return data.masses[dateStr].title;
    }
    return null;
  }

  getSelectedMassSummary(): string | null {
    const dateStr = this.cantiLettureService.selectedMassDate();
    const data = this.cantiLettureService.data();
    if (dateStr && data && data.masses[dateStr]) {
      return data.masses[dateStr].summary || null;
    }
    return null;
  }

  getEsecuzioniCount(id: string): number | null {
    const numId = parseInt(id, 10);
    if (isNaN(numId)) return null;
    const es = this.cantiService.cantiEseguiti().find(x => x.id_canti === numId);
    return es ? es.num : null;
  }

  onImgLoad(id: string) {
    this.loadedThumbs.add(id);
  }

  openYoutube(event: Event, link: string) {
    event.stopPropagation();
    const videoId = this.cantiService.getYoutubeId(link);
    if (videoId) {
      window.open(`https://www.youtube.com/watch?v=${videoId}`, '_blank');
    }
  }

  playVideo(event: Event, id: string) {
    event.stopPropagation();
    if (!this.youtubePlayerService.isPlayerSupported()) {
      return;
    }
    this.youtubePlayerService.setMediaSessionCallbacks(
      () => this.playNextPreview(),
      () => this.playPrevPreview()
    );
    this.youtubePlayerService.initPlayer(
      id, 
      0, 
      () => {
        if (this.settingsService.autoAdvance()) {
          this.playNextPreview();
        } else {
          this.youtubePlayerService.stop();
        }
      }, 
      () => {
        if (this.settingsService.autoAdvance()) {
          setTimeout(() => this.playNextPreview(), 500);
        } else {
          this.youtubePlayerService.stop();
        }
      }
    );
  }

  stopVideo(event: Event) {
    if (event) event.stopPropagation();
    this.youtubePlayerService.stop();
    this.playlistService.autoPlayPlaylist.set(false);
  }

  playNextPreview(event?: Event) {
    if (event) event.stopPropagation();
    const currentId = this.youtubePlayerService.currentCantoId();
    if (!currentId) return;

    const list = this.visibleCanti();
    const currentIndex = list.findIndex(c => c.id === currentId);
    
    for (let i = currentIndex + 1; i < list.length; i++) {
      if (list[i].link_youtube) {
        this.playVideo(new Event('skip'), list[i].id);
        
        setTimeout(() => {
          const el = document.getElementById('canto-' + list[i].id);
          if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }, 300);
        return;
      }
    }
    
    this.youtubePlayerService.stop();
  }

  playPrevPreview(event?: Event) {
    if (event) event.stopPropagation();
    const currentId = this.youtubePlayerService.currentCantoId();
    if (!currentId) return;

    const list = this.visibleCanti();
    const currentIndex = list.findIndex(c => c.id === currentId);
    
    for (let i = currentIndex - 1; i >= 0; i--) {
      if (list[i].link_youtube) {
        this.playVideo(new Event('skip'), list[i].id);
        
        setTimeout(() => {
          const el = document.getElementById('canto-' + list[i].id);
          if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
        }, 300);
        return;
      }
    }
  }

  onSeek(event: any) {
    this.youtubePlayerService.seekTo(event.detail.value);
  }

  onSeekStart() {
    this.isSeeking = true;
  }

  onSeekEnd() {
    this.isSeeking = false;
  }

  getMomentiForCanto(ids: number[] | undefined): any[] {
    if (!ids) return [];
    return this.cantiService.momenti()
      .filter(m => ids.includes(m.id));
  }

  filterByMomento(event: Event, id: number) {
    event.stopPropagation();
    // Use liturgico as default for momento tags
    this.toggleIndex(id, 'liturgico');
    // Scroll to top to show results
    const content = document.querySelector('ion-content');
    if (content) (content as any).scrollToTop(300);
  }

  loadData(event: any) {
    setTimeout(() => {
      this.limit.update(l => l + 10);
      event.target.complete();
    }, 500);
  }

  // --- 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) {
      // We don't preventDefault here to allow scrolling if needed, 
      // but usually pinch should be captured.
      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);
      }
    }
  }

  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));
  }

  handleScannedData(data: string) {
    if (!data) return;

    if (data.includes('import=')) {
      try {
        let base64 = '';
        if (data.includes('?import=')) {
          base64 = data.split('?import=')[1];
        } else if (data.includes('&import=')) {
          base64 = data.split('&import=')[1];
        }

        if (base64.includes('&')) {
          base64 = base64.split('&')[0];
        }
        if (base64.includes('#')) {
          base64 = base64.split('#')[0];
        }

        this.handleImport(base64);
        return;
      } catch (e) {
        console.error('Failed to parse scanned link', e);
      }
    }

    if (data.startsWith('canti:')) {
      const parts = data.replace('canti:', '').split(':');
      let idsStr = '';
      if (parts.length > 1) {
        this.playlistService.activeListName.set(parts[0]);
        idsStr = parts[1];
      } else {
        this.playlistService.activeListName.set('Lista Parrocchiale');
        idsStr = parts[0];
      }
      
      const ids = idsStr.split(',').map(id => id.trim());
      this.playlistService.activeListIds.set(ids);
      this.limit.set(50); // Show more initially for special lists
      
      // Clear other filters to avoid confusion
      this.selectedLiturgico.set(null);
      this.selectedTematico.set(null);
    }
  }

  toggleVoiceSearch() {
    if (this.audioEngine.isSearching()) {
      this.audioEngine.stopSearchRecognition();
    } else {
      this.audioEngine.startSearchRecognition();
    }
  }

  async finishSelection() {
    const alert = await this.alertCtrl.create({
      header: 'Salva Playlist',
      inputs: [
        {
          name: 'name',
          type: 'text',
          placeholder: 'Nome della playlist',
          value: this.playlistService.activeListName() || ''
        }
      ],
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Salva',
          handler: async (data) => {
            if (data.name) {
              const ids = this.reorderList().map(s => s.id);
              await this.playlistService.savePlaylist(data.name, ids);
              
              const toast = await this.toastCtrl.create({
                message: 'Playlist salvata!',
                duration: 2000,
                color: 'success'
              });
              await toast.present();
              
              this.isAddingSongs.set(false);
              this.playlistService.selectionMode.set(false);
              this.playlistService.selectedIds.set(new Set());
              return true;
            }
            return false;
          }
        }
      ]
    });
    await alert.present();
  }

  cancelSelection() {
    const id = this.playlistService.activePlaylistId();
    if (id) {
      const pl = this.playlistService.playlists().find(p => p.id === id);
      if (pl) {
        this.playlistService.activeListIds.set(pl.ids);
        this.playlistService.activeListName.set(pl.name);
      }
    }
    
    this.playlistService.selectionMode.set(false);
    this.playlistService.selectedIds.set(new Set());
    this.isAddingSongs.set(false);
  }

  clearSpecialList(event?: Event) {
    if (event) event.stopPropagation();
    this.playlistService.activeListIds.set([]);
    this.playlistService.activeListName.set(null);
    this.playlistService.activePlaylistId.set(null);
    this.limit.set(30);
  }

  playPlaylist() {
    const ids = this.playlistService.activeListIds();
    if (ids.length > 0) {
      this.playlistService.autoPlayPlaylist.set(true);
      this.router.navigate(['/player'], { queryParams: { id: ids[0] } });
    }
  }

  shareActivePlaylist() {
    const ids = this.playlistService.activeListIds();
    const name = this.playlistService.activeListName() || 'Playlist';
    this.playlistService.sharePlaylistQR(ids, name);
  }

  async importPlaylist() {
    const modal = await this.modalCtrl.create({
      component: QrScannerComponent
    });
    await modal.present();

    const { data } = await modal.onWillDismiss();
    if (!data) return;
    this.handleScannedData(data);
  }

  async deleteActivePlaylist() {
    const id = this.playlistService.activePlaylistId();
    const name = this.playlistService.activeListName();
    if (!id || !name) return;

    const alert = await this.alertCtrl.create({
      header: 'Elimina Playlist',
      message: `Vuoi davvero eliminare "${name}"?`,
      buttons: [
        { text: 'Annulla', role: 'cancel' },
        { 
          text: 'Elimina', 
          role: 'destructive',
          handler: () => {
            this.playlistService.deletePlaylist(id);
            this.clearSpecialList();
          }
        }
      ]
    });
    await alert.present();
  }

  editPlaylist() {
    const ids = this.playlistService.activeListIds();
    const name = this.playlistService.activeListName();
    
    // Prova a recuperare l'ID se stiamo editando una playlist salvata
    const found = this.playlistService.playlists().find(p => p.name === name);
    if (found) {
      this.playlistService.activePlaylistId.set(found.id);
    }

    this.playlistService.selectedIds.set(new Set(ids));
    const songs = ids.map(id => this.findCanto(id)).filter((c): c is any => !!c);
    this.reorderList.set(songs);
    this.playlistService.selectionMode.set(true);
    this.isAddingSongs.set(false); // Default to reorder view
    
    // Svuota la playlist attiva per mostrare tutto l'elenco in modalità selezione
    this.playlistService.activeListIds.set([]);
    this.playlistService.activeListName.set(name);
  }

  drop(event: CdkDragDrop<any[]>) {
    const arr = [...this.reorderList()];
    moveItemInArray(arr, event.previousIndex, event.currentIndex);
    this.reorderList.set(arr);
  }

  toggleAddingSongs() {
    this.isAddingSongs.update(v => !v);
    this.limit.set(10);
  }

  getCommunitySongNumber(canto: any): string | null {
    if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) return null;
    const cantiInfo = this.comunitaService.comunitaCantiInfo();
    const info = cantiInfo.find(x => x.id_canti === canto.id_canti || x.id_canti === Number(canto.id));
    return info && info.num_canto ? info.num_canto.toString() : null;
  }

  toggleComunitaFilter() {
    if (!this.comunitaService.comunitaCode()) {
      this.promptComunitaCode();
    } else {
      this.comunitaService.isFilterActive.update(v => !v);
    }
  }

  editComunitaCode(event: Event) {
    event.stopPropagation();
    this.promptComunitaCode();
  }

  async promptComunitaCode() {
    const alert = await this.alertCtrl.create({
      header: 'Imposta Comunità',
      subHeader: 'Inserisci il codice parrocchiale/comunità per attivare il libretto dedicato:',
      cssClass: 'premium-alert',
      inputs: [
        {
          name: 'code',
          type: 'text',
          placeholder: 'Es: 123456',
          value: this.comunitaService.comunitaCode()
        }
      ],
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Rimuovi',
          role: 'destructive',
          cssClass: 'alert-button-delete',
          handler: async () => {
            await this.comunitaService.setComunitaCode('');
            const toast = await this.toastCtrl.create({
              message: 'Comunità disattivata.',
              duration: 2000,
              color: 'secondary'
            });
            await toast.present();
          }
        },
        {
          text: 'Salva',
          handler: async (data) => {
            const trimmed = (data.code || '').trim();
            if (!trimmed) {
              await this.comunitaService.setComunitaCode('');
              return;
            }

            // Show loading overlay with progress
            const loading = await this.loadingCtrl.create({
              message: 'Caricamento 0%',
              cssClass: 'premium-loading',
              spinner: 'crescent'
            });
            await loading.present();

            // Subscribe to progress updates
            let progressInterval: any = null;
            progressInterval = setInterval(() => {
              const pct = this.comunitaService.loadingProgress();
              loading.message = `Caricamento ${pct}%`;
              if (pct >= 100) {
                clearInterval(progressInterval);
              }
            }, 100);

            const success = await this.comunitaService.setComunitaCode(trimmed);
            clearInterval(progressInterval);
            await loading.dismiss();

            if (success) {
              const toast = await this.toastCtrl.create({
                message: `Comunità attivata: ${this.comunitaService.comunitaNome()}`,
                duration: 2000,
                color: 'success'
              });
              await toast.present();
            } else {
              const toast = await this.toastCtrl.create({
                message: 'Codice non trovato o errore di connessione.',
                duration: 2000,
                color: 'danger'
              });
              await toast.present();
              setTimeout(() => this.promptComunitaCode(), 500);
            }
          }
        }
      ]
    });
    await alert.present();
  }

  private massCardStartX: number = 0;
  private massCardStartY: number = 0;

  onMassCardTouchStart(event: TouchEvent) {
    if (event.touches.length === 1) {
      this.massCardStartX = event.touches[0].clientX;
      this.massCardStartY = event.touches[0].clientY;
    }
  }

  onMassCardTouchEnd(event: TouchEvent) {
    if (event.changedTouches.length === 1) {
      const endX = event.changedTouches[0].clientX;
      const endY = event.changedTouches[0].clientY;
      const diffX = endX - this.massCardStartX;
      const diffY = endY - this.massCardStartY;

      // Ensure it is a horizontal swipe (diffX is much larger than diffY)
      if (Math.abs(diffX) > 60 && Math.abs(diffY) < 40) {
        // Prevent triggering click expansion
        event.stopPropagation();
        event.preventDefault();

        if (diffX > 0) {
          // Swiped right -> go to PREVIOUS date
          this.navigateMassDate(-1);
        } else {
          // Swiped left -> go to NEXT date
          this.navigateMassDate(1);
        }
      }
    }
  }

  async navigateMassDate(direction: number) {
    const list = this.cantiLettureService.availableMasses();
    if (list.length === 0) return;
    
    const currentDate = this.cantiLettureService.selectedMassDate();
    if (!currentDate) {
      this.cantiLettureService.selectedMassDate.set(list[0].date);
      return;
    }

    const currentIndex = list.findIndex(m => m.date === currentDate);
    if (currentIndex === -1) {
      this.cantiLettureService.selectedMassDate.set(list[0].date);
      return;
    }

    const nextIndex = currentIndex + direction;
    if (nextIndex >= 0 && nextIndex < list.length) {
      // Set the next/prev date
      this.cantiLettureService.selectedMassDate.set(list[nextIndex].date);
      
      const toast = await this.toastCtrl.create({
        message: `Messa: ${list[nextIndex].day} ${this.formatCompactDate(list[nextIndex].date)}`,
        duration: 1500,
        color: 'secondary',
        position: 'bottom'
      });
      await toast.present();
    } else {
      // "quando le messe sono finite rimani sull'ultima valorizzata, non dare errore"
      const targetIndex = direction > 0 ? list.length - 1 : 0;
      this.cantiLettureService.selectedMassDate.set(list[targetIndex].date);
      
      const toast = await this.toastCtrl.create({
        message: direction > 0 ? 'Nessun\'altra messa futura disponibile.' : 'Nessun\'altra messa passata disponibile.',
        duration: 1500,
        color: 'medium',
        position: 'bottom'
      });
      await toast.present();
    }
  }

  private formatCompactDate(dateStr: string): string {
    const parts = dateStr.split('-');
    if (parts.length === 3) {
      return `${parts[2]}/${parts[1]}`;
    }
    return dateStr;
  }
}

