import { useState, type FormEvent } from 'react'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Button } from '@/components/ui/button'
import { parseArgentinaDateTimeToUtc } from '@/lib/dateFormat'

/** Filtros crudos del form (todos strings para binding directo del input). */
export interface AuditFiltersValue {
  actor: string
  targetType: string
  targetId: string
  from: string
  to: string
}

// eslint-disable-next-line react-refresh/only-export-components -- constante de reset co-ubicada con el componente que la consume como valor inicial
export const EMPTY_FILTERS: AuditFiltersValue = {
  actor: '',
  targetType: '',
  targetId: '',
  from: '',
  to: '',
}

interface AuditFiltersProps {
  /** Valor inicial (útil cuando el padre mantiene el estado). */
  initialValue?: AuditFiltersValue
  onApply: (value: AuditFiltersValue) => void
  onReset: () => void
}

/**
 * 4 filtros + 2 fechas (from/to). Submit explícito vía botón "Aplicar".
 *
 * NO hace debounce — el usuario aprieta "Aplicar" o "Limpiar".
 * Eso evita pedidos intermedios cuando se escribe un GUID largo en targetId.
 */
export function AuditFilters({
  initialValue = EMPTY_FILTERS,
  onApply,
  onReset,
}: AuditFiltersProps) {
  const [value, setValue] = useState<AuditFiltersValue>(initialValue)

  function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault()
    onApply(value)
  }

  function handleReset() {
    setValue(EMPTY_FILTERS)
    onReset()
  }

  return (
    <form
      onSubmit={handleSubmit}
      className="surface p-4 space-y-4"
      aria-label="Filtros de auditoría"
    >
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
        <div className="space-y-1.5">
          <Label htmlFor="audit-actor">Usuario (ID)</Label>
          <Input
            id="audit-actor"
            type="number"
            inputMode="numeric"
            min={1}
            value={value.actor}
            onChange={(e) => setValue((v) => ({ ...v, actor: e.target.value }))}
            placeholder="Ej: 42"
          />
        </div>

        <div className="space-y-1.5">
          <Label htmlFor="audit-target-type">Tipo de entidad</Label>
          <Input
            id="audit-target-type"
            type="text"
            value={value.targetType}
            onChange={(e) =>
              setValue((v) => ({ ...v, targetType: e.target.value }))
            }
            placeholder="Ej: User, Role, Permission"
          />
        </div>

        <div className="space-y-1.5">
          <Label htmlFor="audit-target-id">ID de entidad</Label>
          <Input
            id="audit-target-id"
            type="text"
            value={value.targetId}
            onChange={(e) =>
              setValue((v) => ({ ...v, targetId: e.target.value }))
            }
            placeholder="Ej: 123 o un GUID"
          />
        </div>

        <div className="space-y-1.5">
          <Label htmlFor="audit-from">Desde</Label>
          <Input
            id="audit-from"
            type="datetime-local"
            value={value.from}
            onChange={(e) => setValue((v) => ({ ...v, from: e.target.value }))}
          />
        </div>

        <div className="space-y-1.5">
          <Label htmlFor="audit-to">Hasta</Label>
          <Input
            id="audit-to"
            type="datetime-local"
            value={value.to}
            onChange={(e) => setValue((v) => ({ ...v, to: e.target.value }))}
          />
        </div>
      </div>

      <div className="flex flex-wrap items-center justify-end gap-2">
        <Button type="button" variant="ghost" onClick={handleReset}>
          Limpiar
        </Button>
        <Button type="submit">Aplicar filtros</Button>
      </div>
    </form>
  )
}

/**
 * Convierte los valores del form (strings) al shape `AuditEventsFilter`
 * que espera el cliente de API.
 *
 * - `actor` vacío o NaN → omitido
 * - `from`/`to` vienen del `datetime-local` (hora ART implícita, sin timezone).
 *   Los convertimos a ISO UTC vía `parseArgentinaDateTimeToUtc()` (fix BUG-FE-05).
 * - Strings vacíos → omitidos.
 */
// eslint-disable-next-line react-refresh/only-export-components -- función utilitaria de mapeo co-ubicada con el componente que la necesita; extraerla a otro archivo aumentaría la fragmentación innecesariamente
export function toApiFilter(
  value: AuditFiltersValue,
): import('@/api/audit').AuditEventsFilter {
  const out: import('@/api/audit').AuditEventsFilter = {}

  if (value.actor.trim() !== '') {
    const n = Number(value.actor)
    if (Number.isFinite(n) && n > 0) out.actor = Math.floor(n)
  }
  if (value.targetType.trim() !== '') out.targetType = value.targetType.trim()
  if (value.targetId.trim() !== '') out.targetId = value.targetId.trim()
  if (value.from.trim() !== '') {
    // BUG-FE-05: interpretar el string como ART (-03:00), no como local del browser
    try { out.from = parseArgentinaDateTimeToUtc(value.from) } catch { /* invalid input */ }
  }
  if (value.to.trim() !== '') {
    try { out.to = parseArgentinaDateTimeToUtc(value.to) } catch { /* invalid input */ }
  }

  return out
}
