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 mockGetAuthHealth = vi.fn()

vi.mock('../auth/auth-api', () => ({
  getAuthHealth: (...args: unknown[]) => mockGetAuthHealth(...args),
}))

import { MarketingLaunchStatusBanner, PublicLaunchStatus } from '../components/ui/PublicLaunchStatus'

function renderComponent(element: React.ReactNode = <PublicLaunchStatus />) {
  const queryClient = new QueryClient({
    defaultOptions: {
      queries: {
        retry: false,
      },
    },
  })

  return render(
    <QueryClientProvider client={queryClient}>
      <MemoryRouter future={ROUTER_FUTURE_FLAGS}>
        {element}
      </MemoryRouter>
    </QueryClientProvider>,
  )
}

describe('PublicLaunchStatus', () => {
  beforeEach(() => {
    cleanup()
    mockGetAuthHealth.mockReset()
  })

  it('surfaces concrete live preview blockers instead of only generic missing labels', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: false,
        apiVersion: '5.4',
        error: null,
        oauth: {
          github: true,
          google: false,
          orcid: true,
        },
      },
      fallback: {
        enabled: true,
        active: false,
        reason: null,
      },
      billing: {
        statePath: '/tmp/hypertwist-billing.json',
        processedEventCount: 0,
        pricePlanMapConfigured: false,
        productPlanMapConfigured: false,
        webhookSecretConfigured: false,
      },
      runtime: {
        mode: 'mixed',
        public_origin_ready: true,
        cookie_secure: true,
        api_domain: 'https://hypertwist.app',
        website_domain: 'https://hypertwist.app',
        warnings: ['SUPERTOKENS_CORE_URI still targets a loopback/local-development host.'],
        errors: [],
      },
      launch: {
        posture: 'preview',
        ready: false,
        readiness: {
          windowsDownloadConfigured: false,
          macosDownloadConfigured: false,
          linuxDownloadConfigured: false,
          operatorCheckoutConfigured: false,
          studioCheckoutConfigured: false,
          mplSourceConfigured: true,
          openSourceRepoConfigured: true,
          billingProductPlanMapConfigured: false,
          billingPricePlanMapConfigured: false,
          billingWebhookSecretConfigured: false,
          publicAuthRuntimeReady: false,
        },
        checklist: [
          {
            id: 'windows-download',
            label: 'Windows release authority',
            configured: false,
            requiredForPublicLaunch: true,
          },
        ],
        missingLabels: ['windows release authority', 'operator checkout URL'],
        targets: {
          operatorCheckoutTarget: null,
          studioCheckoutTarget: null,
        },
      },
    })

    renderComponent()

    await waitFor(() => {
      expect(screen.queryByText(/Checking current account and release access status/i)).toBeNull()
    })

    expect(screen.getByText('Account-gated early access')).toBeTruthy()
    expect(screen.getByText(/signed-in dashboard routes handle download access, subscription state, and desktop pairing/i)).toBeTruthy()
    expect(screen.getByText('Desktop app access: routed through account creation or sign-in before package delivery.')).toBeTruthy()
    expect(screen.getByText('Browser version: available as the public/protected account, docs, release, pricing, and pairing shell, not as simulator parity.')).toBeTruthy()
    expect(screen.getByRole('link', { name: 'Open signed-in downloads' }).getAttribute('href')).toBe('/app/downloads?platform=windows')
    expect(screen.getByRole('link', { name: 'Open protected notices' }).getAttribute('href')).toBe('/app/notices')
  })

  it('keeps the marketing banner compact while still surfacing concrete live blockers', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: false,
        apiVersion: '5.4',
        error: null,
        oauth: {
          github: true,
          google: false,
          orcid: true,
        },
      },
      fallback: {
        enabled: true,
        active: false,
        reason: null,
      },
      billing: {
        statePath: '/tmp/hypertwist-billing.json',
        processedEventCount: 0,
        pricePlanMapConfigured: false,
        productPlanMapConfigured: false,
        webhookSecretConfigured: false,
      },
      runtime: {
        mode: 'mixed',
        public_origin_ready: true,
        cookie_secure: true,
        api_domain: 'https://hypertwist.app',
        website_domain: 'https://hypertwist.app',
        warnings: [],
        errors: [],
      },
      launch: {
        posture: 'preview',
        ready: false,
        readiness: {
          windowsDownloadConfigured: true,
          macosDownloadConfigured: false,
          linuxDownloadConfigured: false,
          operatorCheckoutConfigured: false,
          studioCheckoutConfigured: false,
          mplSourceConfigured: true,
          openSourceRepoConfigured: true,
          billingProductPlanMapConfigured: false,
          billingPricePlanMapConfigured: false,
          billingWebhookSecretConfigured: false,
          publicAuthRuntimeReady: false,
        },
        checklist: [
          {
            id: 'windows-download',
            label: 'Windows release authority',
            configured: true,
            requiredForPublicLaunch: true,
          },
        ],
        missingLabels: ['operator checkout URL', 'studio checkout URL'],
        targets: {
          operatorCheckoutTarget: null,
          studioCheckoutTarget: null,
        },
      },
    })

    renderComponent(<MarketingLaunchStatusBanner />)

    await waitFor(() => {
      expect(screen.getByText(/HyperTwist is in account-gated early access/i)).toBeTruthy()
    })

    expect(screen.getByText(/Some release and commerce steps are still handled through signed-in dashboard or support follow-up/i)).toBeTruthy()
    expect(screen.getByRole('link', { name: 'Open signed-in downloads' }).getAttribute('href')).toBe('/app/downloads?platform=windows')
  })

  it('omits the blocker section when the live launch posture is ready and warning-free', async () => {
    mockGetAuthHealth.mockResolvedValue({
      ok: true,
      service: 'hypertwist-auth-server',
      supertokens: {
        configured: true,
        reachable: true,
        ready: true,
        apiVersion: '5.4',
        error: null,
        oauth: {
          github: true,
          google: true,
          orcid: true,
        },
      },
      fallback: {
        enabled: true,
        active: false,
        reason: null,
      },
      billing: {
        statePath: '/tmp/hypertwist-billing.json',
        processedEventCount: 4,
        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: [],
      },
      launch: {
        posture: 'launch-ready',
        ready: true,
        readiness: {
          windowsDownloadConfigured: true,
          macosDownloadConfigured: false,
          linuxDownloadConfigured: false,
          operatorCheckoutConfigured: true,
          studioCheckoutConfigured: true,
          mplSourceConfigured: true,
          openSourceRepoConfigured: true,
          billingProductPlanMapConfigured: true,
          billingPricePlanMapConfigured: true,
          billingWebhookSecretConfigured: true,
          publicAuthRuntimeReady: true,
        },
        checklist: [
          {
            id: 'windows-download',
            label: 'Windows release authority',
            configured: true,
            requiredForPublicLaunch: true,
          },
        ],
        missingLabels: [],
        targets: {
          operatorCheckoutTarget: 'https://buy.paddle.com/operator',
          studioCheckoutTarget: 'https://buy.paddle.com/studio',
        },
      },
    })

    renderComponent()

    await waitFor(() => {
      expect(screen.queryByText(/Checking current account and release access status/i)).toBeNull()
    })

    expect(screen.queryByText('Current early-access blockers from the live auth runtime')).toBeNull()
    expect(screen.queryByText('Live runtime notes')).toBeNull()
  })
})
