import { Component, inject } from '@angular/core';
import { ThemeService } from '../../services/theme.service';
import { SettingsService } from '../../services/settings.service';
import { CantiService } from '../../services/canti.service';
import { ConnectivityService } from '../../services/connectivity.service';
import { SwUpdate, VersionReadyEvent } from '@angular/service-worker';
import { ToastController, ModalController, AlertController } from '@ionic/angular';
import { VERSION } from '../../version';
import { PlaylistService } from '../../services/playlist.service';
import { Router } from '@angular/router';
import { filter, first } from 'rxjs/operators';

import { MyCantiService } from '../../services/my-canti.service';
import { CantiLettureService } from '../../services/canti-letture.service';
import { ComunitaService } from '../../services/comunita.service';
import { environment } from '../../../environments/environment';

@Component({
  selector: 'app-settings',
  templateUrl: './settings.page.html',
  styleUrls: ['./settings.page.scss'],
  standalone: false
})
export class SettingsPage {
  public myCantiService = inject(MyCantiService);
  public themeService = inject(ThemeService);
  public settingsService = inject(SettingsService);
  public cantiService = inject(CantiService);
  public connectivityService = inject(ConnectivityService);
  public playlistService = inject(PlaylistService);
  public cantiLettureService = inject(CantiLettureService);
  public comunitaService = inject(ComunitaService);
  private swUpdate = inject(SwUpdate);
  private toastCtrl = inject(ToastController);
  private modalCtrl = inject(ModalController);
  private alertCtrl = inject(AlertController);
  private router = inject(Router);

  public version = VERSION;
  public contactEmail = environment.contactEmail;
  public appName = environment.appName;
  public showIosInstructions = false;

  constructor() {}

  private async forceBypassCacheAndCheck(): Promise<boolean> {
    try {
      // 1. Forza il browser mobile a controllare la rete per aggiornamenti al Service Worker nativo
      if ('serviceWorker' in navigator) {
        const registrations = await navigator.serviceWorker.getRegistrations();
        for (const registration of registrations) {
          await registration.update();
          console.log('[PWA-Update] Native Service Worker updated from settings');
        }
      }
      // 2. Forza il caricamento di ngsw.json bypassando le cache intermedie e locali
      await fetch(`/ngsw.json?cb=${Date.now()}`, { cache: 'no-store' });
      await fetch('/ngsw.json', { cache: 'reload' });
      console.log('[PWA-Update] Caches successfully busted for ngsw.json');
    } catch (e) {
      console.warn('[PWA-Update] Failed to bust cache for ngsw.json:', e);
    }
    return await this.swUpdate.checkForUpdate();
  }

  async installApp() {
    await this.settingsService.installPwa();
  }

  toggleIosInstructions() {
    this.showIosInstructions = !this.showIosInstructions;
  }

  onModeChange(event: any) {
    this.settingsService.setShowChordsDefault(event.detail.value === 'chords');
  }

  onMassChange(event: any) {
    this.cantiLettureService.setSelectedMass(event.detail.value);
  }

  async fullRefresh() {
    // 1. Refresh JSON data
    this.cantiService.refresh();
    
    // 2. Refresh liturgical readings JSON
    try {
      await this.cantiLettureService.fetchData();
    } catch (err) {
      console.error('Failed to refresh liturgical readings:', err);
    }

    // 3. Refresh community data if a code is active
    const comunitaCode = this.comunitaService.comunitaCode();
    if (comunitaCode) {
      try {
        await this.comunitaService.setComunitaCode(comunitaCode);
      } catch (err) {
        console.error('Failed to refresh community data:', err);
      }
    }

    // 4. Check for Service Worker updates
    if (this.swUpdate.isEnabled) {
      try {
        const updateFound = await this.forceBypassCacheAndCheck();
        if (updateFound) {
          const toast = await this.toastCtrl.create({
            message: 'Nuova versione disponibile! Aggiornamento in corso...',
            duration: 2000,
            color: 'secondary'
          });
          await toast.present();
          
          this.swUpdate.versionUpdates
            .pipe(
              filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),
              first()
            )
            .subscribe(async () => {
              console.log('[PWA-Update] FullRefresh: version ready, activating...');
              await this.swUpdate.activateUpdate();
              window.location.replace(window.location.origin + window.location.pathname + '?update=' + Date.now());
            });
            
          setTimeout(async () => {
            try {
              await this.swUpdate.activateUpdate();
            } catch(e) {}
            window.location.replace(window.location.origin + window.location.pathname + '?update=' + Date.now());
          }, 6000);
          return;
        }
      } catch (err) {
        console.error('Failed to check for updates', err);
      }
    }

    const toast = await this.toastCtrl.create({
      message: 'Dati aggiornati correttamente!',
      duration: 2000,
      color: 'success'
    });
    await toast.present();
  }

  async checkForAppUpdate() {
    if (!this.swUpdate.isEnabled) {
      const toast = await this.toastCtrl.create({
        message: 'Aggiornamenti non supportati su questo browser.',
        duration: 3000,
        color: 'medium'
      });
      await toast.present();
      return;
    }

    const toastLoading = await this.toastCtrl.create({
      message: 'Ricerca aggiornamenti in corso...',
      duration: 1500,
      color: 'secondary'
    });
    await toastLoading.present();

    try {
      const updateFound = await this.forceBypassCacheAndCheck();
      if (updateFound) {
        const toast = await this.toastCtrl.create({
          message: 'Nuova versione trovata! Installazione e attivazione in corso...',
          duration: 3000,
          color: 'success'
        });
        await toast.present();
        
        // Sottoscrizione per attivare l'aggiornamento appena terminato il download
        this.swUpdate.versionUpdates
          .pipe(
            filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),
            first()
          )
          .subscribe(async () => {
            console.log('[PWA-Update] Manual check: version ready, activating...');
            await this.swUpdate.activateUpdate();
            window.location.replace(window.location.origin + window.location.pathname + '?update=' + Date.now());
          });
          
        // Timeout di sicurezza per forzare l'attivazione e il ricaricamento se è già scaricato
        setTimeout(async () => {
          try {
            await this.swUpdate.activateUpdate();
          } catch(e) {}
          window.location.replace(window.location.origin + window.location.pathname + '?update=' + Date.now());
        }, 8000);
      } else {
        const toast = await this.toastCtrl.create({
          message: 'L\'applicazione è già aggiornata all\'ultima versione.',
          duration: 3000,
          color: 'success'
        });
        await toast.present();
      }
    } catch (err) {
      console.error('Check update failed', err);
      const toast = await this.toastCtrl.create({
        message: 'Errore durante la ricerca di aggiornamenti.',
        duration: 3000,
        color: 'danger'
      });
      await toast.present();
    }
  }
}
