import { describe, it, expect, beforeEach, vi } 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 { LoginPage } from '@/pages/LoginPage'

// Mock window.matchMedia for useTheme hook
Object.defineProperty(window, 'matchMedia', {
  writable: true,
  value: vi.fn().mockImplementation((query: string) => ({
    matches: false,
    media: query,
    onchange: null,
    addListener: vi.fn(),
    removeListener: vi.fn(),
    addEventListener: vi.fn(),
    removeEventListener: vi.fn(),
    dispatchEvent: vi.fn(),
  })),
})

describe('LoginPage', () => {
  beforeEach(() => {
    // LoginPage is for unauthenticated users — do NOT set access_token
    localStorage.removeItem('access_token')
    localStorage.removeItem('refresh_token')

    // Override /api/auth/me to return 401 for unauthenticated state
    server.use(
      http.get('/api/auth/me', () => {
        return new HttpResponse(null, { status: 401 })
      }),
    )
  })

  it('renders email and password input fields', () => {
    renderWithProviders(<LoginPage />, { initialRoute: '/login' })

    expect(screen.getByLabelText('E-Mail')).toBeInTheDocument()
    expect(screen.getByLabelText('Passwort')).toBeInTheDocument()
  })

  it('renders submit button', () => {
    renderWithProviders(<LoginPage />, { initialRoute: '/login' })

    expect(screen.getByRole('button', { name: 'Anmelden' })).toBeInTheDocument()
  })

  it('shows error message on failed login', async () => {
    const user = userEvent.setup()

    // Override login endpoint to return 401
    server.use(
      http.post('/api/auth/login', () => {
        return HttpResponse.json(
          { detail: 'Invalid credentials' },
          { status: 401 },
        )
      }),
    )

    renderWithProviders(<LoginPage />, { initialRoute: '/login' })

    // Fill in valid form data
    await user.type(screen.getByLabelText('E-Mail'), 'wrong@dak.de')
    await user.type(screen.getByLabelText('Passwort'), 'wrongpassword')

    // Submit the form
    await user.click(screen.getByRole('button', { name: 'Anmelden' }))

    // Should show error message for 401
    await waitFor(() => {
      expect(screen.getByText('Ungueltige Anmeldedaten')).toBeInTheDocument()
    })
  })

  it('shows validation errors for empty form submission', async () => {
    const user = userEvent.setup()

    renderWithProviders(<LoginPage />, { initialRoute: '/login' })

    // Click submit without filling in any fields
    await user.click(screen.getByRole('button', { name: 'Anmelden' }))

    // Zod validation errors should appear
    await waitFor(() => {
      expect(screen.getByText('Bitte geben Sie eine gueltige E-Mail-Adresse ein')).toBeInTheDocument()
    })

    expect(screen.getByText('Passwort ist erforderlich')).toBeInTheDocument()
  })
})
