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 { ProductTypeForm } from '../../../features/product-types/components/ProductTypeForm'

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

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>,
  )
}

// ─── ProductTypeForm — field rendering ─────────────────────────────────────

describe('ProductTypeForm — field rendering', () => {
  it('renders nombre field and all flag checkboxes', () => {
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={vi.fn()} />,
    )
    expect(screen.getByLabelText(/nombre/i)).toBeInTheDocument()
    expect(screen.getByLabelText('Tiene duración')).toBeInTheDocument()
    expect(screen.getByLabelText('Requiere texto')).toBeInTheDocument()
    expect(screen.getByLabelText('Requiere categoría')).toBeInTheDocument()
    expect(screen.getByLabelText('Es bundle')).toBeInTheDocument()
    expect(screen.getByLabelText('Permite imágenes')).toBeInTheDocument()
  })

  it('renders multimedia fields when allowImages is true', async () => {
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={vi.fn()} defaultValues={{ allowImages: true }} />,
    )
    expect(screen.getByLabelText('Máx. imágenes')).toBeInTheDocument()
    expect(screen.getByLabelText('Máx. tamaño (MB)')).toBeInTheDocument()
    expect(screen.getByLabelText('Ancho máx. (px)')).toBeInTheDocument()
    expect(screen.getByLabelText('Alto máx. (px)')).toBeInTheDocument()
  })

  it('disables multimedia fields when allowImages is false', () => {
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={vi.fn()} defaultValues={{ allowImages: false }} />,
    )
    expect(screen.getByLabelText('Máx. imágenes')).toBeDisabled()
    expect(screen.getByLabelText('Máx. tamaño (MB)')).toBeDisabled()
    expect(screen.getByLabelText('Ancho máx. (px)')).toBeDisabled()
    expect(screen.getByLabelText('Alto máx. (px)')).toBeDisabled()
  })
})

// ─── ProductTypeForm — allowImages toggle ──────────────────────────────────

describe('ProductTypeForm — allowImages toggle', () => {
  it('enables multimedia fields after toggling allowImages on', async () => {
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={vi.fn()} defaultValues={{ allowImages: false }} />,
    )
    const allowImagesCheckbox = screen.getByLabelText('Permite imágenes')
    await userEvent.click(allowImagesCheckbox)
    await waitFor(() => {
      expect(screen.getByLabelText('Máx. imágenes')).not.toBeDisabled()
    })
  })
})

// ─── ProductTypeForm — validation ─────────────────────────────────────────

describe('ProductTypeForm — zod validation', () => {
  it('shows validation error when nombre is empty', async () => {
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={vi.fn()} />,
    )
    await userEvent.click(screen.getByRole('button', { name: /guardar|crear/i }))
    await waitFor(() => {
      expect(screen.getByText(/nombre.*requerido/i)).toBeInTheDocument()
    })
  })

  it('calls onSubmit with correct payload when form is valid', async () => {
    const onSubmit = vi.fn()
    wrap(
      <ProductTypeForm onSubmit={onSubmit} onCancel={vi.fn()} />,
    )
    await userEvent.type(screen.getByLabelText(/nombre/i), 'Clasificados')
    await userEvent.click(screen.getByRole('button', { name: /guardar|crear/i }))
    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalled()
      const payload = onSubmit.mock.calls[0][0]
      expect(payload).toMatchObject({ nombre: 'Clasificados' })
    })
  })

  it('normalizes multimedia fields to null when allowImages is false on submit', async () => {
    const onSubmit = vi.fn()
    wrap(
      <ProductTypeForm onSubmit={onSubmit} onCancel={vi.fn()} defaultValues={{ allowImages: false }} />,
    )
    await userEvent.type(screen.getByLabelText(/nombre/i), 'Sin imágenes')
    await userEvent.click(screen.getByRole('button', { name: /guardar|crear/i }))
    await waitFor(() => {
      expect(onSubmit).toHaveBeenCalled()
      const payload = onSubmit.mock.calls[0][0]
      expect(payload.maxImages).toBeNull()
      expect(payload.maxImageSizeMB).toBeNull()
      expect(payload.maxImageWidth).toBeNull()
      expect(payload.maxImageHeight).toBeNull()
    })
  })
})

// ─── ProductTypeForm — cancel ──────────────────────────────────────────────

describe('ProductTypeForm — cancel', () => {
  it('calls onCancel when cancel button is clicked', async () => {
    const onCancel = vi.fn()
    wrap(
      <ProductTypeForm onSubmit={vi.fn()} onCancel={onCancel} />,
    )
    await userEvent.click(screen.getByRole('button', { name: /cancelar/i }))
    expect(onCancel).toHaveBeenCalled()
  })
})
