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, LoadingController } 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';
import { showFullscreenUpdateOverlay } from '../../app.component';
import { QrScannerComponent } from '../../components/qr-scanner/qr-scanner.component';
import { IdentityQrModalComponent } from '../../components/identity-qr-modal/identity-qr-modal.component';

@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 loadingCtrl = inject(LoadingController);
  private router = inject(Router);

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

  constructor() {}

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

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

  async showBackupQrCode() {
    const modal = await this.modalCtrl.create({
      component: IdentityQrModalComponent,
      componentProps: {
        userUuid: this.settingsService.userUuid()
      }
    });
    return await modal.present();
  }

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

    const { data } = await modal.onWillDismiss();
    if (data) {
      this.confirmRestore(data);
    }
  }

  async manualRestore() {
    const alert = await this.alertCtrl.create({
      header: 'Ripristina con Codice',
      message: 'Digita o incolla il tuo codice identificativo univoco.',
      inputs: [
        {
          name: 'code',
          type: 'text',
          placeholder: 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx',
          value: ''
        }
      ],
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Conferma',
          handler: (data) => {
            if (data.code && data.code.trim()) {
              this.confirmRestore(data.code.trim());
            }
          }
        }
      ]
    });
    await alert.present();
  }

  private async confirmRestore(code: string) {
    // Basic validation for UUID
    const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
    if (!uuidRegex.test(code)) {
      const errorAlert = await this.alertCtrl.create({
        header: 'Codice Non Valido',
        message: 'Il codice inserito non sembra essere un identificativo univoco valido. Riprova.',
        buttons: ['OK']
      });
      await errorAlert.present();
      return;
    }

    const alert = await this.alertCtrl.create({
      header: 'Ripristina Identità',
      message: 'Sei sicuro di voler ripristinare questa identità? L\'ID attuale del dispositivo verrà sovrascritto permanentemente ed eventuali canti e playlist remoti associati al nuovo ID verranno scaricati.',
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Ripristina',
          role: 'destructive',
          handler: async () => {
            const loading = await this.loadingCtrl.create({
              message: 'Scaricamento dati da remoto...'
            });
            await loading.present();

            try {
              const response = await fetch(`https://api.canticristiani.it/${code}.json?cb=${Date.now()}`, { cache: 'no-store' });
              if (response.ok) {
                const remoteJson = await response.json();
                if (Array.isArray(remoteJson)) {
                  // Reconstruct user name/metadata
                  const userMetadata = remoteJson.find((item: any) => item.momenti && item.momenti.includes('UserMetadata'));
                  if (userMetadata && userMetadata.titolo) {
                    this.settingsService.setUserName(userMetadata.titolo);
                  }

                  // Reconstruct custom songs
                  const customSongs = remoteJson
                    .filter((item: any) => (!item.momenti || !item.momenti.includes('Playlist')) && (!item.momenti || !item.momenti.includes('UserMetadata')))
                    .map((item: any) => ({
                      id: `my_${item.id_canti}`,
                      id_canti: Number(item.id_canti),
                      titolo: item.titolo || 'Senza Titolo',
                      testo: item.testo || '',
                      accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined),
                      autore: item.autore || '',
                      link_youtube: item.link_youtube || '',
                      id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || []
                    }));

                  if (customSongs.length > 0) {
                    this.myCantiService.myCanti.set(customSongs);
                    const storage = this.cantiService.getStorage();
                    if (storage) {
                      await storage.set('my-canti', customSongs);
                    }
                  }

                  // Reconstruct playlists
                  const playlists = remoteJson
                    .filter((item: any) => item.momenti && item.momenti.includes('Playlist'))
                    .map((item: any) => {
                      let songSettings = {};
                      if (item.periodi && item.periodi.length > 0) {
                        try {
                          songSettings = JSON.parse(item.periodi[0]);
                        } catch (e) {}
                      }
                      return {
                        id: String(item.id_canti),
                        name: item.titolo,
                        ids: item.testo ? item.testo.split(',') : [],
                        songSettings: songSettings,
                        createdAt: new Date()
                      };
                    });

                  if (playlists.length > 0) {
                    this.playlistService.playlists.set(playlists);
                    if (this.playlistService['_storage']) {
                      const key = this.playlistService.getPlaylistsStorageKey();
                      await this.playlistService['_storage'].set(key, playlists);
                    }
                  }
                }
              }
            } catch (err) {
              console.error('Failed to restore backup data:', err);
            } finally {
              await loading.dismiss();
            }

            this.settingsService.setUserUuid(code);
            const toast = await this.toastCtrl.create({
              message: 'Identità e dati ripristinati con successo! Ricaricamento...',
              duration: 2000,
              color: 'success',
              position: 'bottom'
            });
            await toast.present();

            setTimeout(() => {
              window.location.replace(window.location.origin + window.location.pathname);
            }, 1500);
          }
        }
      ]
    });
    await alert.present();
  }

  async restoreOriginalIdentity() {
    const original = this.settingsService.originalUserUuid();
    if (!original) {
      const alert = await this.alertCtrl.create({
        header: 'Errore',
        message: 'Nessun identificativo originario trovato.',
        buttons: ['OK']
      });
      await alert.present();
      return;
    }

    const alert = await this.alertCtrl.create({
      header: 'Ripristina ID Originario',
      message: `Sei sicuro di voler ripristinare il codice ID originario assegnato alla prima installazione? L'ID attuale del dispositivo verrà sovrascritto e verranno scaricati eventuali canti e playlist associati all'ID originario.`,
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Ripristina',
          handler: () => {
            this.confirmRestore(original);
          }
        }
      ]
    });
    await alert.present();
  }

  async syncLocalDataToServer() {
    const uid = this.settingsService.userUuid();
    if (!uid) {
      const alert = await this.alertCtrl.create({
        header: 'Errore',
        message: 'Nessun identificativo utente (UID) trovato.',
        buttons: ['OK']
      });
      await alert.present();
      return;
    }

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

    try {
      await this.playlistService.syncLocalDataToServer();
      await toastLoading.dismiss();

      const toastSuccess = await this.toastCtrl.create({
        message: 'Backup sincronizzato con successo!',
        duration: 3000,
        color: 'success'
      });
      await toastSuccess.present();
    } catch (err: any) {
      try {
        await toastLoading.dismiss();
      } catch (e) {}
      console.error('Failed to backup to server:', err);
      const alertError = await this.alertCtrl.create({
        header: 'Errore di sincronizzazione',
        message: 'Impossibile inviare il backup al server. Controlla la connessione e riprova.',
        buttons: ['OK']
      });
      await alertError.present();
    }
  }

  async restoreBackupFromServer() {
    const code = this.settingsService.userUuid();
    if (!code) {
      const alert = await this.alertCtrl.create({
        header: 'Errore',
        message: 'Nessun identificativo utente (UID) trovato.',
        buttons: ['OK']
      });
      await alert.present();
      return;
    }

    const alert = await this.alertCtrl.create({
      header: 'Ripristina Backup',
      message: 'Sei sicuro di voler ripristinare i dati dal server? I tuoi canti personali e le tue scalette locali verranno allineati con l\'ultimo backup presente sul server.',
      buttons: [
        {
          text: 'Annulla',
          role: 'cancel'
        },
        {
          text: 'Ripristina',
          handler: async () => {
            const loading = await this.loadingCtrl.create({
              message: 'Scaricamento dati da remoto...'
            });
            await loading.present();

            try {
              const response = await fetch(`https://api.canticristiani.it/${code}.json?cb=${Date.now()}`, { cache: 'no-store' });
              if (response.ok) {
                const remoteJson = await response.json();
                if (Array.isArray(remoteJson)) {
                  // Reconstruct user name/metadata
                  const userMetadata = remoteJson.find((item: any) => item.momenti && item.momenti.includes('UserMetadata'));
                  if (userMetadata && userMetadata.titolo) {
                    this.settingsService.setUserName(userMetadata.titolo);
                  }

                  // Reconstruct custom songs
                  const customSongs = remoteJson
                    .filter((item: any) => (!item.momenti || !item.momenti.includes('Playlist')) && (!item.momenti || !item.momenti.includes('UserMetadata')))
                    .map((item: any) => ({
                      id: `my_${item.id_canti}`,
                      id_canti: Number(item.id_canti),
                      titolo: item.titolo || 'Senza Titolo',
                      testo: item.testo || '',
                      accordi: item.accordi || (item.testo?.includes('[') ? item.testo : undefined),
                      autore: item.autore || '',
                      link_youtube: item.link_youtube || '',
                      id_momenti: item.momenti?.map((m: any) => Number(m)).filter((m: any) => !isNaN(m)) || []
                    }));

                  this.myCantiService.myCanti.set(customSongs);
                  const storage = this.cantiService.getStorage();
                  if (storage) {
                    await storage.set('my-canti', customSongs);
                  }

                  // Reconstruct playlists
                  const playlists = remoteJson
                    .filter((item: any) => item.momenti && item.momenti.includes('Playlist'))
                    .map((item: any) => {
                      let songSettings = {};
                      if (item.periodi && item.periodi.length > 0) {
                        try {
                          songSettings = JSON.parse(item.periodi[0]);
                        } catch (e) {}
                      }
                      return {
                        id: String(item.id_canti),
                        name: item.titolo,
                        ids: item.testo ? item.testo.split(',') : [],
                        songSettings: songSettings,
                        createdAt: new Date()
                      };
                    });

                  this.playlistService.playlists.set(playlists);
                  if (this.playlistService['_storage']) {
                    const key = this.playlistService.getPlaylistsStorageKey();
                    await this.playlistService['_storage'].set(key, playlists);
                  }

                  const toast = await this.toastCtrl.create({
                    message: 'Dati ripristinati con successo! Ricaricamento...',
                    duration: 2000,
                    color: 'success',
                    position: 'bottom'
                  });
                  await toast.present();

                  setTimeout(() => {
                    window.location.replace(window.location.origin + window.location.pathname);
                  }, 1500);
                } else {
                  throw new Error('Formato dati del backup non valido.');
                }
              } else {
                throw new Error('Nessun backup trovato sul server per questo ID.');
              }
            } catch (err: any) {
              console.error('Failed to restore backup data:', err);
              const errorAlert = await this.alertCtrl.create({
                header: 'Errore Ripristino',
                message: err.message || 'Impossibile scaricare il backup dal server. Verifica la connessione.',
                buttons: ['OK']
              });
              await errorAlert.present();
            } finally {
              await loading.dismiss();
            }
          }
        }
      ]
    });
    await alert.present();
  }

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

  onNameChange(event: any) {
    this.settingsService.setUserName(event.target.value);
  }

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



  async onComunitaToggleChange(event: any) {
    const checked = event.detail.checked;
    if (checked) {
      this.settingsService.comunitaEnabled.set(true);
      localStorage.setItem('comunita-enabled', 'true');
    } else {
      this.settingsService.comunitaEnabled.set(false);
      localStorage.setItem('comunita-enabled', 'false');
    }
  }

  async editComunita() {
    await this.comunitaService.setComunitaCode('');
  }

  async saveComunitaCode(code: string) {
    const trimmed = (code || '').trim();
    if (!trimmed) return;

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

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

  async removeComunita() {
    await this.comunitaService.setComunitaCode('');
    this.settingsService.comunitaEnabled.set(false);
    localStorage.setItem('comunita-enabled', 'false');
    const toast = await this.toastCtrl.create({
      message: 'Comunità disattivata.',
      duration: 2000,
      color: 'secondary'
    });
    await toast.present();
  }
}
