import * as React from "react"
import { IconX } from "@tabler/icons-react"

import { Badge } from "@/components/ui/badge"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"

type MultiValueInputProps = {
  values: string[]
  onChange: (values: string[]) => void
  placeholder?: string
  disabled?: boolean
  maxItems?: number
  addOnBlur?: boolean
  className?: string
  inputClassName?: string
  validate?: (value: string) => string | null
  format?: (value: string) => string
  emptyState?: React.ReactNode
}

export function MultiValueInput({
  values,
  onChange,
  placeholder,
  disabled,
  maxItems,
  addOnBlur,
  className,
  inputClassName,
  validate,
  format,
  emptyState,
}: MultiValueInputProps) {
  const [pending, setPending] = React.useState("")
  const [error, setError] = React.useState<string | null>(null)
  const inputRef = React.useRef<HTMLInputElement | null>(null)

  const remainingSlots = typeof maxItems === "number" ? Math.max(maxItems - values.length, 0) : undefined
  const canAdd = remainingSlots === undefined || remainingSlots > 0

  const addValue = React.useCallback(
    (raw: string) => {
      const trimmed = raw.trim()
      if (!trimmed) return
      const formatted = format ? format(trimmed) : trimmed
      if (values.includes(formatted)) {
        setPending("")
        setError(null)
        return
      }
      if (validate) {
        const validation = validate(formatted)
        if (validation) {
          setError(validation)
          return
        }
      }
      setError(null)
      onChange([...values, formatted])
      setPending("")
    },
    [format, onChange, validate, values]
  )

  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === "Enter" || event.key === "," || event.key === "Tab") {
      if (!canAdd) return
      event.preventDefault()
      addValue(pending)
    }
    if (event.key === "Backspace" && pending.length === 0 && values.length > 0) {
      onChange(values.slice(0, -1))
      setError(null)
    }
  }

  const handleBlur = () => {
    if (addOnBlur && pending.trim()) {
      addValue(pending)
    }
  }

  const removeValue = (value: string) => {
    onChange(values.filter((item) => item !== value))
    setError(null)
    inputRef.current?.focus()
  }

  return (
    <div className={cn("space-y-2", className)}>
      <div
        className={cn(
          "flex flex-wrap gap-2 rounded-md border border-input bg-background px-3 py-2 focus-within:ring-2 focus-within:ring-ring",
          disabled && "opacity-60"
        )}
      >
        {values.map((value) => (
          <Badge
            key={value}
            variant="secondary"
            className="flex items-center gap-1 rounded-full px-2 py-1 text-xs font-medium"
          >
            <span>{value}</span>
            <button
              type="button"
              className="flex h-4 w-4 items-center justify-center rounded-full bg-muted text-muted-foreground hover:bg-muted/80"
              onClick={() => removeValue(value)}
              aria-label={`Remover ${value}`}
              disabled={disabled}
            >
              <IconX className="h-3 w-3" strokeWidth={2} />
            </button>
          </Badge>
        ))}
        {canAdd ? (
          <Input
            ref={inputRef}
            value={pending}
            onChange={(event) => {
              setPending(event.target.value)
              setError(null)
            }}
            onKeyDown={handleKeyDown}
            onBlur={handleBlur}
            placeholder={values.length === 0 ? placeholder : undefined}
            disabled={disabled}
            className={cn(
              "m-0 h-auto min-w-[8rem] flex-1 border-0 bg-transparent px-0 py-1 text-sm shadow-none focus-visible:ring-0",
              inputClassName
            )}
          />
        ) : null}
      </div>
      {error ? <p className="text-xs font-medium text-destructive">{error}</p> : null}
      {!values.length && emptyState ? <div className="text-xs text-muted-foreground">{emptyState}</div> : null}
      {typeof remainingSlots === "number" ? (
        <div className="text-right text-[11px] text-muted-foreground">
          {remainingSlots} item{remainingSlots === 1 ? "" : "s"} restantes
        </div>
      ) : null}
    </div>
  )
}
