"use client";

import { useEffect, useRef, useState } from "react";
import { ChevronDown, Search, X, Loader } from "lucide-react";
import styles from "./Select.module.css";

interface SelectOption {
  value: string | number;
  label: string;
}

interface SelectProps {
  label?: string;
  error?: string;
  hint?: string;
  options: SelectOption[];
  value?: string | number;
  onChange?: (e: { target: { value: string } }) => void;
  placeholder?: string;
  required?: boolean;
  disabled?: boolean;
  loading?: boolean;
}

export default function Select({
  label,
  error,
  hint,
  options,
  value = "",
  onChange,
  placeholder = "Sélectionner...",
  required,
  disabled,
  loading,
}: SelectProps) {
  const [open, setOpen] = useState(false);
  const [query, setQuery] = useState("");
  const [openUp, setOpenUp] = useState(false);
  const containerRef = useRef<HTMLDivElement>(null);
  const inputRef = useRef<HTMLInputElement>(null);

  const selected = options.find((o) => String(o.value) === String(value));

  const filtered = query.trim()
    ? options.filter((o) => o.label.toLowerCase().includes(query.toLowerCase()))
    : options;

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

  useEffect(() => {
    if (open) setTimeout(() => inputRef.current?.focus(), 50);
  }, [open]);

  const handleSelect = (opt: SelectOption) => {
    onChange?.({ target: { value: String(opt.value) } });
    setOpen(false);
    setQuery("");
  };

  const handleClear = (e: React.MouseEvent) => {
    e.stopPropagation();
    onChange?.({ target: { value: "" } });
    setQuery("");
  };

  return (
    <div className={styles.field} ref={containerRef}>
      {label && (
        <label className={styles.label}>
          {label}
          {required && <span className={styles.required}>*</span>}
        </label>
      )}

      <div
        className={`${styles.trigger} ${error ? styles.hasError : ""} ${open ? styles.open : ""} ${disabled || loading ? styles.disabled : ""}`}
        onClick={() => {
          if (disabled || loading) return;
          if (!open && containerRef.current) {
            const rect = containerRef.current.getBoundingClientRect();
            setOpenUp(window.innerHeight - rect.bottom < 260);
          }
          setOpen((v) => !v);
        }}
      >
        <span className={selected ? styles.selectedText : styles.placeholder}>
          {loading ? "Chargement..." : selected ? selected.label : placeholder}
        </span>
        <div className={styles.icons}>
          {loading ? (
            <Loader size={14} className={styles.loadingIcon} />
          ) : (
            <>
              {selected && !disabled && <X size={14} className={styles.clearIcon} onClick={handleClear} />}
              <ChevronDown size={15} className={`${styles.chevron} ${open ? styles.chevronOpen : ""}`} strokeWidth={1.8} />
            </>
          )}
        </div>
      </div>

      {open && (
        <div className={`${styles.dropdown} ${openUp ? styles.dropdownUp : ""}`}>
          <div className={styles.searchWrap}>
            <Search size={14} className={styles.searchIcon} />
            <input
              ref={inputRef}
              className={styles.searchInput}
              placeholder="Rechercher..."
              value={query}
              onChange={(e) => setQuery(e.target.value)}
              onClick={(e) => e.stopPropagation()}
            />
          </div>
          <div className={styles.list}>
            {filtered.length === 0 ? (
              <div className={styles.empty}>Aucun résultat</div>
            ) : (
              filtered.map((opt) => (
                <div
                  key={opt.value}
                  className={`${styles.option} ${String(opt.value) === String(value) ? styles.optionActive : ""}`}
                  onClick={() => handleSelect(opt)}
                >
                  {opt.label}
                </div>
              ))
            )}
          </div>
        </div>
      )}

      {error && <span className={styles.error}>{error}</span>}
      {hint && !error && <span className={styles.hint}>{hint}</span>}
    </div>
  );
}
