// T600.4 — TDD: TipoDeIvaTable
// RED: tests escritos ANTES de la implementación del componente
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 { TooltipProvider } from '@/components/ui/tooltip'
import { TipoDeIvaTable } from '../../../../features/fiscal/iva/components/TipoDeIvaTable'
import type { TipoDeIva } from '../../../../features/fiscal/iva/types/tipoDeIva.types'

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

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

const makeTiposDeIva = (): TipoDeIva[] => [
  {
    id: 1,
    codigo: 'EXENTO',
    descripcion: 'Exento',
    porcentaje: 0,
    vigenciaDesde: '2020-01-01',
    vigenciaHasta: null,
    activo: true,
    aplicaIVA: false,
    predecesorId: null,
  },
  {
    id: 2,
    codigo: 'IVA_21',
    descripcion: 'IVA 21%',
    porcentaje: 21,
    vigenciaDesde: '2020-01-01',
    vigenciaHasta: null,
    activo: true,
    aplicaIVA: true,
    predecesorId: null,
  },
  {
    id: 3,
    codigo: 'NO_GRAVADO',
    descripcion: 'No Gravado',
    porcentaje: 0,
    vigenciaDesde: '2020-01-01',
    vigenciaHasta: '2025-12-31',
    activo: false,
    aplicaIVA: false,
    predecesorId: null,
  },
]

const server = setupServer()

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

function renderTable(
  rows: TipoDeIva[] = makeTiposDeIva(),
  opts: {
    onEdit?: (row: TipoDeIva) => void
    onNuevaVersion?: (row: TipoDeIva) => void
  } = {},
) {
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  })
  const onEdit = opts.onEdit ?? vi.fn()
  const onNuevaVersion = opts.onNuevaVersion ?? vi.fn()

  render(
    <QueryClientProvider client={qc}>
      <MemoryRouter>
        <TooltipProvider>
          <TipoDeIvaTable
            rows={rows}
            onEdit={onEdit}
            onNuevaVersion={onNuevaVersion}
          />
        </TooltipProvider>
      </MemoryRouter>
    </QueryClientProvider>,
  )
  return { onEdit, onNuevaVersion }
}

describe('TipoDeIvaTable', () => {
  it('renders 3 rows with correct data', () => {
    renderTable()

    // Código y descripción presentes
    expect(screen.getByText('EXENTO')).toBeInTheDocument()
    expect(screen.getByText('IVA 21%')).toBeInTheDocument()
    expect(screen.getByText('NO_GRAVADO')).toBeInTheDocument()
  })

  it('renders porcentaje formateado como porcentaje', () => {
    renderTable()
    // IVA_21 tiene 21%
    expect(screen.getByText('21%')).toBeInTheDocument()
  })

  it('muestra "Activo" badge para items activos', () => {
    renderTable()
    const activoBadges = screen.getAllByText('Activo')
    expect(activoBadges.length).toBeGreaterThanOrEqual(2) // EXENTO e IVA_21
  })

  it('muestra "Inactivo" badge para items inactivos', () => {
    renderTable()
    expect(screen.getByText('Inactivo')).toBeInTheDocument() // NO_GRAVADO
  })

  it('vigenciaHasta null muestra "abierta"', () => {
    renderTable()
    const abiertaCells = screen.getAllByText(/abierta/i)
    expect(abiertaCells.length).toBeGreaterThanOrEqual(2) // EXENTO e IVA_21
  })

  it('click en "Editar" dispara onEdit con la fila correcta', async () => {
    const { onEdit } = renderTable()

    const editButtons = screen.getAllByRole('button', { name: /editar/i })
    await userEvent.click(editButtons[0])

    expect(onEdit).toHaveBeenCalledTimes(1)
    expect(onEdit).toHaveBeenCalledWith(
      expect.objectContaining({ codigo: 'EXENTO' }),
    )
  })

  it('click en "Nueva vigencia" dispara onNuevaVersion con la fila correcta', async () => {
    const { onNuevaVersion } = renderTable()

    // El segundo item es IVA_21 (el que tiene porcentaje)
    const nuevaVigButtons = screen.getAllByRole('button', { name: /nueva vigencia/i })
    await userEvent.click(nuevaVigButtons[1])

    expect(onNuevaVersion).toHaveBeenCalledTimes(1)
    expect(onNuevaVersion).toHaveBeenCalledWith(
      expect.objectContaining({ codigo: 'IVA_21' }),
    )
  })

  it('tabla vacía muestra mensaje de sin resultados', () => {
    renderTable([])
    expect(screen.getByText(/sin resultados/i)).toBeInTheDocument()
  })
})

// T600.4 — TRIANGULATE: Historial tooltip hover
describe('TipoDeIvaTable — historial tooltip', () => {
  it('columna Versión muestra botón de historial por fila', () => {
    renderTable()
    // Cada fila debe tener acceso al historial
    const histBtns = screen.getAllByRole('button', { name: /historial/i })
    expect(histBtns.length).toBeGreaterThanOrEqual(1)
  })

  it('hover en botón historial dispara request al backend', async () => {
    let historialCalled = false
    server.use(
      http.get(`${API_URL}/api/v1/admin/fiscal/iva/:id/historial`, () => {
        historialCalled = true
        return HttpResponse.json([
          {
            id: 2,
            codigo: 'IVA_21',
            porcentaje: 21,
            vigenciaDesde: '2020-01-01',
            vigenciaHasta: null,
            activo: true,
            predecesorId: null,
            depth: 0,
          },
        ])
      }),
    )

    renderTable()

    const histBtns = screen.getAllByRole('button', { name: /historial/i })
    await userEvent.hover(histBtns[1]) // IVA_21

    await waitFor(() => expect(historialCalled).toBe(true), { timeout: 2000 })
  })
})
