import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter } from 'react-router-dom'
import { SeccionesFilters } from '../../../features/secciones/components/SeccionesFilters'

const API_URL = 'http://localhost:5000'

vi.mock('sonner', () => ({
  toast: { success: vi.fn(), error: vi.fn() },
}))

const mockMedios = [
  { id: 1, codigo: 'DIA01', nombre: 'Diario El Día', tipo: 1, plataformaEmpresaId: null, activo: true },
  { id: 2, codigo: 'RAD01', nombre: 'Radio AM', tipo: 2, plataformaEmpresaId: null, activo: true },
  { id: 3, codigo: 'WEB01', nombre: 'Portal Web', tipo: 3, plataformaEmpresaId: null, activo: true },
]

const server = setupServer()

beforeAll(() => server.listen({ onUnhandledRequest: 'error' }))
afterEach(() => {
  server.resetHandlers()
  vi.clearAllMocks()
})
afterAll(() => server.close())

function renderFilters(handlers = {
  onMedioIdChange: vi.fn(),
  onTipoChange: vi.fn(),
  onActivoChange: vi.fn(),
  onSearchChange: vi.fn(),
}) {
  server.use(
    http.get(`${API_URL}/api/v1/admin/medios`, () =>
      HttpResponse.json({ items: mockMedios, page: 1, pageSize: 200, total: 3 }),
    ),
  )
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  })
  render(
    <QueryClientProvider client={qc}>
      <MemoryRouter>
        <SeccionesFilters {...handlers} />
      </MemoryRouter>
    </QueryClientProvider>,
  )
  return handlers
}

describe('SeccionesFilters', () => {
  it('loads medios options from API', async () => {
    renderFilters()

    // Open the Medio Radix Select to see options in the portal
    const medioTrigger = await screen.findByRole('combobox', { name: /medio/i })
    await userEvent.click(medioTrigger)

    await waitFor(() =>
      expect(screen.getByRole('option', { name: 'Diario El Día' })).toBeInTheDocument(),
    )
    expect(screen.getByRole('option', { name: 'Radio AM' })).toBeInTheDocument()
    expect(screen.getByRole('option', { name: 'Portal Web' })).toBeInTheDocument()
  })

  it('calls onMedioIdChange when medio is selected', async () => {
    const handlers = renderFilters()

    // Open Medio trigger, wait for options to load, then pick one
    const medioTrigger = await screen.findByRole('combobox', { name: /medio/i })
    await userEvent.click(medioTrigger)

    await waitFor(() =>
      expect(screen.getByRole('option', { name: 'Diario El Día' })).toBeInTheDocument(),
    )

    await userEvent.click(screen.getByRole('option', { name: 'Diario El Día' }))
    expect(handlers.onMedioIdChange).toHaveBeenCalledWith(1)
  })

  it('calls onTipoChange when tipo is selected', async () => {
    const handlers = renderFilters()

    // Open Tipo de sección trigger and pick an option
    const tipoTrigger = screen.getByRole('combobox', { name: /tipo de sección/i })
    await userEvent.click(tipoTrigger)

    await waitFor(() =>
      expect(screen.getByRole('option', { name: 'Clasificados' })).toBeInTheDocument(),
    )

    await userEvent.click(screen.getByRole('option', { name: 'Clasificados' }))
    expect(handlers.onTipoChange).toHaveBeenCalledWith('clasificados')
  })

  it('calls onActivoChange when estado is selected', async () => {
    const handlers = renderFilters()

    // Open Estado trigger and pick Activos
    const estadoTrigger = screen.getByRole('combobox', { name: /estado/i })
    await userEvent.click(estadoTrigger)

    await waitFor(() =>
      expect(screen.getByRole('option', { name: 'Activos' })).toBeInTheDocument(),
    )

    await userEvent.click(screen.getByRole('option', { name: 'Activos' }))
    expect(handlers.onActivoChange).toHaveBeenCalledWith(true)
  })

  it('renders all tipo options', async () => {
    renderFilters()

    // Open Tipo de sección trigger to see options in portal
    const tipoTrigger = screen.getByRole('combobox', { name: /tipo de sección/i })
    await userEvent.click(tipoTrigger)

    await waitFor(() =>
      expect(screen.getByRole('option', { name: 'Clasificados' })).toBeInTheDocument(),
    )
    expect(screen.getByRole('option', { name: 'Notables' })).toBeInTheDocument()
    expect(screen.getByRole('option', { name: 'Suplementos' })).toBeInTheDocument()
  })
})
