import { Injectable, signal, effect } from '@angular/core';

@Injectable({
  providedIn: 'root'
})
export class SettingsService {
  /** Default mode for viewing songs: true = chords, false = text only */
  public showChordsDefault = signal<boolean>(true);

  /** UI Fullscreen mode (lyrics only): true = active */
  public fullscreenMode = signal<boolean>(false);

  /** Browser Fullscreen state: true = fullscreen active */
  public browserFullscreen = signal<boolean>(
    typeof document !== 'undefined' && !!(
      document.fullscreenElement ||
      (document as any).webkitFullscreenElement ||
      (document as any).mozFullScreenElement ||
      (document as any).msFullscreenElement
    )
  );

  /** Avanzamento automatico: true = passa al brano successivo automaticamente */
  public autoAdvance = signal<boolean>(true);

  /** Editor e Canti Personali: true = mostra funzioni aggiunta e lista "Miei" */
  public showEditor = signal<boolean>(false);

  /** Schermo sempre acceso: true = attiva Screen Wake Lock */
  public keepScreenOn = signal<boolean>(true);

  /** Funzionalità Comunità: true = il chip comunità è visibile nella home */
  public comunitaEnabled = signal<boolean>(false);

  /** Invio dati statistici: true = invia pacchetto dati statistici */
  public invioDatiStatistici = signal<boolean>(false);

  /** Visualizza tag sotto autore nella lista canti: true = attivo */
  public showTagsInList = signal<boolean>(true);

  /** Visualizza data update sotto autore nella lista canti: true = attivo */
  public showUpdateDate = signal<boolean>(true);

  /** Attiva autoscroll standard nel dettaglio canto: true = attivo */
  public enableStandardAutoscroll = signal<boolean>(false);

  /** Attiva autoscroll visuale nel dettaglio canto: true = attivo */
  public enableVisualAutoscroll = signal<boolean>(true);

  /** Preferenza notazione accordi: diesis o bemolle */
  public chordNotationPreference = signal<'diesis' | 'bemolle'>('diesis');

  /** Avanzamento a pagine del karaoke manuale: true = i tasti next/prev voltano la pagina */
  public karaokePageScrollMode = signal<boolean>(false);

  /** Vista orizzontale per proiezione: true = attiva layout landscape per proiezione */
  public landscapeProjectionEnabled = signal<boolean>(true);

  /** Identificativo utente univoco per la gestione delle comunità */
  public userUuid = signal<string>('');

  /** Identificativo originario assegnato alla prima installazione */
  public originalUserUuid = signal<string>('');

  /** Nome associato all'identità utente */
  public userName = signal<string>('');

  private wakeLock: any = null;

  // PWA installation signals
  public deferredPrompt = signal<any>(null);
  public showInstallButton = signal<boolean>(false);
  public isStandalone = signal<boolean>(false);
  public isIos = signal<boolean>(false);
  public isAndroid = signal<boolean>(false);
  public isVersionCheckComplete = signal<boolean>(false);

