import { cleanup, render, screen, waitFor } from '@testing-library/react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter } from 'react-router-dom'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import { ROUTER_FUTURE_FLAGS } from '../router/router-future'

const mockUsePlatformAuth = vi.fn()
const mockGetAuthHealth = vi.fn()
const mockCreateDesktopLinkToken = vi.fn()
const mockBuildAuthApiBaseUrls = vi.fn(() => ['https://hypertwist.app'])
const mockGetReleaseManifest = vi.fn()

vi.mock('../auth/platform-auth', () => ({
  usePlatformAuth: () => mockUsePlatformAuth(),
}))

vi.mock('../auth/auth-api', () => ({
  getAuthHealth: (...args: unknown[]) => mockGetAuthHealth(...args),
  createDesktopLinkToken: (...args: unknown[]) => mockCreateDesktopLinkToken(...args),
  buildAuthApiBaseUrls: () => mockBuildAuthApiBaseUrls(),
  getReleaseManifest: (...args: unknown[]) => mockGetReleaseManifest(...args),
}))

import { AppRouteTree } from '../router/AppRouteTree'

function renderRoute(initialEntry: string) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  })

  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter initialEntries={[initialEntry]} future={ROUTER_FUTURE_FLAGS}>
        <AppRouteTree />
      </MemoryRouter>
    </QueryClientProvider>,
  )
}

