import { useEffect } from 'react'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from '@/components/ui/form'
import type { ProductTypeListItem } from '@/features/product-types/types'

// ─── Schema ───────────────────────────────────────────────────────────────────

function nullablePositiveInt() {
  return z
    .string()
    .optional()
    .transform((v) => (v === '' || v == null ? null : Number(v)))
    .pipe(z.number().int().positive().nullable())
}

const productFormSchema = z.object({
  nombre: z.string().trim().min(1, 'Nombre requerido').max(300, 'Máximo 300 caracteres'),
  medioId: z
    .string()
    .min(1, 'Medio requerido')
    .transform((v) => Number(v))
    .pipe(z.number().int().positive('Medio requerido')),
  productTypeId: z
    .string()
    .min(1, 'Tipo de producto requerido')
    .transform((v) => Number(v))
    .pipe(z.number().int().positive('Tipo de producto requerido')),
  rubroId: nullablePositiveInt(),
  basePrice: z
    .string()
    .min(1, 'Precio requerido')
    .transform((v) => Number(v))
    .pipe(z.number().min(0, 'El precio no puede ser negativo')),
  priceDurationDays: nullablePositiveInt(),
})

// Raw form field types (strings before zod transforms)
type ProductFormRaw = {
  nombre: string
  medioId: string
  productTypeId: string
  rubroId: string
  basePrice: string
  priceDurationDays: string
}

// Output type after zod transforms (what onSubmit receives at runtime)
export type ProductFormOutput = {
  nombre: string
  medioId: number
  productTypeId: number
  rubroId: number | null
  basePrice: number
  priceDurationDays: number | null
}

// ─── Props ────────────────────────────────────────────────────────────────────

export interface ProductFormDefaultValues {
  nombre?: string
  medioId?: number | null
  productTypeId?: number | null
  rubroId?: number | null
  basePrice?: number | null
  priceDurationDays?: number | null
}

interface ProductFormProps {
  productTypes: ProductTypeListItem[]
  defaultValues?: ProductFormDefaultValues
  onSubmit: (values: ProductFormOutput) => void
  onCancel: () => void
  isPending?: boolean
  isEdit?: boolean
}

// ─── Component ────────────────────────────────────────────────────────────────

export function ProductForm({
  productTypes,
  defaultValues,
  onSubmit,
  onCancel,
  isPending = false,
  isEdit = false,
}: ProductFormProps) {
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  const form = useForm<ProductFormRaw>({
    resolver: zodResolver(productFormSchema) as any,
    defaultValues: {
      nombre: defaultValues?.nombre ?? '',
      medioId: defaultValues?.medioId != null ? String(defaultValues.medioId) : '',
      productTypeId: defaultValues?.productTypeId != null ? String(defaultValues.productTypeId) : '',
      rubroId: defaultValues?.rubroId != null ? String(defaultValues.rubroId) : '',
      basePrice: defaultValues?.basePrice != null ? String(defaultValues.basePrice) : '',
      priceDurationDays: defaultValues?.priceDurationDays != null ? String(defaultValues.priceDurationDays) : '',
    },
  })

  useEffect(() => {
    form.reset({
      nombre: defaultValues?.nombre ?? '',
      medioId: defaultValues?.medioId != null ? String(defaultValues.medioId) : '',
      productTypeId: defaultValues?.productTypeId != null ? String(defaultValues.productTypeId) : '',
      rubroId: defaultValues?.rubroId != null ? String(defaultValues.rubroId) : '',
      basePrice: defaultValues?.basePrice != null ? String(defaultValues.basePrice) : '',
      priceDurationDays: defaultValues?.priceDurationDays != null ? String(defaultValues.priceDurationDays) : '',
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [defaultValues?.nombre, defaultValues?.medioId, defaultValues?.productTypeId])

  // Derive selected ProductType flags
  const productTypeIdStr = form.watch('productTypeId')
  const selectedProductTypeId = productTypeIdStr ? Number(productTypeIdStr) : null
  const selectedProductType = productTypes.find((pt) => pt.id === selectedProductTypeId) ?? null
  const requiresCategory = selectedProductType?.requiresCategory ?? false
  const hasDuration = selectedProductType?.hasDuration ?? false

  function handleSubmit(data: ProductFormOutput) {
    // Normalize conditional fields to null when not applicable
    const normalized: ProductFormOutput = {
      ...data,
      rubroId: requiresCategory ? data.rubroId : null,
      priceDurationDays: hasDuration ? data.priceDurationDays : null,
    }
    onSubmit(normalized)
  }

  return (
    <Form {...form}>
      <form
        onSubmit={form.handleSubmit(
          handleSubmit as unknown as Parameters<typeof form.handleSubmit>[0],
        )}
        className="space-y-4"
        noValidate
      >
        {/* Nombre */}
        <FormField
          control={form.control}
          name="nombre"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Nombre</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  type="text"
                  disabled={isPending}
                  placeholder="Nombre del producto"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        {/* Medio ID */}
        <FormField
          control={form.control}
          name="medioId"
          render={({ field }) => (
            <FormItem>
              <FormLabel>ID de Medio</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  type="number"
                  min={1}
                  disabled={isPending || isEdit}
                  placeholder="ID del medio"
                  aria-label="ID de Medio"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        {/* Product Type ID */}
        <FormField
          control={form.control}
          name="productTypeId"
          render={({ field }) => (
            <FormItem>
              <FormLabel>ID de Tipo de Producto</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  type="number"
                  min={1}
                  disabled={isPending || isEdit}
                  placeholder="ID del tipo de producto"
                  aria-label="ID de Tipo de Producto"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        {/* Rubro ID — only shown when requiresCategory=true */}
        {requiresCategory && (
          <FormField
            control={form.control}
            name="rubroId"
            render={({ field }) => (
              <FormItem>
                <FormLabel>ID de Rubro</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    type="number"
                    min={1}
                    disabled={isPending}
                    placeholder="ID del rubro"
                    aria-label="ID de Rubro"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
        )}

        {/* Base Price */}
        <FormField
          control={form.control}
          name="basePrice"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Precio base</FormLabel>
              <FormControl>
                <Input
                  {...field}
                  type="number"
                  min={0}
                  step={0.01}
                  disabled={isPending}
                  placeholder="0.00"
                  aria-label="Precio base"
                />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        {/* Price Duration Days — only shown when hasDuration=true */}
        {hasDuration && (
          <FormField
            control={form.control}
            name="priceDurationDays"
            render={({ field }) => (
              <FormItem>
                <FormLabel>Días de duración del precio</FormLabel>
                <FormControl>
                  <Input
                    {...field}
                    type="number"
                    min={1}
                    disabled={isPending}
                    placeholder="Días"
                    aria-label="Días de duración del precio"
                  />
                </FormControl>
                <FormMessage />
              </FormItem>
            )}
          />
        )}

        <div className="flex justify-end gap-2 pt-2">
          <Button
            type="button"
            variant="outline"
            onClick={onCancel}
            disabled={isPending}
          >
            Cancelar
          </Button>
          <Button type="submit" disabled={isPending}>
            {isPending ? 'Guardando...' : isEdit ? 'Guardar cambios' : 'Guardar'}
          </Button>
        </div>
      </form>
    </Form>
  )
}
