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 { DeactivateMedioModal } from '../../../features/medios/components/DeactivateMedioModal'

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

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

const server = setupServer()

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

function renderModal(activo = true) {
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  })
  return render(
    <QueryClientProvider client={qc}>
      <MemoryRouter>
        <DeactivateMedioModal medioId={1} medioNombre="Diario El Día" activo={activo} />
      </MemoryRouter>
    </QueryClientProvider>,
  )
}

describe('DeactivateMedioModal', () => {
  it('shows "Desactivar" trigger when medio is active', () => {
    renderModal(true)
    expect(screen.getByRole('button', { name: /desactivar/i })).toBeInTheDocument()
  })

  it('shows "Reactivar" trigger when medio is inactive', () => {
    renderModal(false)
    expect(screen.getByRole('button', { name: /reactivar/i })).toBeInTheDocument()
  })

  it('opens dialog and shows confirmation text', async () => {
    renderModal(true)
    await userEvent.click(screen.getByRole('button', { name: /desactivar/i }))
    await waitFor(() =>
      expect(screen.getByText(/desactivar medio/i)).toBeInTheDocument(),
    )
    expect(screen.getByText(/diario el día/i)).toBeInTheDocument()
  })

  it('calls deactivate endpoint on confirm and invalidates query', async () => {
    let called = false
    server.use(
      http.post(`${API_URL}/api/v1/admin/medios/1/deactivate`, () => {
        called = true
        return new HttpResponse(null, { status: 204 })
      }),
    )

    renderModal(true)
    await userEvent.click(screen.getByRole('button', { name: /desactivar/i }))
    await waitFor(() => screen.getByRole('alertdialog'))
    await userEvent.click(screen.getByRole('button', { name: /desactivar$/i }))

    await waitFor(() => expect(called).toBe(true))
  })

  it('calls reactivate endpoint on confirm when inactive', async () => {
    let called = false
    server.use(
      http.post(`${API_URL}/api/v1/admin/medios/1/reactivate`, () => {
        called = true
        return new HttpResponse(null, { status: 204 })
      }),
    )

    renderModal(false)
    await userEvent.click(screen.getByRole('button', { name: /reactivar/i }))
    await waitFor(() => screen.getByRole('alertdialog'))
    await userEvent.click(screen.getByRole('button', { name: /reactivar$/i }))

    await waitFor(() => expect(called).toBe(true))
  })
})
