import { describe, expect, test, beforeEach, vi } from 'vitest';

function setupLocalStorage(initial: Record<string, string> = {}) {
  const store: Record<string, string> = { ...initial };
  vi.stubGlobal('localStorage', {
    getItem: (k: string) => (k in store ? store[k] : null),
    setItem: (k: string, v: string) => { store[k] = v; },
    removeItem: (k: string) => { delete store[k]; }
  });
  return store;
}

function setupMatchMedia(prefersLight: boolean) {
  const listeners: ((e: { matches: boolean }) => void)[] = [];
  const mql = {
    matches: prefersLight,
    addEventListener: (_: string, cb: (e: { matches: boolean }) => void) => listeners.push(cb),
    removeEventListener: () => {}
  };
  vi.stubGlobal('window', {
    matchMedia: () => mql
  });
  return {
    mql,
    listeners,
    fire: (matches: boolean) => {
      mql.matches = matches;
      listeners.forEach((cb) => cb({ matches }));
    }
  };
}

beforeEach(() => {
  vi.resetModules();
  vi.unstubAllGlobals();
  if (typeof document !== 'undefined') {
    document.documentElement.removeAttribute('data-theme');
  }
});

describe('theme store', () => {
  test('default preference is system; resolves via matchMedia', async () => {
    setupLocalStorage();
    setupMatchMedia(false); // prefers-dark
    const mod = await import('./theme.svelte');
    expect(mod.theme.value).toBe('system');
    expect(mod.resolvedTheme.value).toBe('dark');
  });

  test('explicit preference from localStorage is honored', async () => {
    setupLocalStorage({ 'minstrel:theme': 'light' });
    setupMatchMedia(false);
    const mod = await import('./theme.svelte');
    expect(mod.theme.value).toBe('light');
    expect(mod.resolvedTheme.value).toBe('light');
  });

  test('setTheme persists, updates resolved, sets data-theme attribute', async () => {
    const store = setupLocalStorage();
    setupMatchMedia(true);
    const mod = await import('./theme.svelte');
    mod.setTheme('dark');
    expect(store['minstrel:theme']).toBe('dark');
    expect(mod.theme.value).toBe('dark');
    expect(mod.resolvedTheme.value).toBe('dark');
    expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
  });

  test('matchMedia change updates resolved while in system mode', async () => {
    setupLocalStorage();
    const mm = setupMatchMedia(false); // prefers-dark
    const mod = await import('./theme.svelte');
    expect(mod.resolvedTheme.value).toBe('dark');
    mm.fire(true); // OS flipped to light
    expect(mod.resolvedTheme.value).toBe('light');
  });

  test('matchMedia change does NOT update resolved when explicit preference set', async () => {
    setupLocalStorage({ 'minstrel:theme': 'dark' });
    const mm = setupMatchMedia(false);
    const mod = await import('./theme.svelte');
    expect(mod.resolvedTheme.value).toBe('dark');
    mm.fire(true); // OS prefers light, but user explicitly chose dark
    expect(mod.resolvedTheme.value).toBe('dark');
  });
});