describe('AppRouteTree', () => {
  beforeEach(() => {
    cleanup()
    mockUsePlatformAuth.mockReset()
    mockGetAuthHealth.mockReset()
    mockCreateDesktopLinkToken.mockReset()
    mockBuildAuthApiBaseUrls.mockReset()
    mockGetReleaseManifest.mockReset()
    mockBuildAuthApiBaseUrls.mockReturnValue(['https://hypertwist.app'])
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: true,
        apiVersion: '5.0',
        oauth: {
          github: false,
          google: false,
        },
      },
      fallback: {
        enabled: true,
        active: false,
        reason: null,
      },
      billing: {
        statePath: '/tmp/hypertwist-billing.json',
        processedEventCount: 1,
        pricePlanMapConfigured: true,
        productPlanMapConfigured: true,
        webhookSecretConfigured: true,
      },
      runtime: {
        mode: 'public',
        public_origin_ready: true,
        cookie_secure: true,
        api_domain: 'https://hypertwist.app',
        website_domain: 'https://hypertwist.app',
        warnings: [],
        errors: [],
      },
    })
    mockCreateDesktopLinkToken.mockResolvedValue({
      ok: true,
      token: 'desktop-token-123',
      expires_at: '2026-06-22T12:00:00.000Z',
    })
    mockGetReleaseManifest.mockResolvedValue({
      ok: true,
      manifest: {
        generated_at: '2026-06-22T12:00:00.000Z',
        support_email: 'hello@hypertwist.app',
        public_docs_url: 'https://docs.hypertwist.app',
        release_notes_url: 'https://notes.hypertwist.app',
        corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
        open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
        viewer: {
          authenticated: false,
          canDownload: false,
          plan: null,
          role: null,
          accessStatus: null,
        },
        platforms: [
          {
            platform_key: 'windows',
            platform: 'Windows',
            subtitle: 'Primary shipping lane',
            details: 'Current packaged validation is strongest on the Windows Unreal lane.',
            configured: true,
            channel: 'candidate',
            version: '1.0.0',
            build_id: 'win64-1000',
            published_at: '2026-06-22T00:00:00.000Z',
            file_name: 'HyperTwist-Windows.zip',
            file_size_bytes: 1048576,
            checksum_sha256: 'abc123',
            download_url: null,
            download_available: false,
          },
        ],
      },
    })
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: false,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })
  })

  it('renders the homepage through the real public route tree', async () => {
    renderRoute('/')

    expect(screen.getByText('Loading HyperTwist...')).toBeTruthy()
    expect(screen.getByText('Public website')).toBeTruthy()
    expect(screen.getByText(/full HyperTwist story, the current access snapshot, and the easiest path into the desktop app/i)).toBeTruthy()
    expect(await screen.findByText(
      'One serious home for classic cubes, 120‑cell, 5D, and deep daily practice.',
      {},
      { timeout: 3000 },
    )).toBeTruthy()
  })

  it('renders the browser-guide page through the real public route tree', async () => {
    renderRoute('/browser')

    expect(screen.getByText('Browser access guide')).toBeTruthy()
    expect(screen.getByText('Browser companion')).toBeTruthy()
    expect(screen.getByText(/website, account access, and desktop app work together/i)).toBeTruthy()
    expect(await screen.findByText('The website gets you in. The desktop app becomes the training room.')).toBeTruthy()
  })

  it('renders the help-center page through the real public route tree', async () => {
    renderRoute('/help')

    expect(screen.getAllByText('Help center').length).toBeGreaterThan(0)
    expect(screen.getByText(/setup, controls, downloads, and practical troubleshooting/i)).toBeTruthy()
    expect(await screen.findByText('Practical help for setup, controls, downloads, and launch.')).toBeTruthy()
  })

  it('renders the pricing page through the real public route tree', async () => {
    renderRoute('/pricing')
    expect(await screen.findByText('Pricing that matches the actual delivery model.')).toBeTruthy()
    expect(screen.getByText('Plan lineup')).toBeTruthy()
  })

  it('renders the public feature-atlas page through the real public route tree', async () => {
    renderRoute('/features')
    expect(await screen.findByText('A deep training toolkit, not just a timer.')).toBeTruthy()
    expect(screen.getByText('How to read this feature map')).toBeTruthy()
  })

  it('renders the download page through the real public route tree', async () => {
    renderRoute('/download')
    expect(await screen.findByText('Download the desktop build and pair it with your browser account.')).toBeTruthy()
    expect(screen.getByText('Available targets')).toBeTruthy()
  })

  it('renders the getting-started page through the real public route tree', async () => {
    renderRoute('/getting-started')
    expect(screen.getAllByText('Getting started').length).toBeGreaterThan(0)
    expect(screen.getByText(/first-session path from account setup to the desktop app/i)).toBeTruthy()
    expect(await screen.findByText('The first serious HyperTwist session')).toBeTruthy()
  })

  it('renders the launch-status page through the real public route tree', async () => {
    renderRoute('/launch-status')
    expect(screen.getByText('Launch status')).toBeTruthy()
    expect(screen.getByText('Access status')).toBeTruthy()
    expect(screen.getByText(/current availability, release progress, and access options/i)).toBeTruthy()
    expect(await screen.findByText('See how public pages, account access, and desktop delivery work together.')).toBeTruthy()
  })

  it('renders the login page through the real public route tree', async () => {
    renderRoute('/login?next=%2Fapp%2Fdownloads')

    expect(screen.getByText('Account access')).toBeTruthy()
    expect(screen.getByText(/sign-in, account access, and the path into your dashboard and downloads/i)).toBeTruthy()
    expect(await screen.findByText('Log in to HyperTwist')).toBeTruthy()
    expect(screen.getByRole('link', { name: /create an account/i }).getAttribute('href')).toBe('/register?next=%2Fapp%2Fdownloads')
  })

  it('redirects unauthenticated protected routes into the login route through the real route tree', async () => {
    renderRoute('/app')

    expect(await screen.findByText('Log in to HyperTwist')).toBeTruthy()
    expect(screen.getByRole('link', { name: /create an account/i }).getAttribute('href')).toBe('/register?next=%2Fapp')
  })

  it('renders the protected dashboard route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })
    mockGetReleaseManifest.mockResolvedValue({
      ok: true,
      manifest: {
        generated_at: '2026-06-22T12:00:00.000Z',
        support_email: 'hello@hypertwist.app',
        public_docs_url: 'https://docs.hypertwist.app',
        release_notes_url: 'https://notes.hypertwist.app',
        corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
        open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
        viewer: {
          authenticated: true,
          canDownload: true,
          plan: 'operator',
          role: 'operator',
          accessStatus: 'active',
        },
        platforms: [
          {
            platform_key: 'windows',
            platform: 'Windows',
            subtitle: 'Primary shipping lane',
            details: 'Current packaged validation is strongest on the Windows Unreal lane.',
            configured: true,
            channel: 'candidate',
            version: '1.0.0',
            build_id: 'win64-1000',
            published_at: '2026-06-22T00:00:00.000Z',
            file_name: 'HyperTwist-Windows.zip',
            file_size_bytes: 1048576,
            checksum_sha256: 'abc123',
            download_url: 'https://downloads.hypertwist.app/windows.exe',
            download_available: true,
          },
        ],
      },
    })

    renderRoute('/app')
    expect(await screen.findByText('HyperTwist dashboard')).toBeTruthy()
    expect(await screen.findByText('Account state')).toBeTruthy()
    expect(screen.getByText('Current product-surface map')).toBeTruthy()
  })

  it('renders the protected downloads route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })
    mockGetReleaseManifest.mockResolvedValue({
      ok: true,
      manifest: {
        generated_at: '2026-06-22T12:00:00.000Z',
        support_email: 'hello@hypertwist.app',
        public_docs_url: 'https://docs.hypertwist.app',
        release_notes_url: 'https://notes.hypertwist.app',
        corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
        open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
        viewer: {
          authenticated: true,
          canDownload: true,
          plan: 'operator',
          role: 'operator',
          accessStatus: 'active',
        },
        platforms: [
          {
            platform_key: 'windows',
            platform: 'Windows',
            subtitle: 'Primary shipping lane',
            details: 'Current packaged validation is strongest on the Windows Unreal lane.',
            configured: true,
            channel: 'candidate',
            version: '1.0.0',
            build_id: 'win64-1000',
            published_at: '2026-06-22T00:00:00.000Z',
            file_name: 'HyperTwist-Windows.zip',
            file_size_bytes: 1048576,
            checksum_sha256: 'abc123',
            download_url: 'https://downloads.hypertwist.app/windows.exe',
            download_available: true,
          },
        ],
      },
    })

    renderRoute('/app/downloads')
    await waitFor(() => {
      expect(screen.getByText('Release targets')).toBeTruthy()
    })
    expect(screen.getByText('Windows')).toBeTruthy()
  })

  it('renders the protected launch-status route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })
    mockGetReleaseManifest.mockResolvedValue({
      ok: true,
      manifest: {
        generated_at: '2026-06-22T12:00:00.000Z',
        support_email: 'hello@hypertwist.app',
        public_docs_url: 'https://docs.hypertwist.app',
        release_notes_url: 'https://notes.hypertwist.app',
        corresponding_source_url: 'https://hypertwist.app/open-source/source.zip',
        open_source_repo_url: 'https://github.com/hypertwist/hypertwist',
        viewer: {
          authenticated: true,
          canDownload: true,
          plan: 'operator',
          role: 'operator',
          accessStatus: 'active',
        },
        platforms: [
          {
            platform_key: 'windows',
            platform: 'Windows',
            subtitle: 'Primary shipping lane',
            details: 'Current packaged validation is strongest on the Windows Unreal lane.',
            configured: true,
            channel: 'candidate',
            version: '1.0.0',
            build_id: 'win64-1000',
            published_at: '2026-06-22T00:00:00.000Z',
            file_name: 'HyperTwist-Windows.zip',
            file_size_bytes: 1048576,
            checksum_sha256: 'abc123',
            download_url: 'https://downloads.hypertwist.app/windows.exe',
            download_available: true,
          },
        ],
      },
    })

    renderRoute('/app/launch-status')
    expect(await screen.findByRole('heading', { name: 'Launch references and notices' })).toBeTruthy()
  })

  it('renders the protected browser-access route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })

    renderRoute('/app/browser-access')
    expect(await screen.findByText('Current browser role')).toBeTruthy()
    expect(screen.getByText('Browser-to-desktop handoff')).toBeTruthy()
  })

  it('renders the protected account route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })

    renderRoute('/app/account')
    expect(await screen.findByText('Session profile')).toBeTruthy()
    expect(screen.getByText('Account follow-through')).toBeTruthy()
  })

  it('renders the protected notices route through the real route tree when authenticated', async () => {
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: true,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'session',
          accessStatus: 'active',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
    })

    renderRoute('/app/notices')
    expect(await screen.findByText('Distribution notices')).toBeTruthy()
    expect(screen.getByText('Reference surfaces')).toBeTruthy()
  })
})
