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>(false);

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

  /** Browser Fullscreen state: true = fullscreen active */
  public browserFullscreen = signal<boolean>(
    !!(
      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>(false);

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

  /** 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>(false);

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

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

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

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

  constructor() {
    // 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
      );
    } 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');
    });
    const savedChords = localStorage.getItem('show-chords-default');
    if (savedChords !== null) {
      this.showChordsDefault.set(savedChords === 'true');
    }

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

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

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

    const savedKeepScreenOn = localStorage.getItem('keep-screen-on');
    if (savedKeepScreenOn !== null) {
      this.keepScreenOn.set(savedKeepScreenOn === 'true');
    }

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

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

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

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

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

    const savedAcousticAutoscroll = localStorage.getItem('enable-acoustic-autoscroll');
    if (savedAcousticAutoscroll !== null) {
      this.enableAcousticAutoscroll.set(savedAcousticAutoscroll === '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());
      
      const isFs = !!(
        document.fullscreenElement ||
        (document as any).webkitFullscreenElement ||
        (document as any).mozFullScreenElement ||
        (document as any).msFullscreenElement
      );
      
      if (mode && !isFs) {
        const docEl = document.documentElement as any;
        if (docEl.requestFullscreen) {
          docEl.requestFullscreen().catch((err: any) => console.log('Request fs ignored', err));
        } else if (docEl.webkitRequestFullscreen) {
          docEl.webkitRequestFullscreen();
        }
      } else if (!mode && isFs) {
        const doc = document as any;
        if (doc.exitFullscreen) {
          doc.exitFullscreen().catch((err: any) => console.log('Exit fs ignored', err));
        } else if (doc.webkitExitFullscreen) {
          doc.webkitExitFullscreen();
        }
      }
    });

    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-acoustic-autoscroll', this.enableAcousticAutoscroll().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());
  }

  toggleKeepScreenOn() {
    this.keepScreenOn.update(v => !v);
  }

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

  toggleAcousticAutoscroll() {
    const newValue = !this.enableAcousticAutoscroll();
    this.enableAcousticAutoscroll.set(newValue);
    localStorage.setItem('enable-acoustic-autoscroll', newValue.toString());
  }

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