  constructor() {
    // Gestione/Generazione ID utente univoco
    let savedUuid = localStorage.getItem('user-uuid');
    if (!savedUuid) {
      if (typeof crypto !== 'undefined' && crypto.randomUUID) {
        savedUuid = crypto.randomUUID();
      } else {
        savedUuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
          const r = Math.random() * 16 | 0;
          const v = c === 'x' ? r : (r & 0x3 | 0x8);
          return v.toString(16);
        });
      }
      localStorage.setItem('user-uuid', savedUuid);
    }
    this.userUuid.set(savedUuid);

    // Salvataggio dell'ID originario (alla prima installazione) se non è già presente
    let originalUuid = localStorage.getItem('original-user-uuid');
    if (!originalUuid) {
      originalUuid = savedUuid;
      localStorage.setItem('original-user-uuid', originalUuid);
    }
    this.originalUserUuid.set(originalUuid);

    const savedName = localStorage.getItem('user-name');
    if (savedName) {
      this.userName.set(savedName);
    }

    // Detect PWA status
    try {
      this.isStandalone.set(
        window.matchMedia('(display-mode: standalone)').matches ||
        (window.navigator as any).standalone === true
      );
      this.isIos.set(
        /iPad|iPhone|iPod/.test(navigator.userAgent) && !(window as any).MSStream
      );
      this.isAndroid.set(
        /Android/i.test(navigator.userAgent)
      );
    } catch (e) {
      console.warn('Browser environment does not support display-mode media query');
    }

    window.addEventListener('beforeinstallprompt', (e: any) => {
      // Prevent the mini-infobar from appearing on mobile
      e.preventDefault();
      // Stash the event so it can be triggered later.
      this.deferredPrompt.set(e);
      // Update UI notify the user they can install the PWA
      this.showInstallButton.set(true);
    });

    window.addEventListener('appinstalled', () => {
      this.deferredPrompt.set(null);
      this.showInstallButton.set(false);
      this.isStandalone.set(true);
      console.log('PWA was installed');
    });

    // Migration: force settings defaults once for existing users to match the new rules
    const migrationKey = 'defaults-migrated-20260605';
    if (localStorage.getItem(migrationKey) !== 'true') {
      localStorage.setItem('show-chords-default', 'true');
      localStorage.setItem('fullscreen-mode', this.isIos().toString());
      localStorage.setItem('show-editor', 'false');
      localStorage.setItem('auto-advance', 'true');
      localStorage.setItem('keep-screen-on', 'true');
      localStorage.setItem('comunita-enabled', 'false');
      localStorage.setItem('invio-dati-statistici', 'false');
      localStorage.setItem('show-tags-in-list', 'true');
      localStorage.setItem('show-update-date', 'true');
      localStorage.setItem('enable-standard-autoscroll', 'false');
      localStorage.setItem('enable-visual-autoscroll', 'true');
      localStorage.setItem('chord-notation-preference', 'diesis');
      
      // ThemeService high contrast default
      localStorage.setItem('high-contrast', 'true');
      
      localStorage.setItem(migrationKey, 'true');
    }


    const savedChords = localStorage.getItem('show-chords-default');
    if (savedChords !== null) {
      this.showChordsDefault.set(savedChords === 'true');
    } else {
      this.showChordsDefault.set(true);
    }

    const savedFullscreen = localStorage.getItem('fullscreen-mode');
    if (savedFullscreen !== null) {
      this.fullscreenMode.set(savedFullscreen === 'true');
    } else {
      this.fullscreenMode.set(this.isIos());
    }

    const savedEditor = localStorage.getItem('show-editor');
    if (savedEditor !== null) {
      this.showEditor.set(savedEditor === 'true');
    } else {
      this.showEditor.set(false);
    }

    const savedAutoAdvance = localStorage.getItem('auto-advance');
    if (savedAutoAdvance !== null) {
      this.autoAdvance.set(savedAutoAdvance === 'true');
    } else {
      this.autoAdvance.set(true);
    }

    // Keep screen always on by default and always active
    this.keepScreenOn.set(true);

    const savedComunitaEnabled = localStorage.getItem('comunita-enabled');
    if (savedComunitaEnabled !== null) {
      this.comunitaEnabled.set(savedComunitaEnabled === 'true');
    } else {
      this.comunitaEnabled.set(false);
    }

    const savedStats = localStorage.getItem('invio-dati-statistici');
    if (savedStats !== null) {
      this.invioDatiStatistici.set(savedStats === 'true');
    } else {
      this.invioDatiStatistici.set(false);
    }

    const savedShowTags = localStorage.getItem('show-tags-in-list');
    if (savedShowTags !== null) {
      this.showTagsInList.set(savedShowTags === 'true');
    } else {
      this.showTagsInList.set(true);
    }

    const savedShowUpdateDate = localStorage.getItem('show-update-date');
    if (savedShowUpdateDate !== null) {
      this.showUpdateDate.set(savedShowUpdateDate === 'true');
    } else {
      this.showUpdateDate.set(true);
    }

    const savedStandardAutoscroll = localStorage.getItem('enable-standard-autoscroll');
    if (savedStandardAutoscroll !== null) {
      this.enableStandardAutoscroll.set(savedStandardAutoscroll === 'true');
    } else {
      this.enableStandardAutoscroll.set(false);
    }

    const savedVisualAutoscroll = localStorage.getItem('enable-visual-autoscroll');
    if (savedVisualAutoscroll !== null) {
      this.enableVisualAutoscroll.set(savedVisualAutoscroll === 'true');
    } else {
      this.enableVisualAutoscroll.set(true);
    }

    const savedNotation = localStorage.getItem('chord-notation-preference');
    if (savedNotation !== null) {
      this.chordNotationPreference.set(savedNotation === 'bemolle' ? 'bemolle' : 'diesis');
    } else {
      this.chordNotationPreference.set('diesis');
    }

    const savedKaraokePageScrollMode = localStorage.getItem('karaoke-page-scroll-mode');
    if (savedKaraokePageScrollMode !== null) {
      this.karaokePageScrollMode.set(savedKaraokePageScrollMode === 'true');
    } else {
      this.karaokePageScrollMode.set(false);
    }

    const savedLandscapeProjectionEnabled = localStorage.getItem('landscape-projection-enabled');
    if (savedLandscapeProjectionEnabled !== null) {
      this.landscapeProjectionEnabled.set(savedLandscapeProjectionEnabled === 'true');
    } else {
      this.landscapeProjectionEnabled.set(true);
    }

    // Sync browser fullscreen state with listeners (supporting vendor prefixes)
    const updateFullscreenState = () => {
      const isFs = !!(
        document.fullscreenElement ||
        (document as any).webkitFullscreenElement ||
        (document as any).mozFullScreenElement ||
        (document as any).msFullscreenElement
      );
      this.browserFullscreen.set(isFs);
    };

    document.addEventListener('fullscreenchange', updateFullscreenState);
    document.addEventListener('webkitfullscreenchange', updateFullscreenState);
    document.addEventListener('mozfullscreenchange', updateFullscreenState);
    document.addEventListener('MSFullscreenChange', updateFullscreenState);

    effect(() => {
      localStorage.setItem('show-chords-default', this.showChordsDefault().toString());
    });

    effect(() => {
      const mode = this.fullscreenMode();
      localStorage.setItem('fullscreen-mode', mode.toString());
    });

    effect(() => {
      localStorage.setItem('auto-advance', this.autoAdvance().toString());
    });

    effect(() => {
      localStorage.setItem('show-tags-in-list', this.showTagsInList().toString());
    });

    effect(() => {
      localStorage.setItem('show-update-date', this.showUpdateDate().toString());
    });

    effect(() => {
      localStorage.setItem('enable-standard-autoscroll', this.enableStandardAutoscroll().toString());
    });

    effect(() => {
      localStorage.setItem('enable-visual-autoscroll', this.enableVisualAutoscroll().toString());
    });

    effect(() => {
      localStorage.setItem('chord-notation-preference', this.chordNotationPreference());
    });

    effect(() => {
      localStorage.setItem('karaoke-page-scroll-mode', this.karaokePageScrollMode().toString());
    });

    effect(() => {
      localStorage.setItem('landscape-projection-enabled', this.landscapeProjectionEnabled().toString());
    });

    effect(() => {
      const active = this.keepScreenOn();
      localStorage.setItem('keep-screen-on', active.toString());
      if (active) {
        this.requestWakeLock();
      } else {
        this.releaseWakeLock();
      }
    });

    // Re-request on visibility change
    document.addEventListener('visibilitychange', () => {
      if (this.keepScreenOn() && document.visibilityState === 'visible') {
        this.requestWakeLock();
      }
    });
  }

  setShowChordsDefault(val: boolean) {
    this.showChordsDefault.set(val);
  }

  toggleFullscreenMode() {
    this.fullscreenMode.update(v => !v);
  }

  toggleAutoAdvance() {
    this.autoAdvance.update(v => !v);
  }

  toggleEditor() {
    const newValue = !this.showEditor();
    this.showEditor.set(newValue);
    localStorage.setItem('show-editor', newValue.toString());
  }


  toggleComunitaEnabled() {
    const newValue = !this.comunitaEnabled();
    this.comunitaEnabled.set(newValue);
    localStorage.setItem('comunita-enabled', newValue.toString());
  }

  private async requestWakeLock() {
    if ('wakeLock' in navigator) {
      try {
        this.wakeLock = await (navigator as any).wakeLock.request('screen');
      } catch (err: any) {
        console.error(`Wake Lock error: ${err.name}, ${err.message}`);
      }
    }
  }

  private releaseWakeLock() {
    if (this.wakeLock) {
      this.wakeLock.release();
      this.wakeLock = null;
    }
  }

  toggleBrowserFullscreen() {
    const isFs = !!(
      document.fullscreenElement ||
      (document as any).webkitFullscreenElement ||
      (document as any).mozFullScreenElement ||
      (document as any).msFullscreenElement
    );

    if (!isFs) {
      const docEl = document.documentElement as any;
      if (docEl.requestFullscreen) {
        docEl.requestFullscreen().catch((err: any) => console.error(err));
      } else if (docEl.webkitRequestFullscreen) {
        docEl.webkitRequestFullscreen();
      } else if (docEl.mozRequestFullScreen) {
        docEl.mozRequestFullScreen();
      } else if (docEl.msRequestFullscreen) {
        docEl.msRequestFullscreen();
      }
    } else {
      const doc = document as any;
      if (doc.exitFullscreen) {
        doc.exitFullscreen().catch((err: any) => console.error(err));
      } else if (doc.webkitExitFullscreen) {
        doc.webkitExitFullscreen();
      } else if (doc.mozCancelFullScreen) {
        doc.mozCancelFullScreen();
      } else if (doc.msExitFullscreen) {
        doc.msExitFullscreen();
      }
    }
  }

  toggleInvioDatiStatistici() {
    const newValue = !this.invioDatiStatistici();
    this.invioDatiStatistici.set(newValue);
    localStorage.setItem('invio-dati-statistici', newValue.toString());
  }

  toggleShowTagsInList() {
    const newValue = !this.showTagsInList();
    this.showTagsInList.set(newValue);
    localStorage.setItem('show-tags-in-list', newValue.toString());
  }

  toggleShowUpdateDate() {
    const newValue = !this.showUpdateDate();
    this.showUpdateDate.set(newValue);
    localStorage.setItem('show-update-date', newValue.toString());
  }

  toggleStandardAutoscroll() {
    const newValue = !this.enableStandardAutoscroll();
    this.enableStandardAutoscroll.set(newValue);
    localStorage.setItem('enable-standard-autoscroll', newValue.toString());
  }

  toggleVisualAutoscroll() {
    const newValue = !this.enableVisualAutoscroll();
    this.enableVisualAutoscroll.set(newValue);
    localStorage.setItem('enable-visual-autoscroll', newValue.toString());
  }

  toggleKaraokePageScrollMode() {
    const newValue = !this.karaokePageScrollMode();
    this.karaokePageScrollMode.set(newValue);
    localStorage.setItem('karaoke-page-scroll-mode', newValue.toString());
  }

  toggleLandscapeProjectionEnabled() {
    const newValue = !this.landscapeProjectionEnabled();
    this.landscapeProjectionEnabled.set(newValue);
    localStorage.setItem('landscape-projection-enabled', newValue.toString());
  }

  setChordNotationPreference(val: 'diesis' | 'bemolle') {
    this.chordNotationPreference.set(val);
  }

  setUserUuid(uuid: string) {
    const trimmed = uuid.trim();
    if (trimmed) {
      this.userUuid.set(trimmed);
      localStorage.setItem('user-uuid', trimmed);
    }
  }

  setUserName(name: string) {
    const trimmed = name.trim();
    this.userName.set(trimmed);
    localStorage.setItem('user-name', trimmed);
  }

  async installPwa() {
    const promptEvent = this.deferredPrompt();
    if (!promptEvent) {
      return;
    }
    // Show the install prompt
    promptEvent.prompt();
    // Wait for the user to respond to the prompt
    const { outcome } = await promptEvent.userChoice;
    console.log(`User response to the install prompt: ${outcome}`);
    // We've used the prompt, and can't use it again, discard it
    this.deferredPrompt.set(null);
    this.showInstallButton.set(false);
  }
}
