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 mockGetReleaseManifest = vi.fn()
const mockBuildAuthApiBaseUrls = vi.fn(() => ['https://hypertwist.app'])
const mockCreateDesktopLinkToken = vi.fn()
const mockGetAuthHealth = vi.fn()
const mockUsePlatformAuth = vi.fn()

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

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

vi.mock('../site-config', () => ({
  brandConfig: {
    brandName: 'HyperTwist',
    legalName: 'HyperTwist',
    domain: 'hypertwist.app',
    tagline: 'Native cube and hypercube training, from first solve to 120-cell.',
    contact: {
      email: 'hello@hypertwist.app',
      emailHref: 'mailto:hello@hypertwist.app',
    },
    payment: {
      provider: 'Paddle',
    },
  },
  planCatalog: [
    {
      key: 'explorer',
      name: 'Explorer',
      price: 'Free',
      ctaLabel: 'Start in the browser',
      ctaHref: '/register?next=%2Fapp',
      notes: 'Preview the browser account shell, operator dashboard, release notes, and desktop onboarding posture.',
      features: ['Browser account access'],
    },
    {
      key: 'operator',
      name: 'Operator',
      price: 'Launch pricing via Paddle',
      ctaLabel: 'Open protected downloads',
      ctaHref: '/app/downloads?platform=windows',
      notes: 'Desktop-first recognition, replay, training, and higher-dimensional runtime ownership for active training operators.',
      features: ['Desktop download access'],
    },
    {
      key: 'studio',
      name: 'Studio',
      price: 'Contact for launch readiness',
      ctaLabel: 'Open protected rollout lane',
      ctaHref: '/app/browser-access',
      notes: 'Higher-dimensional families, operator deployment support, and packaging/validation coordination for production lanes.',
      features: ['Magic120Cell and 5D operator posture'],
    },
  ],
  downloadTargets: [
    {
      platformKey: 'windows',
      platform: 'Windows',
      subtitle: 'Primary shipping lane',
      configured: true,
      details: 'Current packaged validation is strongest on the Windows Unreal lane.',
    },
    {
      platformKey: 'macos',
      platform: 'macOS',
      subtitle: 'Planned distribution surface',
      configured: true,
      details: 'List a signed desktop build here when the package lane is opened.',
    },
    {
      platformKey: 'linux',
      platform: 'Linux',
      subtitle: 'Operator-targeted later lane',
      configured: false,
      details: 'Use for future package publication after the bounded release lane is widened.',
    },
  ],
  launchReadiness: {
    operatorCheckoutConfigured: true,
    studioCheckoutConfigured: true,
    windowsDownloadConfigured: true,
    macDownloadConfigured: true,
    linuxDownloadConfigured: false,
    mplSourceConfigured: true,
    openSourceRepoConfigured: true,
  },
  mplSourceUrl: 'https://hypertwist.app/open-source/source.zip',
  openSourceRepoUrl: 'https://github.com/hypertwist/hypertwist',
  publicDocsUrl: 'https://docs.hypertwist.app',
  releaseNotesUrl: 'https://notes.hypertwist.app',
}))

import { DownloadCenterPage } from '../pages/app-pages'

