import { describe, it, expect, beforeEach } from 'vitest'
import { screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { http, HttpResponse } from 'msw'
import { server } from '@/test/mocks/server'
import { renderWithProviders } from '@/test/utils'
import { AdminUsersPage } from '@/pages/AdminUsersPage'

describe('AdminUsersPage', () => {
  beforeEach(() => {
    localStorage.setItem('access_token', 'test-token')
  })

  it('renders user list with user data', async () => {
    renderWithProviders(<AdminUsersPage />, { initialRoute: '/admin/users' })

    await waitFor(() => {
      // mockUserResponse has username 'admin_user', email 'admin@dak.de', role 'admin'
      expect(screen.getByText('admin_user')).toBeInTheDocument()
    })

    expect(screen.getByText('admin@dak.de')).toBeInTheDocument()
    expect(screen.getByText('Admin')).toBeInTheDocument()
    // "Aktiv" appears both as table header and badge; check for at least 2
    const aktivElements = screen.getAllByText('Aktiv')
    expect(aktivElements.length).toBeGreaterThanOrEqual(2)
  })

  it('shows "Neuen Benutzer erstellen" button and opens dialog', async () => {
    const user = userEvent.setup()
    renderWithProviders(<AdminUsersPage />, { initialRoute: '/admin/users' })

    await waitFor(() => {
      expect(screen.getByText('Neuen Benutzer erstellen')).toBeInTheDocument()
    })

    // Click the create button to open the dialog
    await user.click(screen.getByText('Neuen Benutzer erstellen'))

    // Dialog should open with form fields
    await waitFor(() => {
      expect(screen.getByLabelText('Benutzername')).toBeInTheDocument()
    })
    expect(screen.getByLabelText('E-Mail')).toBeInTheDocument()
    expect(screen.getByLabelText('Passwort')).toBeInTheDocument()
  })

  it('handles empty user list', async () => {
    server.use(
      http.get('/api/admin/users', () => {
        return HttpResponse.json([])
      }),
    )

    renderWithProviders(<AdminUsersPage />, { initialRoute: '/admin/users' })

    await waitFor(() => {
      expect(screen.getByText('Keine Benutzer gefunden.')).toBeInTheDocument()
    })
  })

  it('shows loading state', () => {
    server.use(
      http.get('/api/admin/users', async () => {
        await new Promise((resolve) => setTimeout(resolve, 500))
        return HttpResponse.json([])
      }),
    )

    renderWithProviders(<AdminUsersPage />, { initialRoute: '/admin/users' })

    // Heading is always visible
    expect(screen.getByText('Benutzer')).toBeInTheDocument()

    // During loading, user data should not be visible yet
    expect(screen.queryByText('admin_user')).not.toBeInTheDocument()
    expect(screen.queryByText('Keine Benutzer gefunden.')).not.toBeInTheDocument()
  })

  it('shows error state on API failure', async () => {
    server.use(
      http.get('/api/admin/users', () => {
        return new HttpResponse(null, { status: 500 })
      }),
    )

    renderWithProviders(<AdminUsersPage />, { initialRoute: '/admin/users' })

    // When the query fails, users defaults to [] so it should show empty state
    await waitFor(() => {
      expect(screen.getByText('Keine Benutzer gefunden.')).toBeInTheDocument()
    })
  })
})
