import { describe, it, expect, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { MemoryRouter } from 'react-router-dom'
import React from 'react'
import { DeactivateProductTypeDialog } from '../../../features/product-types/components/DeactivateProductTypeDialog'
import type { ProductTypeListItem } from '../../../features/product-types/types'

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

const sampleProductType: ProductTypeListItem = {
  id: 1,
  nombre: 'Clasificados',
  hasDuration: true,
  requiresText: false,
  requiresCategory: false,
  isBundle: false,
  allowImages: false,
  isActive: true,
}

function wrap(children: React.ReactNode) {
  const qc = new QueryClient({
    defaultOptions: { queries: { retry: false }, mutations: { retry: false } },
  })
  return render(
    <QueryClientProvider client={qc}>
      <MemoryRouter>{children}</MemoryRouter>
    </QueryClientProvider>,
  )
}

describe('DeactivateProductTypeDialog', () => {
  it('renders confirmation message with product type name', () => {
    wrap(
      <DeactivateProductTypeDialog
        open={true}
        onOpenChange={vi.fn()}
        productType={sampleProductType}
        onConfirm={vi.fn()}
      />,
    )
    expect(screen.getByText(/Clasificados/i)).toBeInTheDocument()
    expect(screen.getByRole('heading', { name: /desactivar tipo/i })).toBeInTheDocument()
  })

  it('calls onConfirm with product type id when user confirms', async () => {
    const onConfirm = vi.fn().mockResolvedValue(undefined)
    wrap(
      <DeactivateProductTypeDialog
        open={true}
        onOpenChange={vi.fn()}
        productType={sampleProductType}
        onConfirm={onConfirm}
      />,
    )
    const buttons = screen.getAllByRole('button', { name: /desactivar/i })
    const confirmBtn = buttons.find((b) => b.textContent?.trim() === 'Desactivar')!
    await userEvent.click(confirmBtn)
    await waitFor(() => expect(onConfirm).toHaveBeenCalledWith(sampleProductType.id))
  })

  it('shows inline error when backend returns 409 EnUso', async () => {
    const onConfirm = vi.fn(() =>
      Promise.reject({
        response: { status: 409, data: { message: 'No se puede desactivar: el tipo está en uso por Products.' } },
      }),
    )
    wrap(
      <DeactivateProductTypeDialog
        open={true}
        onOpenChange={vi.fn()}
        productType={sampleProductType}
        onConfirm={onConfirm}
      />,
    )
    const buttons = screen.getAllByRole('button', { name: /desactivar/i })
    const confirmBtn = buttons.find((b) => b.textContent?.trim() === 'Desactivar')!
    await userEvent.click(confirmBtn)
    await waitFor(() => {
      expect(screen.getByText(/en uso/i)).toBeInTheDocument()
    })
  })

  it('closes dialog when cancel is clicked', async () => {
    const onOpenChange = vi.fn()
    wrap(
      <DeactivateProductTypeDialog
        open={true}
        onOpenChange={onOpenChange}
        productType={sampleProductType}
        onConfirm={vi.fn()}
      />,
    )
    await userEvent.click(screen.getByRole('button', { name: /cancelar/i }))
    await waitFor(() => expect(onOpenChange).toHaveBeenCalled())
  })
})
