/**
 * test/setup/local-storage.ts — in-memory Web Storage polyfill for the test env.
 *
 * jsdom 29 (the `@vitest-environment jsdom` files) exposes a `localStorage`
 * object whose Storage methods (getItem/setItem/clear/…) are `undefined` under
 * this vitest config — so any test that calls `localStorage.clear()` throws
 * "localStorage.clear is not a function". This registered setupFile installs a
 * spec-compliant in-memory Storage whenever the ambient one is missing or
 * non-functional, so frontend unit tests (quick-reply, push, projects-panel)
 * get real persistence semantics. It is a no-op if a working Storage already
 * exists, and harmless in the node environment (just adds an unused global).
 */

class MemoryStorage implements Storage {
  private store = new Map<string, string>()

  get length(): number {
    return this.store.size
  }

  clear(): void {
    this.store.clear()
  }

  getItem(key: string): string | null {
    return this.store.has(key) ? (this.store.get(key) as string) : null
  }

  setItem(key: string, value: string): void {
    this.store.set(String(key), String(value))
  }

  removeItem(key: string): void {
    this.store.delete(key)
  }

  key(index: number): string | null {
    return Array.from(this.store.keys())[index] ?? null
  }
}

/** True when `s` is a usable Storage (has a callable `clear`). */
function isUsableStorage(s: unknown): s is Storage {
  return s != null && typeof (s as Storage).clear === 'function'
}

/** Install an in-memory Storage on `target[name]` unless a working one exists. */
function ensureStorage(target: Record<string, unknown>, name: string): void {
  if (isUsableStorage(target[name])) return
  Object.defineProperty(target, name, {
    value: new MemoryStorage(),
    configurable: true,
    writable: true,
  })
}

const globalTarget = globalThis as unknown as Record<string, unknown>
ensureStorage(globalTarget, 'localStorage')
ensureStorage(globalTarget, 'sessionStorage')

// Mirror onto `window` (jsdom env) so `window.localStorage` resolves too.
const win = (globalThis as { window?: Record<string, unknown> }).window
if (win) {
  ensureStorage(win, 'localStorage')
  ensureStorage(win, 'sessionStorage')
}
