import { cleanup, render, screen, waitFor } from '@testing-library/react'
import { beforeEach, describe, expect, it, vi } from 'vitest'

const mockUsePlatformAuth = vi.fn()
const mockIsSuperTokensConfigured = vi.fn(() => false)

vi.mock('../auth/platform-auth', () => ({
  PlatformAuthProvider: ({ children }: { children: React.ReactNode }) => <>{children}</>,
  usePlatformAuth: () => mockUsePlatformAuth(),
}))

vi.mock('../auth/supertokens-runtime', async (importOriginal) => {
  const actual = await importOriginal<typeof import('../auth/supertokens-runtime')>()
  return {
    ...actual,
    isSuperTokensConfigured: () => mockIsSuperTokensConfigured(),
    isGoogleOAuthEnabled: () => false,
    isGitHubOAuthEnabled: () => false,
    isOrcidOAuthEnabled: () => false,
    getSuperTokensAuthRuntimeValidation: () => ({
      ready: true,
      missing: [],
      warnings: [],
    }),
  }
})

vi.mock('../auth/SuperTokensRouteWrapper', () => ({
  SuperTokensRouteWrapper: ({ children }: { children: React.ReactNode }) => (
    <div data-testid="supertokens-wrapper">{children}</div>
  ),
}))

import App from '../App'

describe('App bootstrap', () => {
  beforeEach(() => {
    cleanup()
    window.localStorage.clear()
    mockUsePlatformAuth.mockReset()
    mockIsSuperTokensConfigured.mockReset()
    mockIsSuperTokensConfigured.mockReturnValue(false)
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: false,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: false,
      user: null,
    })
    window.history.replaceState({}, '', '/')
  })

  it('redirects unknown routes to the homepage through the real app root', async () => {
    window.history.replaceState({}, '', '/totally-unknown')

    render(<App />)

    expect(await screen.findByText('One serious home for classic cubes, 120‑cell, 5D, and deep daily practice.')).toBeTruthy()
    await waitFor(() => {
      expect(window.location.pathname).toBe('/')
    })
    expect(screen.queryByTestId('supertokens-wrapper')).toBeNull()
  })

  it('does not wrap ordinary public routes in SuperTokens just because auth is configured', async () => {
    mockIsSuperTokensConfigured.mockReturnValue(true)
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: false,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: null,
    })
    window.history.replaceState({}, '', '/pricing')

    render(<App />)

    expect(await screen.findByText('Pricing that matches the actual delivery model.')).toBeTruthy()
    expect(screen.queryByTestId('supertokens-wrapper')).toBeNull()
    expect(document.querySelector('[data-testid="supertokens-auth-backdrop"]')).toBeNull()
  })

  it('wraps auth-shell routes in SuperTokens and syncs the auth backdrop', async () => {
    mockIsSuperTokensConfigured.mockReturnValue(true)
    mockUsePlatformAuth.mockReturnValue({
      isAuthenticated: false,
      isLoading: false,
      login: vi.fn(),
      register: vi.fn(),
      logout: vi.fn(),
      toggleColorMode: vi.fn(),
      colorMode: 'dark',
      superTokensConfigured: true,
      user: null,
    })
    window.history.replaceState({}, '', '/login')

    render(<App />)

    expect(await screen.findByText('Log in to HyperTwist')).toBeTruthy()
    expect(screen.getByTestId('supertokens-wrapper')).toBeTruthy()
    expect(document.querySelector('[data-testid="supertokens-auth-backdrop"]')).not.toBeNull()
  })

  it('keeps the SuperTokens wrapper active on public routes when a local platform session is already stored', async () => {
    mockIsSuperTokensConfigured.mockReturnValue(true)
    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',
        authMethod: 'supertokens',
        plan: 'operator',
      },
    })
    window.localStorage.setItem('hypertwist.platform.user.v1', JSON.stringify({
      id: 'operator-1',
      name: 'Operator',
      email: 'operator@hypertwist.app',
      authMethod: 'supertokens',
      plan: 'operator',
    }))
    window.history.replaceState({}, '', '/pricing')

    render(<App />)

    expect(await screen.findByText('Pricing that matches the actual delivery model.')).toBeTruthy()
    expect(screen.getByTestId('supertokens-wrapper')).toBeTruthy()
  })
})
