/**
 * The Fayda round trip leaves the app entirely, so the little state that has to
 * survive it lives in sessionStorage: same tab, same origin, gone when the tab
 * closes.
 *
 * Nothing secret is kept here. The `transactionToken` is signed by the API and
 * useless without it — the PKCE verifier, the nonce and the client key never
 * leave the backend.
 */

const REQUEST_KEY = 'fayda:request';
const RESULT_KEY = 'fayda:result';

export interface FaydaRequest {
  transactionToken: string;
  state: string;
}

export interface FaydaPrefill {
  email?: string;
  phoneNumber?: string;
  nameEn?: string;
  nameAm?: string;
  /** Shown for context only — the signup form has no field for these. */
  gender?: string;
  address?: string;
  birthdate?: string;
  nationality?: string;
  faydaNumber?: string;
}

/** Shape of `POST /auth/register-with-fayda` with `action: "verify"`. */
export interface FaydaResult {
  identity: FaydaPrefill;
  faydaVerified: boolean;
  /** Signup fields Fayda vouched for. */
  verifiedFields: string[];
  /** Prefilled fields already taken by another account. */
  conflicts: string[];
  /**
   * Encrypted proof of the verification, presented to POST /profiles/me/fayda
   * after signup so the account and profile record what Fayda vouched for.
   */
  verificationToken: string;
}

// Private browsing and locked-down browsers can throw on access, and a failure
// here should degrade to "no Fayda prefill", never break the signup page.
function read<T>(key: string): T | null {
  try {
    const raw = sessionStorage.getItem(key);
    return raw ? (JSON.parse(raw) as T) : null;
  } catch {
    return null;
  }
}

function write(key: string, value: unknown): void {
  try {
    sessionStorage.setItem(key, JSON.stringify(value));
  } catch {
    /* nothing to do — the flow reports a generic failure instead */
  }
}

function clear(key: string): void {
  try {
    sessionStorage.removeItem(key);
  } catch {
    /* ignore */
  }
}

export const faydaSession = {
  saveRequest: (request: FaydaRequest) => write(REQUEST_KEY, request),
  takeRequest: (): FaydaRequest | null => {
    const request = read<FaydaRequest>(REQUEST_KEY);
    // Single use: a stale token would otherwise be replayed against a fresh
    // callback and fail with a confusing "session expired".
    clear(REQUEST_KEY);
    return request;
  },

  saveResult: (result: FaydaResult) => write(RESULT_KEY, result),
  peekResult: (): FaydaResult | null => read<FaydaResult>(RESULT_KEY),
  clearResult: () => clear(RESULT_KEY),
};
