"use strict";

import { Platform } from 'react-native';
import { APP_COLOR_NAMES } from "./color-presets.js";
const VALID_PRESETS = new Set(APP_COLOR_NAMES);
const VALID_MODES = new Set(['light', 'dark', 'system', 'adaptive']);

/**
 * Storage adapter for persisting Bloom theme state.
 *
 * Methods may be synchronous or asynchronous. The provider awaits both, so
 * `AsyncStorage`-compatible adapters on native and `localStorage`-backed
 * adapters on web both work without consumer-side branching.
 *
 * On web, a synchronous adapter lets Bloom hydrate before the first paint —
 * preventing a flash of the default palette. On native, the provider can
 * gate `children` rendering until hydration completes (see
 * `awaitHydration` on `BloomThemeProvider`).
 */

const isValidMode = value => typeof value === 'string' && VALID_MODES.has(value);
const isValidPreset = value => typeof value === 'string' && VALID_PRESETS.has(value);
function parsePersistedTheme(raw) {
  if (typeof raw !== 'string') return null;
  let parsed;
  try {
    parsed = JSON.parse(raw);
  } catch {
    return null;
  }
  if (!parsed || typeof parsed !== 'object') return null;
  const obj = parsed;
  const mode = isValidMode(obj.mode) ? obj.mode : undefined;
  const colorPreset = isValidPreset(obj.colorPreset) ? obj.colorPreset : undefined;
  if (!mode && !colorPreset) return null;
  return {
    mode,
    colorPreset
  };
}
const isThenable = value => !!value && typeof value.then === 'function';

/**
 * Read persisted state during the first render. Returns a discriminated union
 * so the provider can tell apart:
 *   - `none`: persistence not configured.
 *   - `sync`: adapter returned a value synchronously (web `localStorage`).
 *     Provider can render immediately with the resolved state.
 *   - `async`: adapter returned a Promise (native `AsyncStorage`). Provider
 *     must await `readPersistedTheme` before painting if gating is enabled.
 */
export function readPersistedThemeSync(persistKey, storage) {
  if (!persistKey || !storage) return {
    kind: 'none'
  };
  let raw;
  try {
    raw = storage.getItem(persistKey);
  } catch {
    return {
      kind: 'sync',
      state: null
    };
  }
  if (isThenable(raw)) return {
    kind: 'async'
  };
  return {
    kind: 'sync',
    state: parsePersistedTheme(raw)
  };
}
export async function readPersistedTheme(persistKey, storage) {
  if (!persistKey || !storage) return null;
  try {
    const raw = await storage.getItem(persistKey);
    return parsePersistedTheme(raw);
  } catch {
    return null;
  }
}
export async function writePersistedTheme(persistKey, storage, state) {
  if (!persistKey || !storage) return;
  const payload = {};
  if (state.mode !== undefined) payload.mode = state.mode;
  if (state.colorPreset !== undefined) payload.colorPreset = state.colorPreset;
  try {
    await storage.setItem(persistKey, JSON.stringify(payload));
  } catch {
    // Persistence is best-effort: ignore quota and privacy-mode errors.
  }
}
export async function removePersistedTheme(persistKey, storage) {
  if (!persistKey || !storage) return;
  try {
    if (typeof storage.removeItem === 'function') {
      await storage.removeItem(persistKey);
      return;
    }
    await storage.setItem(persistKey, '');
  } catch {
    // Best-effort cleanup.
  }
}

/**
 * `localStorage`-backed storage adapter. Only defined on web; on native the
 * export is `undefined` so consumers pass an `AsyncStorage` adapter explicitly.
 */
export const webLocalStorage = (() => {
  if (Platform.OS !== 'web') return undefined;
  if (typeof globalThis === 'undefined') return undefined;
  if (!('localStorage' in globalThis)) return undefined;
  const ls = globalThis.localStorage;
  return {
    getItem: key => {
      try {
        return ls.getItem(key);
      } catch {
        return null;
      }
    },
    setItem: (key, value) => {
      try {
        ls.setItem(key, value);
      } catch {
        // Swallow quota / privacy-mode errors.
      }
    },
    removeItem: key => {
      try {
        ls.removeItem(key);
      } catch {
        // Swallow privacy-mode errors.
      }
    }
  };
})();
//# sourceMappingURL=persistence.js.map