import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';

function getStoreValue<T>(store: { subscribe: (run: (value: T) => void) => () => void }): T {
  let value!: T;
  const unsubscribe = store.subscribe((current) => {
    value = current;
  });
  unsubscribe();
  return value;
}

describe('layout store', () => {
  beforeEach(() => {
    vi.resetModules();
    document.documentElement.removeAttribute('data-theme');
    (localStorage.getItem as Mock).mockReturnValue(null);
  });

  it('initializes with default values', async () => {
    const store = await import('../../src/lib/stores/layout');

    expect(getStoreValue(store.sidebarState)).toBe('expanded');
    expect(getStoreValue(store.theme)).toBe('light');
  });

  it('toggleSidebar toggles expanded/collapsed and recovers from hidden', async () => {
    const store = await import('../../src/lib/stores/layout');

    store.setSidebarState('expanded');
    store.toggleSidebar();
    expect(getStoreValue(store.sidebarState)).toBe('collapsed');
    expect(localStorage.setItem).toHaveBeenCalledWith('headroom_sidebar_state', 'collapsed');

    store.toggleSidebar();
    expect(getStoreValue(store.sidebarState)).toBe('expanded');

    store.setSidebarState('hidden');
    store.toggleSidebar();
    expect(getStoreValue(store.sidebarState)).toBe('expanded');
  });

  it('theme toggle works and applies to document', async () => {
    const store = await import('../../src/lib/stores/layout');

    store.setTheme('light');
    store.toggleTheme();
    expect(getStoreValue(store.theme)).toBe('dark');
    expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
    expect(localStorage.setItem).toHaveBeenCalledWith('headroom_theme', 'dark');

    store.toggleTheme();
    expect(getStoreValue(store.theme)).toBe('light');
    expect(document.documentElement.getAttribute('data-theme')).toBe('light');
    expect(localStorage.setItem).toHaveBeenCalledWith('headroom_theme', 'light');
  });
});
