"use client";

import React, { useState, useRef, useEffect, useCallback } from "react";
import { Search, List, Loader2, Check } from "lucide-react";
import { Input } from "@/components/ui/input";

export interface ModelOption {
  id: string;
  name?: string;
  owned_by?: string;
  context_length?: number;
  pricing?: { prompt?: string; completion?: string };
}

interface ModelComboboxProps {
  value: string;
  onChange: (value: string) => void;
  models: ModelOption[];
  isLoading: boolean;
  onFetchModels: () => void;
  providerLabel: string;
  placeholder?: string;
}

export function ModelCombobox({
  value,
  onChange,
  models,
  isLoading,
  onFetchModels,
  providerLabel,
  placeholder = "nom-du-modele",
}: ModelComboboxProps) {
  const [isOpen, setIsOpen] = useState(false);
  const [filter, setFilter] = useState("");
  const containerRef = useRef<HTMLDivElement>(null);
  const listRef = useRef<HTMLUListElement>(null);
  const [highlightIndex, setHighlightIndex] = useState(-1);

  const filtered = React.useMemo(() => {
    if (!filter.trim()) return models;
    const q = filter.toLowerCase();
    return models.filter(
      (m) =>
        m.id.toLowerCase().includes(q) ||
        (m.name && m.name.toLowerCase().includes(q))
    );
  }, [models, filter]);

  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (containerRef.current && !containerRef.current.contains(e.target as Node)) {
        setIsOpen(false);
      }
    }
    document.addEventListener("mousedown", handleClick);
    return () => document.removeEventListener("mousedown", handleClick);
  }, []);

  useEffect(() => { setHighlightIndex(-1); }, [filter]);

  useEffect(() => {
    if (highlightIndex >= 0 && listRef.current) {
      (listRef.current.children[highlightIndex] as HTMLElement)?.scrollIntoView({ block: "nearest" });
    }
  }, [highlightIndex]);

  const handleBrowse = useCallback(() => {
    if (!isOpen) onFetchModels();
    setIsOpen(!isOpen);
  }, [isOpen, onFetchModels]);

  const handleSelect = useCallback(
    (model: ModelOption) => {
      onChange(model.id);
      setFilter("");
      setIsOpen(false);
    },
    [onChange]
  );

  const handleKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (!isOpen || filtered.length === 0) return;
      if (e.key === "ArrowDown") { e.preventDefault(); setHighlightIndex((p) => Math.min(p + 1, filtered.length - 1)); }
      else if (e.key === "ArrowUp") { e.preventDefault(); setHighlightIndex((p) => Math.max(p - 1, 0)); }
      else if (e.key === "Enter" && highlightIndex >= 0) { e.preventDefault(); handleSelect(filtered[highlightIndex]); }
      else if (e.key === "Escape") { setIsOpen(false); }
    },
    [isOpen, filtered, highlightIndex, handleSelect]
  );

  return (
    <div ref={containerRef} className="relative">
      <div className="flex gap-2">
        <div className="flex-1">
          <Input
            placeholder={placeholder}
            value={value}
            onChange={(e) => onChange(e.target.value)}
            onFocus={() => { if (models.length > 0) setIsOpen(true); }}
            onKeyDown={handleKeyDown}
            leftIcon={<Search className="size-4" />}
            loading={isLoading}
          />
        </div>
        <button
          type="button"
          onClick={handleBrowse}
          disabled={isLoading}
          className="flex items-center gap-1.5 px-3 h-10 rounded-lg border border-border-subtle bg-surface text-sm text-muted-foreground hover:bg-surface-elevated hover:text-foreground transition-colors disabled:opacity-50"
        >
          {isLoading ? <Loader2 className="size-4 animate-spin" /> : <List className="size-4" />}
          <span className="hidden sm:inline">Parcourir</span>
        </button>
      </div>

      {isOpen && (
        <div className="absolute z-50 mt-1 w-full rounded-lg border border-border-subtle bg-card shadow-xl max-h-72 overflow-hidden flex flex-col">
          {/* Filter */}
          <div className="p-2 border-b border-border-subtle">
            <Input
              placeholder={`Filtrer...`}
              value={filter}
              onChange={(e) => setFilter(e.target.value)}
              leftIcon={<Search className="size-3.5" />}
              className="h-8 text-xs"
            />
          </div>

          {/* List */}
          <ul ref={listRef} className="overflow-y-auto flex-1">
            {filtered.length === 0 ? (
              <li className="px-3 py-4 text-xs text-muted-foreground text-center">
                {models.length === 0 ? "Aucun modele recupere" : "Aucun modele ne correspond"}
              </li>
            ) : (
              filtered.map((model, i) => (
                <li
                  key={model.id}
                  onClick={() => handleSelect(model)}
                  onMouseEnter={() => setHighlightIndex(i)}
                  className={`flex items-center justify-between px-3 py-2 text-xs cursor-pointer transition-colors ${
                    i === highlightIndex ? "bg-primary/10 text-foreground" : "text-muted-foreground hover:bg-surface-elevated"
                  } ${value === model.id ? "bg-primary/5" : ""}`}
                >
                  <div className="flex-1 min-w-0">
                    <div className="font-mono truncate text-foreground">{model.id}</div>
                    {model.name && model.name !== model.id && (
                      <div className="text-muted-foreground truncate mt-0.5">{model.name}</div>
                    )}
                    {model.context_length && (
                      <span className="text-muted-foreground">ctx: {(model.context_length / 1000).toFixed(0)}k</span>
                    )}
                  </div>
                  {value === model.id && <Check className="size-3.5 text-primary flex-shrink-0 ml-2" />}
                </li>
              ))
            )}
          </ul>

          {models.length > 0 && (
            <div className="px-3 py-1.5 border-t border-border-subtle text-xs text-muted-foreground text-center bg-card">
              {filtered.length} modele{filtered.length !== 1 ? "s" : ""}
              {filter ? ` sur ${models.length}` : ""} — nom libre possible
            </div>
          )}
        </div>
      )}
    </div>
  );
}
