import { describe, expect, test, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent } from '@testing-library/svelte';

vi.mock('$lib/api/listenbrainz', () => {
  // Mocks must look like a Svelte readable store. The page reads e.g.
  // $status.isPending, which is shorthand for "subscribe to status,
  // then read .isPending on the emitted value." Returning an object
  // that ALSO carries isPending/etc. as bare properties (without a
  // working subscribe) makes $status resolve to undefined.
  const stub = <T extends Record<string, unknown>>(value: T) => ({
    subscribe: (run: (v: T) => void) => {
      run(value);
      return () => {};
    }
  });
  return {
    createLBStatusQuery: () =>
      stub({
        isPending: false,
        isError: false,
        data: { token_set: false, enabled: false }
      }),
    createTokenMutation: () => stub({ mutate: vi.fn(), isPending: false }),
    createEnabledMutation: () => stub({ mutate: vi.fn(), isPending: false })
  };
});

vi.mock('$lib/api/metrics', () => ({
  createRecommendationMetricsQuery: () => ({
    subscribe: (run: (v: unknown) => void) => {
      run({ isPending: false, isError: false, data: { window_days: 30, baseline: null, groups: [] } });
      return () => {};
    }
  })
}));

beforeEach(() => {
  globalThis.localStorage.clear();
  document.documentElement.removeAttribute('data-theme');
});

import SettingsPage from './+page.svelte';

describe('Settings → Appearance', () => {
  test('renders three theme options', () => {
    render(SettingsPage);
    expect(screen.getByText(/^Appearance$/)).toBeInTheDocument();
    expect(screen.getByLabelText('dark', { exact: false })).toBeInTheDocument();
    expect(screen.getByLabelText('light', { exact: false })).toBeInTheDocument();
    expect(screen.getByLabelText('system', { exact: false })).toBeInTheDocument();
  });

  test('clicking light writes localStorage and sets data-theme', async () => {
    render(SettingsPage);
    const lightRadio = screen.getByLabelText('light', { exact: false }) as HTMLInputElement;
    await fireEvent.click(lightRadio);
    expect(localStorage.getItem('minstrel:theme')).toBe('light');
    expect(document.documentElement.getAttribute('data-theme')).toBe('light');
  });

  test('clicking dark writes localStorage and sets data-theme', async () => {
    render(SettingsPage);
    const darkRadio = screen.getByLabelText('dark', { exact: false }) as HTMLInputElement;
    await fireEvent.click(darkRadio);
    expect(localStorage.getItem('minstrel:theme')).toBe('dark');
    expect(document.documentElement.getAttribute('data-theme')).toBe('dark');
  });
});
