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

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

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

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

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

describe('DashboardOverviewPage', () => {
  beforeEach(() => {
    cleanup()
    mockUsePlatformAuth.mockReset()
    mockCreateDesktopLinkToken.mockReset()
    mockGetAuthHealth.mockReset()
    mockBuildAuthApiBaseUrls.mockReset()
    mockGetReleaseManifest.mockReset()
    mockInvalidateSession.mockReset()
    mockBuildAuthApiBaseUrls.mockReturnValue(['https://hypertwist.app'])
    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: 'trial',
        },
        platforms: [
          {
            platform_key: 'windows',
            platform: 'Windows',
            subtitle: 'Primary shipping lane',
            details: 'Current packaged validation is strongest on the Windows Unreal lane.',
            configured: false,
            channel: 'preview',
            version: null,
            build_id: null,
            published_at: null,
            file_name: null,
            file_size_bytes: null,
            checksum_sha256: null,
            download_url: null,
            download_available: false,
            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',
                },
              ],
            },
          },
        ],
      },
    })

    mockUsePlatformAuth.mockReturnValue({
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        authMethod: 'email',
        plan: 'operator',
        role: 'operator',
        canDownload: true,
        billing: {
          source: 'local-fallback',
          accessStatus: 'trial',
          canDownload: true,
          lastEventType: 'transaction.completed',
        },
      },
      superTokensConfigured: true,
      invalidateSession: (...args: unknown[]) => mockInvalidateSession(...args),
      reconcileReleaseAuthority: vi.fn(),
      releaseAuthoritySyncItems: [],
    })
  })

  it('surfaces launch-readiness issues and the generated desktop-link verify URL', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: false,
        ready: false,
        apiVersion: null,
        oauth: {
          github: false,
          google: false,
        },
      },
      fallback: {
        enabled: true,
        active: true,
        reason: 'not_ready',
      },
      billing: {
        statePath: '/tmp/hypertwist-billing.json',
        processedEventCount: 0,
        pricePlanMapConfigured: false,
        productPlanMapConfigured: false,
        webhookSecretConfigured: false,
      },
      runtime: {
        mode: 'mixed',
        public_origin_ready: false,
        cookie_secure: false,
        api_domain: 'http://localhost:3001',
        website_domain: 'http://localhost:4273',
        warnings: ['COOKIE_SECURE disabled'],
        errors: ['API_DOMAIN still points at localhost'],
      },
    })

    mockCreateDesktopLinkToken.mockResolvedValue({
      ok: true,
      token: 'desktop-token-123',
      expires_at: '2026-06-22T12:00:00.000Z',
    })

    renderPage()

    await waitFor(() => {
      expect(screen.queryByText(/Checking auth server health/i)).toBeNull()
    })

    expect(screen.getByText(/This session is currently using local recovery mode/i)).toBeTruthy()
    expect(screen.getByText(/Shared auth core is not fully ready right now/i)).toBeTruthy()
    expect(screen.getByText('Auth and session authority')).toBeTruthy()
    expect(screen.getByText('Signed-in method: Email and password')).toBeTruthy()
    expect(screen.getByText('Available provider routes: Email/password on, GitHub off, Google off, ORCID off')).toBeTruthy()
    expect(screen.getByText('API domain: http://localhost:3001')).toBeTruthy()
    expect(screen.getByText('What stays intentionally bounded')).toBeTruthy()
    expect(screen.getByText('Recommended recovery order')).toBeTruthy()
    expect(screen.getByText(/Public launch is not fully configured yet:/i)).toBeTruthy()
    expect(screen.getByText('Billing product-plan map: pending')).toBeTruthy()
    expect(screen.getByText('Billing price-plan map: pending')).toBeTruthy()
    expect(screen.getByText('Paddle webhook secret: pending')).toBeTruthy()
    expect(screen.getByText('Public auth runtime status: local-or-mixed')).toBeTruthy()
    expect(screen.getByText('Current early-access blockers from the live auth runtime')).toBeTruthy()
    expect(screen.getByText('Shared browser-auth runtime still needs production readiness confirmation on the current deployment.')).toBeTruthy()
    expect(screen.getByText('Paddle webhook verification still needs to be enabled for fully automated billing updates.')).toBeTruthy()
    expect(screen.getByText('Billing product-plan mapping still needs to be connected to the live subscription catalog.')).toBeTruthy()
    expect(screen.getByText('Billing price-plan mapping still needs to be connected to the live subscription catalog.')).toBeTruthy()
    expect(screen.getByText('Runtime error: API_DOMAIN still points at localhost')).toBeTruthy()
    expect(screen.getByText('Runtime warning: COOKIE_SECURE disabled')).toBeTruthy()
    expect(screen.getByText('Current release action')).toBeTruthy()
    expect(screen.getByText('Desktop access is visible, but no packaged target is published yet.')).toBeTruthy()
    expect(screen.getAllByRole('link', { name: 'Review release notes' })[0]?.getAttribute('href')).toBe('/changelog')
    expect(screen.getByText('Protected operator quick routes')).toBeTruthy()
    expect(screen.getByText('Signed-in help lanes')).toBeTruthy()
    expect(screen.getByText('Protected browser-versus-desktop reality')).toBeTruthy()
    expect(screen.getByText('Controls and device support today')).toBeTruthy()
    expect(
      screen
        .getAllByRole('link', { name: 'Open protected launch status' })
        .some((link) => link.getAttribute('href') === '/app/launch-status'),
    ).toBe(true)
    expect(screen.getByRole('link', { name: 'Open account' }).getAttribute('href')).toBe('/app/account')
    expect(screen.getAllByRole('link', { name: 'Open browser access' }).every((link) => link.getAttribute('href') === '/app/browser-access')).toBe(true)
    expect(screen.getAllByRole('link', { name: 'Open notices' }).length).toBeGreaterThan(0)
    expect(screen.getByText('Current packaged desktop proof')).toBeTruthy()
    expect(screen.getByText('Packaged validation passed')).toBeTruthy()
    expect(screen.getByText(/Magic120Cell dedicated-family training map: passed/i)).toBeTruthy()
    expect(screen.getByText('First simulator session')).toBeTruthy()
    expect(screen.getByText('1. Resolve access and choose the right build')).toBeTruthy()
    expect(screen.getByText('4. Open the higher-dimensional families and read the control boundary honestly')).toBeTruthy()
    expect(screen.getByText('Software workflows after access is resolved')).toBeTruthy()
    expect(screen.getByText('2. Run a recognition and correction workflow')).toBeTruthy()
    expect(screen.getByText('Native control and settings roster')).toBeTruthy()
    expect(screen.getAllByText(/classic-wca-keyboard\/v1/i).length).toBeGreaterThan(0)
    expect(screen.getByText('XR groundwork exists, but the full VR lane is not finished')).toBeTruthy()
    expect(screen.getByText('Desktop rollout follow-through')).toBeTruthy()
    expect(screen.getByText('Current product-surface map')).toBeTruthy()
    expect(screen.getByText('Embedded simulator web tools')).toBeTruthy()
    expect(screen.getByText('Pair desktop access to the browser account')).toBeTruthy()

    const generateDesktopLinkButtons = screen.getAllByRole('button', { name: /generate desktop-link token/i })
    await userEvent.click(generateDesktopLinkButtons[generateDesktopLinkButtons.length - 1]!)

    await waitFor(() => {
      expect(screen.getByText((content) => content === 'desktop-token-123')).toBeTruthy()
    })

    expect(screen.getByText(/https:\/\/hypertwist\.app\/api\/auth\/desktop-link\/verify\?token=desktop-token-123/i)).toBeTruthy()
  })

  it('invalidates the protected browser session when desktop-link issuance returns unauthorized', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: true,
        apiVersion: '5.4',
        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.mockRejectedValue(Object.assign(new Error('unauthorized'), { status: 401 }))

    renderPage()

    await waitFor(() => {
      expect(screen.queryByText(/Checking auth server health/i)).toBeNull()
    })

    const generateDesktopLinkButtons = screen.getAllByRole('button', { name: /generate desktop-link token/i })
    await userEvent.click(generateDesktopLinkButtons[generateDesktopLinkButtons.length - 1]!)

    await waitFor(() => {
      expect(mockInvalidateSession).toHaveBeenCalledWith('desktop_link_unauthorized')
    })
  })

  it('surfaces live authority sync details after release access has been refreshed from live manifest truth', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: true,
        apiVersion: '5.4',
        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: [],
      },
    })

    mockUsePlatformAuth.mockReturnValue({
      user: {
        id: 'operator-1',
        name: 'Operator',
        email: 'operator@hypertwist.app',
        authMethod: 'email',
        plan: 'free',
        role: 'viewer',
        canDownload: false,
        billing: {
          source: 'session',
          accessStatus: 'session-default',
          canDownload: false,
          lastEventType: 'transaction.completed',
        },
      },
      superTokensConfigured: true,
      reconcileReleaseAuthority: vi.fn(),
      invalidateSession: (...args: unknown[]) => mockInvalidateSession(...args),
      releaseAuthoritySyncItems: [
        'Plan changed from local free to live operator.',
        'Desktop download access changed from local not entitled to live enabled.',
      ],
    })

    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',
                },
              ],
            },
          },
        ],
      },
    })

    renderPage()

    expect(await screen.findByText('Live authority sync')).toBeTruthy()
    expect(screen.getByText(/plan changed from local free to live operator/i)).toBeTruthy()
    expect(screen.getByText(/desktop download access changed from local not entitled to live enabled/i)).toBeTruthy()
    expect(screen.getByText('Current release action')).toBeTruthy()
    expect(screen.getByText('Windows package is ready for this account.')).toBeTruthy()
    expect(screen.getByRole('link', { name: 'Download Windows package' }).getAttribute('href')).toBe('https://downloads.hypertwist.app/windows.exe')
  })
})
