import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import { http, HttpResponse } from 'msw'
import { setupServer } from 'msw/node'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
import { EditMedioPage } from '../../../features/medios/pages/EditMedioPage'

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

const mockNavigate = vi.fn()
vi.mock('react-router-dom', async (importOriginal) => {
  const actual = await importOriginal<typeof import('react-router-dom')>()
  return { ...actual, useNavigate: () => mockNavigate }
})

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

const sampleMedio = {
  id: 5,
  codigo: 'WEB01',
  nombre: 'Portal Web',
  tipo: 3,
  plataformaEmpresaId: 42,
  activo: true,
  fechaCreacion: '2026-01-01T00:00:00Z',
  fechaModificacion: null,
}

const server = setupServer()

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

function renderPage(id = '5') {
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  })
  return render(
    <QueryClientProvider client={qc}>
      <MemoryRouter initialEntries={[`/admin/medios/${id}/edit`]}>
        <Routes>
          <Route path="/admin/medios/:id/edit" element={<EditMedioPage />} />
        </Routes>
      </MemoryRouter>
    </QueryClientProvider>,
  )
}

describe('EditMedioPage', () => {
  it('shows loading state initially', () => {
    server.use(
      http.get(`${API_URL}/api/v1/admin/medios/5`, () =>
        HttpResponse.json(sampleMedio),
      ),
    )

    renderPage()
    expect(screen.getByText(/cargando/i)).toBeInTheDocument()
  })

  it('loads and pre-fills form with medio data', async () => {
    server.use(
      http.get(`${API_URL}/api/v1/admin/medios/5`, () =>
        HttpResponse.json(sampleMedio),
      ),
    )

    renderPage()

    await waitFor(() =>
      expect((screen.getByLabelText(/nombre/i) as HTMLInputElement).value).toBe('Portal Web'),
    )
    expect((screen.getByLabelText(/código/i) as HTMLInputElement).value).toBe('WEB01')
    // Código disabled in edit mode
    expect((screen.getByLabelText(/código/i) as HTMLInputElement).disabled).toBe(true)
  })

  it('shows "Medio no encontrado" when 404', async () => {
    server.use(
      http.get(`${API_URL}/api/v1/admin/medios/999`, () =>
        new HttpResponse(null, { status: 404 }),
      ),
    )

    renderPage('999')

    await waitFor(() =>
      expect(screen.getByText(/medio no encontrado/i)).toBeInTheDocument(),
    )
  })

  it('shows "Guardar cambios" button in edit mode', async () => {
    server.use(
      http.get(`${API_URL}/api/v1/admin/medios/5`, () =>
        HttpResponse.json(sampleMedio),
      ),
    )

    renderPage()

    await waitFor(() =>
      expect(screen.getByRole('button', { name: /guardar cambios/i })).toBeInTheDocument(),
    )
  })
})
