import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
import Contact from '../app/kontakt/page'

// Mock fetch
const fetchMock = vi.fn()
global.fetch = fetchMock

// Mock alert
const alertMock = vi.fn()
global.alert = alertMock

describe('Contact Page', () => {
  beforeEach(() => {
    fetchMock.mockClear()
    alertMock.mockClear()
  })

  it('renders the contact form correctly', () => {
    render(<Contact />)
    
    expect(screen.getByLabelText(/Name \*/i)).toBeInTheDocument()
    expect(screen.getByLabelText(/Firma/i)).toBeInTheDocument()
    expect(screen.getByLabelText(/E-Mail \*/i)).toBeInTheDocument()
    expect(screen.getByLabelText(/Nachricht \*/i)).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /Nachricht senden/i })).toBeInTheDocument()
  })

  it('submits the form successfully', async () => {
    fetchMock.mockResolvedValueOnce({
      ok: true,
      json: async () => ({ success: true }),
    })

    render(<Contact />)

    fireEvent.change(screen.getByLabelText(/Name \*/i), { target: { value: 'John Doe' } })
    fireEvent.change(screen.getByLabelText(/Firma/i), { target: { value: 'Acme Corp' } })
    fireEvent.change(screen.getByLabelText(/E-Mail \*/i), { target: { value: 'john@example.com' } })
    fireEvent.change(screen.getByLabelText(/Nachricht \*/i), { target: { value: 'This is a test message that is long enough.' } })

    fireEvent.click(screen.getByRole('button', { name: /Nachricht senden/i }))

    await waitFor(() => {
      expect(fetchMock).toHaveBeenCalledTimes(1)
      expect(fetchMock).toHaveBeenCalledWith('/api/contact', expect.objectContaining({
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          name: 'John Doe',
          company: 'Acme Corp',
          email: 'john@example.com',
          message: 'This is a test message that is long enough.',
          website: ''
        }),
      }))
    })

    expect(screen.getByText(/Nachricht gesendet/i)).toBeInTheDocument()
    expect(screen.getByText(/Vielen Dank für Ihre Anfrage/i)).toBeInTheDocument()
  })

  it('handles submission errors', async () => {
    fetchMock.mockResolvedValueOnce({
      ok: false,
      json: async () => ({ error: 'Server error' }),
    })

    render(<Contact />)

    fireEvent.change(screen.getByLabelText(/Name \*/i), { target: { value: 'John Doe' } })
    fireEvent.change(screen.getByLabelText(/E-Mail \*/i), { target: { value: 'john@example.com' } })
    fireEvent.change(screen.getByLabelText(/Nachricht \*/i), { target: { value: 'This is a test message that is long enough.' } })

    fireEvent.click(screen.getByRole('button', { name: /Nachricht senden/i }))

    await waitFor(() => {
      expect(alertMock).toHaveBeenCalledWith('Fehler: Server error')
    })
  })

  it('handles network errors', async () => {
    fetchMock.mockRejectedValueOnce(new Error('Network error'))

    render(<Contact />)

    fireEvent.change(screen.getByLabelText(/Name \*/i), { target: { value: 'John Doe' } })
    fireEvent.change(screen.getByLabelText(/E-Mail \*/i), { target: { value: 'john@example.com' } })
    fireEvent.change(screen.getByLabelText(/Nachricht \*/i), { target: { value: 'This is a test message that is long enough.' } })

    fireEvent.click(screen.getByRole('button', { name: /Nachricht senden/i }))

    await waitFor(() => {
      expect(alertMock).toHaveBeenCalledWith('Es gab einen Fehler beim Senden Ihrer Nachricht.')
    })
  })
})
