import { Injectable, inject, signal } from '@angular/core';
import { ExperimentalVlcRuntimeService } from '../../infrastructure/services/experimental-vlc-runtime.service';

const STORAGE_KEY_EXPERIMENTAL_MEDIA_SETTINGS = 'metoyou_experimental_media_settings';

export interface ExperimentalMediaSettings {
  vlcJsPlaybackEnabled: boolean;
}

const DEFAULT_EXPERIMENTAL_MEDIA_SETTINGS: ExperimentalMediaSettings = {
  vlcJsPlaybackEnabled: false
};

@Injectable({ providedIn: 'root' })
export class ExperimentalMediaSettingsService {
  private readonly vlcRuntime = inject(ExperimentalVlcRuntimeService);
  private readonly storedSettings = loadExperimentalMediaSettings();

  readonly vlcJsPlaybackEnabled = signal(false);
  readonly vlcJsRuntimeAvailable = signal(false);
  readonly vlcJsRuntimeStatus = signal<'checking' | 'available' | 'missing'>('checking');

  constructor() {
    void this.refreshVlcRuntimeStatus();
  }

  setVlcJsPlaybackEnabled(enabled: boolean): void {
    if (enabled && !this.vlcJsRuntimeAvailable()) {
      this.vlcJsPlaybackEnabled.set(false);
      saveExperimentalMediaSettings({ vlcJsPlaybackEnabled: false });
      return;
    }

    const settings = saveExperimentalMediaSettings({
      vlcJsPlaybackEnabled: enabled
    });

    this.vlcJsPlaybackEnabled.set(settings.vlcJsPlaybackEnabled);
  }

  async refreshVlcRuntimeStatus(): Promise<void> {
    this.vlcJsRuntimeStatus.set('checking');

    const available = await this.vlcRuntime.hasBundledRuntime();

    this.vlcJsRuntimeAvailable.set(available);
    this.vlcJsRuntimeStatus.set(available ? 'available' : 'missing');
    this.vlcJsPlaybackEnabled.set(available && this.storedSettings.vlcJsPlaybackEnabled);

    if (!available && this.storedSettings.vlcJsPlaybackEnabled) {
      saveExperimentalMediaSettings({ vlcJsPlaybackEnabled: false });
    }
  }
}

function loadExperimentalMediaSettings(): ExperimentalMediaSettings {
  try {
    const raw = localStorage.getItem(STORAGE_KEY_EXPERIMENTAL_MEDIA_SETTINGS);

    if (!raw) {
      return { ...DEFAULT_EXPERIMENTAL_MEDIA_SETTINGS };
    }

    return normaliseExperimentalMediaSettings(JSON.parse(raw) as Partial<ExperimentalMediaSettings>);
  } catch {
    return { ...DEFAULT_EXPERIMENTAL_MEDIA_SETTINGS };
  }
}

function saveExperimentalMediaSettings(patch: Partial<ExperimentalMediaSettings>): ExperimentalMediaSettings {
  const nextSettings = normaliseExperimentalMediaSettings({
    ...loadExperimentalMediaSettings(),
    ...patch
  });

  try {
    localStorage.setItem(STORAGE_KEY_EXPERIMENTAL_MEDIA_SETTINGS, JSON.stringify(nextSettings));
  } catch {}

  return nextSettings;
}

function normaliseExperimentalMediaSettings(raw: Partial<ExperimentalMediaSettings>): ExperimentalMediaSettings {
  return {
    vlcJsPlaybackEnabled: typeof raw.vlcJsPlaybackEnabled === 'boolean'
      ? raw.vlcJsPlaybackEnabled
      : DEFAULT_EXPERIMENTAL_MEDIA_SETTINGS.vlcJsPlaybackEnabled
  };
}
