/**
 * useWorkspaceId Hook Tests
 * Tests for SEC-WEB-35: warning logging when workspace ID is not found
 */

import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { renderHook } from "@testing-library/react";
import { useWorkspaceId } from "./useLayout";

interface MockLocalStorage {
  getItem: ReturnType<typeof vi.fn>;
  setItem: ReturnType<typeof vi.fn>;
  removeItem: ReturnType<typeof vi.fn>;
  clear: ReturnType<typeof vi.fn>;
  readonly length: number;
  key: ReturnType<typeof vi.fn>;
}

// Mock localStorage
const localStorageMock = ((): MockLocalStorage => {
  let store: Record<string, string> = {};
  return {
    getItem: vi.fn((key: string): string | null => store[key] ?? null),
    setItem: vi.fn((key: string, value: string): void => {
      store[key] = value;
    }),
    removeItem: vi.fn((key: string): void => {
      store = Object.fromEntries(Object.entries(store).filter(([k]) => k !== key));
    }),
    clear: vi.fn((): void => {
      store = {};
    }),
    get length(): number {
      return Object.keys(store).length;
    },
    key: vi.fn((_index: number): string | null => null),
  };
})();

Object.defineProperty(window, "localStorage", {
  value: localStorageMock,
  writable: true,
});

describe("useWorkspaceId", (): void => {
  let consoleWarnSpy: ReturnType<typeof vi.spyOn>;
  let consoleErrorSpy: ReturnType<typeof vi.spyOn>;

  beforeEach((): void => {
    vi.clearAllMocks();
    localStorageMock.clear();
    consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => undefined);
    consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => undefined);
  });

  afterEach((): void => {
    consoleWarnSpy.mockRestore();
    consoleErrorSpy.mockRestore();
    vi.resetAllMocks();
  });

  it("should return workspace ID when stored in localStorage", (): void => {
    localStorageMock.setItem("mosaic-workspace-id", "ws-123");

    const { result } = renderHook(() => useWorkspaceId());

    expect(result.current).toBe("ws-123");
    expect(consoleWarnSpy).not.toHaveBeenCalled();
  });

  it("should return null and log warning when no workspace ID in localStorage", (): void => {
    const { result } = renderHook(() => useWorkspaceId());

    expect(result.current).toBeNull();
    expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
    expect(consoleWarnSpy).toHaveBeenCalledWith(
      expect.stringContaining("No workspace ID found in localStorage")
    );
  });

  it("should include the storage key in the warning message", (): void => {
    renderHook(() => useWorkspaceId());

    expect(consoleWarnSpy).toHaveBeenCalledWith(expect.stringContaining("mosaic-workspace-id"));
  });

  it("should log console.error when localStorage throws", (): void => {
    localStorageMock.getItem.mockImplementation(() => {
      throw new Error("localStorage is disabled");
    });

    const { result } = renderHook(() => useWorkspaceId());

    expect(result.current).toBeNull();
    expect(consoleErrorSpy).toHaveBeenCalledWith(
      "Failed to load workspace ID from localStorage:",
      expect.any(Error)
    );
  });

  it("should not log warning when workspace ID exists", (): void => {
    localStorageMock.setItem("mosaic-workspace-id", "ws-abc-def");

    renderHook(() => useWorkspaceId());

    expect(consoleWarnSpy).not.toHaveBeenCalled();
    expect(consoleErrorSpy).not.toHaveBeenCalled();
  });
});
