import { render, screen } from '@testing-library/react'
import { http, HttpResponse } from 'msw'
import { createMemoryRouter, RouterProvider } from 'react-router'
import { describe, expect, it } from 'vitest'
import { AuthProvider } from './auth/AuthProvider'
import { routes } from './router'
import { server } from './test/server'

/**
 * Smoke tests for the REAL route-object array (`routes` from ./router), driven
 * through `createMemoryRouter`. Unlike the guard/page component tests, these
 * exercise the actual shipped config end-to-end — catch-all redirect, both
 * guards, and the real pages — so a future swapped path/element regression in
 * router.tsx is caught here instead of only in hand-built test route trees.
 */
describe('app router config', () => {
  it('unknown paths redirect to the app root', async () => {
    server.use(
      http.get('http://localhost/api/me', () =>
        HttpResponse.json({ id: 'u1', email: 'a@b.com' }),
      ),
      http.get('http://localhost/api/scenarios', () =>
        HttpResponse.json({
          '@context': '/api/contexts/Scenario',
          '@id': '/api/scenarios',
          '@type': 'hydra:Collection',
          member: [
            {
              '@id': '/api/scenarios/11111111-1111-1111-1111-111111111111',
              '@type': 'Scenario',
              name: 'Emergency Fund',
              description: 'Rainy day savings',
            },
          ],
          totalItems: 1,
        }),
      ),
    )

    const router = createMemoryRouter(routes, {
      initialEntries: ['/some/unknown/path'],
    })

    render(
      <AuthProvider>
        <RouterProvider router={router} />
      </AuthProvider>,
    )

    expect(await screen.findByText('Emergency Fund')).toBeInTheDocument()
  })

  it('the /login route resolves to the login page for a guest', async () => {
    server.use(
      http.get('http://localhost/api/me', () =>
        HttpResponse.json({ message: 'unauthorized' }, { status: 401 }),
      ),
    )

    const router = createMemoryRouter(routes, { initialEntries: ['/login'] })

    render(
      <AuthProvider>
        <RouterProvider router={router} />
      </AuthProvider>,
    )

    expect(await screen.findByLabelText(/email/i)).toBeInTheDocument()
  })

  it('an authenticated user at /login is redirected to the app', async () => {
    server.use(
      http.get('http://localhost/api/me', () =>
        HttpResponse.json({ id: 'u1', email: 'a@b.com' }),
      ),
      http.get('http://localhost/api/scenarios', () =>
        HttpResponse.json({
          '@context': '/api/contexts/Scenario',
          '@id': '/api/scenarios',
          '@type': 'hydra:Collection',
          member: [
            {
              '@id': '/api/scenarios/11111111-1111-1111-1111-111111111111',
              '@type': 'Scenario',
              name: 'Emergency Fund',
              description: 'Rainy day savings',
            },
          ],
          totalItems: 1,
        }),
      ),
    )

    const router = createMemoryRouter(routes, { initialEntries: ['/login'] })

    render(
      <AuthProvider>
        <RouterProvider router={router} />
      </AuthProvider>,
    )

    expect(await screen.findByText('Emergency Fund')).toBeInTheDocument()
    expect(screen.queryByLabelText(/email/i)).not.toBeInTheDocument()
  })
})
