"use client"

import { useMemo, useRef, useState } from "react"
import { X } from "lucide-react"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import {
  Popover,
  PopoverContent,
  PopoverTrigger,
} from "@/components/ui/popover"
import type { AiModelCatalogEntry } from "@/lib/admin-settings/org-settings-types"
import { cn } from "@/lib/utils"

const VISIBLE_SUGGESTIONS = 5
const SUGGESTION_ROW_HEIGHT_REM = 2.25

function modelKey(entry: AiModelCatalogEntry) {
  return entry.model_id
}

function chipLabel(entry: AiModelCatalogEntry) {
  const label = entry.label.trim()
  return label && label !== entry.model_id ? label : entry.model_id
}

export function AiAuthorizedModelPicker({
  models,
  onChange,
  availableModelIds,
  disabled,
  emptyHint,
}: {
  models: AiModelCatalogEntry[]
  onChange: (models: AiModelCatalogEntry[]) => void
  availableModelIds: string[]
  disabled?: boolean
  emptyHint?: string
}) {
  const [query, setQuery] = useState("")
  const [focused, setFocused] = useState(false)
  const [activeIndex, setActiveIndex] = useState(0)
  const blurTimer = useRef<number | null>(null)

  const taken = useMemo(() => new Set(models.map((m) => m.model_id)), [models])

  const suggestions = useMemo(() => {
    const q = query.trim().toLowerCase()
    const pool = availableModelIds.filter((id) => !taken.has(id))
    const matches = q ? pool.filter((id) => id.toLowerCase().includes(q)) : pool
    return matches.sort((a, b) => a.localeCompare(b))
  }, [availableModelIds, query, taken])

  const showSuggestions = focused && !disabled && suggestions.length > 0

  function addModel(modelId: string) {
    const id = modelId.trim()
    if (!id || taken.has(id)) return
    onChange([...models, { model_id: id, label: id, enabled: true }])
    setQuery("")
    setActiveIndex(0)
  }

  function removeModel(modelId: string) {
    onChange(models.filter((entry) => entry.model_id !== modelId))
  }

  function updateLabel(modelId: string, label: string) {
    onChange(
      models.map((entry) =>
        entry.model_id === modelId ? { ...entry, label } : entry,
      ),
    )
  }

  function tryAddFromQuery() {
    const id = query.trim()
    if (!id) return false
    if (suggestions[activeIndex]) {
      addModel(suggestions[activeIndex]!)
      return true
    }
    if (!taken.has(id)) {
      addModel(id)
      return true
    }
    return false
  }

  return (
    <div className="space-y-2">
      <div className="relative">
        <Input
          value={query}
          disabled={disabled}
          placeholder="Rechercher ou saisir un modèle…"
          className="h-9"
          onChange={(e) => {
            setQuery(e.target.value)
            setActiveIndex(0)
          }}
          onFocus={() => {
            if (blurTimer.current) window.clearTimeout(blurTimer.current)
            setFocused(true)
          }}
          onBlur={() => {
            blurTimer.current = window.setTimeout(() => setFocused(false), 120)
          }}
          onKeyDown={(e) => {
            if (e.key === "Enter") {
              e.preventDefault()
              tryAddFromQuery()
              return
            }
            if (!showSuggestions || suggestions.length === 0) return
            if (e.key === "ArrowDown") {
              e.preventDefault()
              setActiveIndex((i) => (i + 1) % suggestions.length)
            } else if (e.key === "ArrowUp") {
              e.preventDefault()
              setActiveIndex((i) => (i - 1 + suggestions.length) % suggestions.length)
            } else if (e.key === "Escape") {
              setFocused(false)
            }
          }}
        />
        {showSuggestions ? (
          <ul
            className="absolute z-20 mt-1 w-full overflow-y-auto rounded-md border border-border bg-popover py-1 shadow-md"
            style={{ maxHeight: `${VISIBLE_SUGGESTIONS * SUGGESTION_ROW_HEIGHT_REM}rem` }}
          >
            {suggestions.map((modelId, index) => (
              <li key={modelId}>
                <button
                  type="button"
                  className={cn(
                    "block w-full px-3 py-1.5 text-left text-xs hover:bg-muted",
                    index === activeIndex && "bg-muted",
                  )}
                  onMouseDown={(e) => {
                    e.preventDefault()
                    addModel(modelId)
                  }}
                >
                  <span className="block truncate font-mono">{modelId}</span>
                </button>
              </li>
            ))}
          </ul>
        ) : null}
      </div>

      {models.length > 0 ? (
        <div className="flex flex-wrap gap-1.5">
          {models.map((entry) => (
            <span
              key={modelKey(entry)}
              className="inline-flex max-w-full items-center gap-1 rounded-full border border-border bg-muted/60 px-2 py-0.5 text-[11px] text-foreground"
            >
              <Popover>
                <PopoverTrigger asChild>
                  <button
                    type="button"
                    className="max-w-[14rem] truncate text-left hover:underline"
                    title={entry.model_id}
                  >
                    {chipLabel(entry)}
                  </button>
                </PopoverTrigger>
                <PopoverContent align="start" className="w-72 space-y-2 p-3">
                  <div className="space-y-1">
                    <Label className="text-xs">ID modèle</Label>
                    <p className="truncate font-mono text-xs text-muted-foreground">
                      {entry.model_id}
                    </p>
                  </div>
                  <div className="space-y-1">
                    <Label className="text-xs">Surnom utilisateur</Label>
                    <Input
                      className="h-8 text-xs"
                      value={entry.label}
                      onChange={(e) => updateLabel(entry.model_id, e.target.value)}
                      placeholder={entry.model_id}
                    />
                  </div>
                </PopoverContent>
              </Popover>
              <button
                type="button"
                className="shrink-0 rounded-full p-0.5 hover:bg-background/80"
                aria-label={`Retirer ${entry.model_id}`}
                onClick={() => removeModel(entry.model_id)}
              >
                <X className="size-3" />
              </button>
            </span>
          ))}
        </div>
      ) : emptyHint ? (
        <p className="text-sm text-muted-foreground">{emptyHint}</p>
      ) : null}
    </div>
  )
}
