import { render, waitFor } from '@solidjs/testing-library'
import { ThemeProvider, THEME_STORAGE_KEY, loadStoredTheme, resolveTheme, useTheme } from '@/stores/theme-store'

const ThemeHarness = () => {
  const theme = useTheme()

  return (
    <div>
      <button type="button" onClick={() => theme.setMode('light')}>
        Set Light
      </button>
      <span data-testid="resolved">{theme.resolved()}</span>
    </div>
  )
}

describe('theme-store', () => {
  beforeEach(() => {
    localStorage.clear()
    document.documentElement.removeAttribute('data-theme')
  })

  it('resolves system mode based on preference', () => {
    expect(resolveTheme('system', true)).toBe('dark')
    expect(resolveTheme('system', false)).toBe('light')
  })

  it('loads persisted mode and falls back to system', () => {
    localStorage.setItem(THEME_STORAGE_KEY, 'dark')
    expect(loadStoredTheme(localStorage)).toBe('dark')

    localStorage.setItem(THEME_STORAGE_KEY, 'invalid')
    expect(loadStoredTheme(localStorage)).toBe('system')
  })

  it('persists explicit mode and updates root dataset', async () => {
    const matchMediaMock = vi.fn().mockImplementation(() => ({
      matches: true,
      addEventListener: vi.fn(),
      removeEventListener: vi.fn(),
    }))

    vi.stubGlobal('matchMedia', matchMediaMock)

    const { getByText, getByTestId } = render(() => (
      <ThemeProvider>
        <ThemeHarness />
      </ThemeProvider>
    ))

    await waitFor(() => {
      expect(document.documentElement.getAttribute('data-theme')).toBe('dark')
      expect(getByTestId('resolved')).toHaveTextContent('dark')
    })

    getByText('Set Light').click()

    await waitFor(() => {
      expect(localStorage.getItem(THEME_STORAGE_KEY)).toBe('light')
      expect(document.documentElement.getAttribute('data-theme')).toBe('light')
      expect(getByTestId('resolved')).toHaveTextContent('light')
    })

    vi.unstubAllGlobals()
  })
})
