import * as SecureStore from 'expo-secure-store';

const URL_KEY = 'goon.backend_url';
const API_KEY = 'goon.api_key';
const DEVICE_KEY = 'goon.device_id';

// Stabilne ID instalacji — scope'uje stan usera (favorites/progress/blacklisty) na
// serwerze per urządzenie (bug 2026-06-08: stan był globalny, nowi userzy nadpisywali
// ulubione). Generowane raz, trzymane w SecureStore (przeżywa restart, NIE reinstalację).
let _deviceIdCache: string | null = null;

function _genDeviceId(): string {
  // 32 hex chars — wystarczająco unikalne dla ID instalacji (nie security-critical).
  let s = '';
  for (let i = 0; i < 32; i++) s += Math.floor(Math.random() * 16).toString(16);
  return s;
}

export async function getDeviceId(): Promise<string> {
  if (_deviceIdCache) return _deviceIdCache;
  let id = await SecureStore.getItemAsync(DEVICE_KEY);
  if (!id) {
    id = _genDeviceId();
    await SecureStore.setItemAsync(DEVICE_KEY, id);
  }
  _deviceIdCache = id;
  return id;
}

// Jednorazowe przejęcie legacy stanu (sprzed device-scopingu) — flaga per instalacja.
const LEGACY_ADOPTED_KEY = 'goon.legacy_adopted';

export async function isLegacyAdopted(): Promise<boolean> {
  return (await SecureStore.getItemAsync(LEGACY_ADOPTED_KEY)) === '1';
}

export async function markLegacyAdopted(): Promise<void> {
  await SecureStore.setItemAsync(LEGACY_ADOPTED_KEY, '1');
}

// "What's new" — ostatnio widziany wpis changelogu. Po dociągnięciu OTA bundle ma
// nowszy changelog → WhatsNewModal pokazuje różnicę i zapisuje najnowszy id.
const CHANGELOG_SEEN_KEY = 'goon.changelog_seen_id';

export async function getLastSeenChangelog(): Promise<string | null> {
  return SecureStore.getItemAsync(CHANGELOG_SEEN_KEY);
}

export async function setLastSeenChangelog(id: string): Promise<void> {
  await SecureStore.setItemAsync(CHANGELOG_SEEN_KEY, id);
}

// Onboarding/tutorial — pokazany raz przy pierwszym odpaleniu (carousel: tabs,
// funkcje, longpressy, gesty playera). Wersjonowany klucz → bump gdy tutorial
// istotnie się zmieni i chcemy pokazać ponownie. Replay z ustawień przez bus.
const ONBOARDING_SEEN_KEY = 'goon.onboarding_seen_v1';

export async function getOnboardingSeen(): Promise<boolean> {
  try {
    return (await SecureStore.getItemAsync(ONBOARDING_SEEN_KEY)) === '1';
  } catch {
    return true; // brak SecureStore → nie blokuj UI tutorialem w kółko
  }
}

export async function setOnboardingSeen(seen: boolean): Promise<void> {
  try {
    if (seen) await SecureStore.setItemAsync(ONBOARDING_SEEN_KEY, '1');
    else await SecureStore.deleteItemAsync(ONBOARDING_SEEN_KEY);
  } catch {
    // ignore — keychain quirks
  }
}

// Liczba kolumn w siatkach scen (1/2/3). Feedback mobilism: domyślne 2 kol = za małe
// miniaturki na telefonie do rozpoznania performera. Default 2 (tablet-friendly).
const GRID_COLS_KEY = 'goon.grid_columns';

export async function getGridColumns(): Promise<number> {
  const v = await SecureStore.getItemAsync(GRID_COLS_KEY);
  const n = v ? parseInt(v, 10) : 2;
  return n === 1 || n === 2 || n === 3 ? n : 2;
}

export async function setGridColumns(n: number): Promise<void> {
  await SecureStore.setItemAsync(GRID_COLS_KEY, String(n));
}

// Domyślna jakość odtwarzania (user-request: mniej klików). Gdy resolve zwróci kilka
// jakości i jest dopasowanie do tej wartości, apka pomija picker i gra od razu. 'auto'
// = zawsze pokaż picker (stare zachowanie). 'lowest' = najniższa dostępna.
export type DefaultQuality = 'auto' | 2160 | 1080 | 720 | 480 | 'lowest';
const DEFAULT_QUALITY_KEY = 'goon.default_quality';

export async function getDefaultQuality(): Promise<DefaultQuality> {
  const v = await SecureStore.getItemAsync(DEFAULT_QUALITY_KEY);
  if (!v) return 'auto';
  if (v === 'auto' || v === 'lowest') return v;
  const n = parseInt(v, 10);
  return n === 2160 || n === 1080 || n === 720 || n === 480 ? (n as DefaultQuality) : 'auto';
}

export async function setDefaultQuality(v: DefaultQuality): Promise<void> {
  await SecureStore.setItemAsync(DEFAULT_QUALITY_KEY, String(v));
}

export interface Credentials {
  baseUrl: string;
  apiKey: string;
}

export async function loadCredentials(): Promise<Credentials | null> {
  const baseUrl = await SecureStore.getItemAsync(URL_KEY);
  const apiKey = await SecureStore.getItemAsync(API_KEY);
  if (!baseUrl || !apiKey) return null;
  return { baseUrl, apiKey };
}

export async function saveCredentials(c: Credentials): Promise<void> {
  await SecureStore.setItemAsync(URL_KEY, c.baseUrl);
  await SecureStore.setItemAsync(API_KEY, c.apiKey);
}

export async function clearCredentials(): Promise<void> {
  await SecureStore.deleteItemAsync(URL_KEY);
  await SecureStore.deleteItemAsync(API_KEY);
}