describe('DownloadCenterPage', () => {
  beforeEach(() => {
    cleanup()
    mockUsePlatformAuth.mockReset()
    mockGetReleaseManifest.mockReset()
    mockBuildAuthApiBaseUrls.mockReset()
    mockCreateDesktopLinkToken.mockReset()
    mockGetAuthHealth.mockReset()
    mockBuildAuthApiBaseUrls.mockReturnValue(['https://hypertwist.app'])
    mockUsePlatformAuth.mockReturnValue({
      user: {
        canDownload: true,
      },
    })
  })

  it('surfaces the requested protected release target when the public site passes a platform hint through auth', async () => {
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    })

    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,
            validation_summary: {
              lane: 'Windows Unreal packaged validation',
              result: 'passed',
              generated_at: '2026-06-22T01:43:08.7625247Z',
              configuration: 'Development',
              skip_build: true,
              smoke_map_count: 2,
              smoke_maps: [
                {
                  map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining',
                  label: 'Magic120Cell dedicated-family training map',
                  result: 'passed',
                },
                {
                  map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_MagicCube5DTraining',
                  label: 'MagicCube5D dedicated-family training map',
                  result: 'passed',
                },
              ],
            },
          },
        ],
      },
    })

    render(
      <QueryClientProvider client={queryClient}>
        <MemoryRouter initialEntries={['/app/downloads?platform=windows']} future={ROUTER_FUTURE_FLAGS}>
          <DownloadCenterPage />
        </MemoryRouter>
      </QueryClientProvider>,
    )

    expect(screen.getByText(/preserved your Windows selection/i)).toBeTruthy()
    expect(screen.getAllByText('Requested target').length).toBeGreaterThan(0)
    expect((await screen.findByRole('link', { name: 'Download Windows package' })).getAttribute('href')).toBe('https://downloads.hypertwist.app/windows.exe')
    expect(screen.getByText('Release guide')).toBeTruthy()
    expect(screen.getByText('First launch follow-through')).toBeTruthy()
    expect(screen.getByText('Verify the current training lanes')).toBeTruthy()
    expect(screen.getByText('Protected browser-versus-desktop reality')).toBeTruthy()
    expect(screen.getByText('Why the desktop app exists')).toBeTruthy()
    expect(screen.getByText('Download and rollout escalation')).toBeTruthy()
    expect(screen.getByText('Current product-surface map')).toBeTruthy()
    expect(await screen.findByText('Version: 1.0.0')).toBeTruthy()
    expect(screen.getByText('Build: win64-1000')).toBeTruthy()
    expect(screen.getAllByText('Packaged validation passed').length).toBeGreaterThan(0)
    expect(screen.getAllByText(/MagicCube5D dedicated-family training map: passed/i).length).toBeGreaterThan(0)
    expect(document.title).toBe('HyperTwist downloads | HyperTwist')
  })

  it('trusts the live manifest viewer posture when local auth state is stale about download entitlement', async () => {
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    })

    mockUsePlatformAuth.mockReturnValue({
      user: {
        canDownload: false,
      },
    })

    mockGetReleaseManifest.mockResolvedValue({
      ok: true,
      manifest: {
        generated_at: '2026-06-23T12: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.1',
            build_id: 'win64-1001',
            published_at: '2026-06-23T00:00:00.000Z',
            file_name: 'HyperTwist-Windows.zip',
            file_size_bytes: 1048576,
            checksum_sha256: 'abc124',
            download_url: 'https://downloads.hypertwist.app/windows.exe',
            download_available: true,
            validation_summary: {
              lane: 'Windows Unreal packaged validation',
              result: 'passed',
              generated_at: '2026-06-23T01:43:08.7625247Z',
              configuration: 'Development',
              skip_build: true,
              smoke_map_count: 2,
              smoke_maps: [
                {
                  map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining',
                  label: 'Magic120Cell dedicated-family training map',
                  result: 'passed',
                },
                {
                  map_url: '/Game/HyperTwistTraining/Maps/L_HyperTwist_MagicCube5DTraining',
                  label: 'MagicCube5D dedicated-family training map',
                  result: 'passed',
                },
              ],
            },
          },
        ],
      },
    })

    render(
      <QueryClientProvider client={queryClient}>
        <MemoryRouter initialEntries={['/app/downloads?platform=windows']} future={ROUTER_FUTURE_FLAGS}>
          <DownloadCenterPage />
        </MemoryRouter>
      </QueryClientProvider>,
    )

    expect((await screen.findByRole('link', { name: 'Download Windows package' })).getAttribute('href')).toBe('https://downloads.hypertwist.app/windows.exe')
    await waitFor(() => {
      expect(screen.queryByText(/does not yet have desktop download entitlement/i)).toBeNull()
    })
  })

  it('keeps entitled fallback posture honest when live release authority is temporarily unavailable', async () => {
    const queryClient = new QueryClient({
      defaultOptions: {
        queries: {
          retry: false,
        },
      },
    })

    mockGetReleaseManifest.mockRejectedValue(new Error('release manifest unavailable'))

    render(
      <QueryClientProvider client={queryClient}>
        <MemoryRouter initialEntries={['/app/downloads?platform=windows']} future={ROUTER_FUTURE_FLAGS}>
          <DownloadCenterPage />
        </MemoryRouter>
      </QueryClientProvider>,
    )

    expect(await screen.findByText('Current release action')).toBeTruthy()
    expect(await screen.findAllByText(/your signed-in account still resolves to desktop access/i)).toHaveLength(2)
    expect(screen.getAllByText((_content, node) => node?.textContent === 'Live release authority must recover before package delivery resumes.').length).toBeGreaterThan(0)
    expect(screen.getAllByText('Live release authority temporarily unavailable').length).toBeGreaterThan(0)
    expect(screen.getByText('What stays intentionally withheld')).toBeTruthy()
    expect(screen.getAllByRole('link', { name: 'Open dashboard' }).every((link) => link.getAttribute('href') === '/app')).toBe(true)
    expect(screen.queryByText(/account not entitled yet/i)).toBeNull()
  })
})
