import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import { describe, it, expect, vi } from 'vitest'
import { BrowserRouter } from 'react-router-dom'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import EntitiesPage from '@/pages/EntitiesPage'
import * as entitiesApi from '@/api/entitiesApi'

vi.mock('@/api/entitiesApi')

const wrapper = ({ children }: { children: React.ReactNode }) => (
  <QueryClientProvider client={new QueryClient({ defaultOptions: { queries: { retry: false } } })}>
    <BrowserRouter>{children}</BrowserRouter>
  </QueryClientProvider>
)

const mockEntity = {
  id: 'entity-1',
  name: 'Test Entity',
  email: 'test@condado.com',
  jobTitle: 'Tester',
  personality: 'Formal',
  scheduleCron: '0 9 * * *',
  contextWindowDays: 3,
  active: true,
  createdAt: '2024-01-01T00:00:00',
}

describe('EntitiesPage', () => {
  it('should_renderEntityList_when_entitiesLoaded', async () => {
    vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity])
    render(<EntitiesPage />, { wrapper })
    await waitFor(() => {
      expect(screen.getByText('Test Entity')).toBeInTheDocument()
    })
  })

  it('should_openCreateDialog_when_addButtonClicked', async () => {
    vi.mocked(entitiesApi.getEntities).mockResolvedValue([])
    render(<EntitiesPage />, { wrapper })
    const addButton = screen.getByRole('button', { name: /add|create|new/i })
    fireEvent.click(addButton)
    await waitFor(() => {
      expect(screen.getByRole('dialog')).toBeInTheDocument()
      expect(screen.queryByLabelText(/default email context window/i)).not.toBeInTheDocument()
    })
  })

  it('should_submitDefaultContextWindow_when_createEntitySubmitted', async () => {
    vi.mocked(entitiesApi.getEntities).mockResolvedValue([])
    vi.mocked(entitiesApi.createEntity).mockResolvedValue(mockEntity)

    render(<EntitiesPage />, { wrapper })

    fireEvent.click(screen.getByRole('button', { name: /add|create|new/i }))

    await waitFor(() => {
      expect(screen.getByRole('dialog', { name: /create entity/i })).toBeInTheDocument()
    })

    fireEvent.change(screen.getByLabelText(/entity name/i), { target: { value: 'Test Entity' } })
    fireEvent.change(screen.getByLabelText(/sender email/i), { target: { value: 'test@condado.com' } })
    fireEvent.change(screen.getByLabelText(/job title/i), { target: { value: 'Tester' } })
    fireEvent.change(screen.getByLabelText(/personality notes/i), { target: { value: 'Formal' } })
    fireEvent.click(screen.getByRole('button', { name: /create/i }))

    await waitFor(() => {
      expect(entitiesApi.createEntity).toHaveBeenCalled()
      expect(vi.mocked(entitiesApi.createEntity).mock.calls[0]?.[0]).toEqual({
        name: 'Test Entity',
        email: 'test@condado.com',
        jobTitle: 'Tester',
        personality: 'Formal',
        contextWindowDays: 3,
      })
    })
  })

  it('should_callDeleteApi_when_deleteConfirmed', async () => {
    vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity])
    vi.mocked(entitiesApi.deleteEntity).mockResolvedValue(undefined)
    render(<EntitiesPage />, { wrapper })
    await waitFor(() => {
      expect(screen.getByText('Test Entity')).toBeInTheDocument()
    })
    const deleteButton = screen.getByRole('button', { name: /delete|deactivate/i })
    fireEvent.click(deleteButton)
    await waitFor(() => {
      expect(entitiesApi.deleteEntity).toHaveBeenCalledWith('entity-1')
    })
  })

  it('should_renderDetailLink_when_entitiesLoaded', async () => {
    vi.mocked(entitiesApi.getEntities).mockResolvedValue([mockEntity])
    render(<EntitiesPage />, { wrapper })

    await waitFor(() => {
      expect(screen.getByRole('link', { name: /open details/i })).toHaveAttribute('href', '/entities/entity-1')
    })
  })
})
