import { expect, test } from '@playwright/test'

const routes = [
  '/app/dashboard',
  '/app/discover',
  '/app/games',
  '/app/movies',
  '/app/shows',
  '/app/watch-later',
  '/app/watched',
  '/app/downloads',
  '/app/calendar',
  '/app/recommendations',
  '/app/library',
  '/app/collections',
  '/app/settings',
  '/app/admin',
]

const routeTestIds = new Map<string, string>([
  ['/app/dashboard', 'dashboard-page'],
  ['/app/discover', 'discover-page'],
  ['/app/games', 'games-page'],
  ['/app/movies', 'movies-page'],
  ['/app/shows', 'shows-page'],
  ['/app/watch-later', 'watch-later-page'],
  ['/app/watched', 'watched-page'],
  ['/app/downloads', 'downloads-page'],
  ['/app/calendar', 'calendar-page'],
  ['/app/recommendations', 'recommendations-page'],
  ['/app/library', 'library-page'],
  ['/app/collections', 'collections-page'],
  ['/app/settings', 'settings-page'],
  ['/app/admin', 'admin-page'],
])

const authenticate = async (page: import('@playwright/test').Page): Promise<void> => {
  await page.goto('/login', { waitUntil: 'domcontentloaded' })
  await page.getByLabel('Email').fill('demo@seen.local')
  await page.getByLabel('Password').fill('password123')
  await page.getByRole('button', { name: /Sign In to Dashboard/i }).click()
  await expect(page).toHaveURL(/\/app\/dashboard$/)
}

test('loads dashboard with widgets', async ({ page }) => {
  await authenticate(page)

  await expect(page.getByTestId('dashboard-page')).toBeVisible()
  await expect(page.getByText('WELCOME', { exact: false })).toBeVisible()
  await expect(page.getByText('CONTINUE', { exact: true })).toBeVisible()
  await expect(page.getByText('RECOMMENDED', { exact: true })).toBeVisible()
})

test('theme mode persists after refresh', async ({ page }) => {
  await page.goto('/login', { waitUntil: 'domcontentloaded' })
  await page.getByRole('button', { name: 'Light', exact: true }).click()
  await expect(page.locator('html')).toHaveAttribute('data-theme', 'light')
  await expect.poll(async () => page.evaluate(() => localStorage.getItem('seen-theme-mode'))).toBe('light')

  await page.getByLabel('Email').fill('demo@seen.local')
  await page.getByLabel('Password').fill('password123')
  await page.getByRole('button', { name: /Sign In to Dashboard/i }).click()
  await expect(page).toHaveURL(/\/app\/dashboard$/)
  await expect(page.locator('html')).toHaveAttribute('data-theme', 'light')

  await page.reload({ waitUntil: 'domcontentloaded' })
  await expect(page).toHaveURL(/\/app\/dashboard$/)
  await expect.poll(async () => page.evaluate(() => localStorage.getItem('seen-theme-mode'))).toBe('light')
})

test('sidebar routes navigate without crashes', async ({ page }) => {
  await authenticate(page)

  await expect(page.getByTestId('dashboard-page')).toBeVisible()

  for (const route of routes.slice(1)) {
    const testId = routeTestIds.get(route)!

    await page.evaluate((targetRoute) => {
      window.history.pushState({}, '', targetRoute)
      window.dispatchEvent(new PopStateEvent('popstate'))
    }, route)
    await expect(page).toHaveURL(new RegExp(`${route}$`))
    await page.getByTestId(testId).waitFor({ state: 'visible', timeout: 15_000 })
  }
})

test('dashboard transitions from loading skeletons to content', async ({ page }) => {
  await authenticate(page)

  await expect(page.getByTestId('skeleton').first()).toBeVisible()
  await expect(page.getByText('WELCOME', { exact: false })).toBeVisible()
  await expect(page.getByTestId('skeleton').first()).not.toBeVisible()
})

test('discover search and filters update displayed results', async ({ page }) => {
  await authenticate(page)
  await page.locator('[data-route="/app/discover"]').first().click()
  await expect(page).toHaveURL(/\/app\/discover$/)

  await page.getByLabel('Discover search').fill('zero')
  const searchResults = page.getByTestId('discover-search-results')

  await expect(searchResults).toBeVisible()
  await expect(searchResults.getByText('Searching…')).toBeVisible()
  await expect(searchResults.getByText('Searching…')).not.toBeVisible()
  await expect(searchResults.getByText('Zero Meridian')).toBeVisible()

  await page.getByRole('button', { name: 'Clear', exact: true }).click()
  await page.getByRole('button', { name: 'Sci-Fi', exact: true }).click()
  await expect(page.getByText('Trending · Sci-Fi')).toBeVisible()

  await page.getByRole('button', { name: 'All', exact: true }).click()

  const loadMoreButton = page.getByRole('button', { name: 'Load More' })
  await expect(loadMoreButton).toBeEnabled()

  const firstLoadCount = await page.locator('article').count()
  await loadMoreButton.click()
  await expect
    .poll(async () => {
      const nextCount = await page.locator('article').count()
      return nextCount
    })
    .toBeGreaterThan(firstLoadCount)
})
