/** Failure-contained session persistence with no dependency on browser globals. */

import { decodeJourneySnapshot, encodeJourneySnapshot } from "./state.ts";
import type {
  JourneySessionClearResult,
  JourneySessionLoadResult,
  JourneySessionSaveResult,
  JourneyState,
  JourneyStorageAdapter,
} from "./types.ts";

function validKey(key: string): boolean {
  return typeof key === "string" && key.trim().length > 0;
}

export function saveJourneySession(
  storage: JourneyStorageAdapter,
  key: string,
  state: JourneyState,
): JourneySessionSaveResult {
  if (!validKey(key)) return { ok: false, error: "journey: session key is empty" };
  let encoded: string;
  try {
    encoded = encodeJourneySnapshot(state);
  } catch (error) {
    return {
      ok: false,
      error: error instanceof Error ? error.message : "journey: snapshot encoding failed",
    };
  }
  try {
    storage.setItem(key, encoded);
    return { ok: true };
  } catch {
    return { ok: false, error: "journey: session storage is unavailable" };
  }
}

export function loadJourneySession(
  storage: JourneyStorageAdapter,
  key: string,
): JourneySessionLoadResult {
  if (!validKey(key)) return { status: "invalid", error: "journey: session key is empty" };
  let encoded: string | null;
  try {
    encoded = storage.getItem(key);
  } catch {
    return { status: "unavailable", error: "journey: session storage is unavailable" };
  }
  if (encoded === null) return { status: "missing" };
  const decoded = decodeJourneySnapshot(encoded);
  if (!decoded.ok) return { status: "invalid", error: decoded.error };
  return { status: "loaded", state: decoded.state };
}

export function clearJourneySession(
  storage: JourneyStorageAdapter,
  key: string,
): JourneySessionClearResult {
  if (!validKey(key)) return { ok: false, error: "journey: session key is empty" };
  try {
    storage.removeItem(key);
    return { ok: true };
  } catch {
    return { ok: false, error: "journey: session storage is unavailable" };
  }
}
