import { render, screen } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { afterEach, describe, expect, it, vi } from 'vitest'
import App from './App'

describe('App', () => {
  afterEach(() => {
    vi.unstubAllGlobals()
    vi.restoreAllMocks()
  })

  it('renders the dashboard shell with brand and nav', async () => {
    vi.stubGlobal(
      'fetch',
      vi.fn().mockResolvedValue({
        ok: true,
        json: async () => ({
          service: 'clustercanvas',
          version: '0.1.0',
        }),
      }),
    )

    render(<App />)

    expect(
      screen.getByRole('heading', { name: 'Cluster Canvas' }),
    ).toBeInTheDocument()
    expect(screen.getByText(`Frontend Version ${__FRONTEND_VERSION__}`)).toBeInTheDocument()
    expect(await screen.findByText('Backend Version 0.1.0')).toBeInTheDocument()

    expect(screen.getByRole('button', { name: 'Overview' })).toBeInTheDocument()
    expect(screen.getByRole('button', { name: 'VMs' })).toBeInTheDocument()
    expect(
      screen.getByRole('button', { name: 'Containers' }),
    ).toBeInTheDocument()
    expect(
      screen.getByRole('button', { name: 'Configuration' }),
    ).toBeInTheDocument()

    expect(
      screen.getByRole('heading', { name: 'Overview', level: 2 }),
    ).toBeInTheDocument()
    expect(screen.getByText('Coming soon')).toBeInTheDocument()
  })

  it('switches the content panel when a nav item is selected', async () => {
    const user = userEvent.setup()
    vi.stubGlobal(
      'fetch',
      vi.fn().mockResolvedValue({
        ok: true,
        json: async () => ({
          service: 'clustercanvas',
          version: '0.1.0',
        }),
      }),
    )

    render(<App />)

    await user.click(screen.getByRole('button', { name: 'VMs' }))
    expect(
      screen.getByRole('heading', { name: 'VMs', level: 2 }),
    ).toBeInTheDocument()

    await user.click(screen.getByRole('button', { name: 'Configuration' }))
    expect(
      screen.getByRole('heading', { name: 'Configuration', level: 2 }),
    ).toBeInTheDocument()
  })

  it('shows unavailable when backend status fetch fails', async () => {
    vi.stubGlobal(
      'fetch',
      vi.fn().mockResolvedValue({
        ok: false,
        status: 503,
      }),
    )

    render(<App />)

    expect(
      await screen.findByText('Backend Version unavailable'),
    ).toBeInTheDocument()
  })
})
