import { expect, test, type Page } from '@playwright/test'
import { gotoAppRoute } from './helpers/navigation'
import { expectNoHorizontalOverflow } from './helpers/layout'

type PublicRouteExpectation = {
  path: string
  heading: string
  cta?: string
}

const responsivePublicRoutes: readonly PublicRouteExpectation[] = [
  {
    path: '/',
    heading: 'One serious home for classic cubes, 120‑cell, 5D, and deep daily practice.',
    cta: 'Create account',
  },
  {
    path: '/features',
    heading: 'A deep training toolkit, not just a timer.',
  },
  {
    path: '/about',
    heading: 'A training stack built for people who want more than a timer.',
  },
  {
    path: '/resources',
    heading: 'Every guide you need to start, train, and grow with HyperTwist.',
  },
  {
    path: '/docs',
    heading: 'The complete HyperTwist manual.',
  },
  {
    path: '/pricing',
    heading: 'Pricing that matches the actual delivery model.',
  },
  {
    path: '/download',
    heading: 'Download the desktop build and pair it with your browser account.',
  },
  {
    path: '/getting-started',
    heading: 'Start on the website. Train in the desktop app.',
  },
  {
    path: '/launch-status',
    heading: 'See how public pages, account access, and desktop delivery work together.',
  },
  {
    path: '/support',
    heading: 'Help for access, downloads, setup, and launch.',
  },
  {
    path: '/login',
    heading: 'Log in to HyperTwist',
    cta: 'Log in',
  },
  {
    path: '/changelog',
    heading: 'Release notes for players, teams, and studios.',
  },
  {
    path: '/open-source-notices',
    heading: 'Open-source notices for public distribution surfaces.',
  },
  {
    path: '/privacy',
    heading: 'Privacy model',
  },
  {
    path: '/terms',
    heading: 'Terms of access',
  },
  {
    path: '/shipping-payment',
    heading: 'Digital delivery only',
  },
  {
    path: '/register',
    heading: 'Create a HyperTwist account',
    cta: 'Create account',
  },
] as const

async function assertResponsivePublicRoute(page: Page, route: PublicRouteExpectation) {
  await gotoAppRoute(page, route.path, { waitUntil: 'domcontentloaded', timeoutMs: 45_000 })

  await expect(page.getByRole('heading', { level: 1, name: route.heading })).toBeVisible()
  if (route.cta) {
    const button = page.getByRole('button', { name: route.cta })
    if ((await button.count()) > 0) {
      await expect(button.first()).toBeVisible()
    } else {
      await expect(page.getByRole('link', { name: route.cta }).first()).toBeVisible()
    }
  }

  if (route.path === '/login' || route.path === '/register') {
    await expectAuthShellAboveBackdrop(page)
  }

  await expectNoHorizontalOverflow(page)
}

async function expectAuthShellAboveBackdrop(page: Page) {
  await expect(page.locator('#hypertwist-auth-shell-backdrop')).toHaveCount(1)

  const stacking = await page.evaluate(() => {
    const backdrop = document.getElementById('hypertwist-auth-shell-backdrop')
    const shell = document.querySelector('.auth-shell')
    if (!(backdrop instanceof HTMLElement) || !(shell instanceof HTMLElement)) {
      return null
    }

    const backdropStyle = window.getComputedStyle(backdrop)
    const shellStyle = window.getComputedStyle(shell)

    return {
      backdropPointerEvents: backdropStyle.pointerEvents,
      backdropZIndex: backdropStyle.zIndex,
      shellIsolation: shellStyle.isolation,
      shellPosition: shellStyle.position,
      shellZIndex: shellStyle.zIndex,
    }
  })

  expect(stacking).toEqual({
    backdropPointerEvents: 'none',
    backdropZIndex: '0',
    shellIsolation: 'isolate',
    shellPosition: 'relative',
    shellZIndex: '1',
  })
}

test.describe('responsive public routes (mobile)', () => {
  test.use({ viewport: { width: 390, height: 844 } })

  for (const route of responsivePublicRoutes) {
    test(`${route.path} renders without horizontal overflow`, async ({ page }) => {
      await assertResponsivePublicRoute(page, route)
    })
  }
})

test.describe('responsive public routes (tablet)', () => {
  test.use({ viewport: { width: 820, height: 1180 } })

  for (const route of responsivePublicRoutes) {
    test(`${route.path} renders without horizontal overflow`, async ({ page }) => {
      await assertResponsivePublicRoute(page, route)
    })
  }
})
