"use client";
import React, { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, Search, X } from "lucide-react";

// Generic select-like dropdown that supports arbitrary node rendering for
// each option (so we can show flags, offsets, etc.) and an optional search
// box that filters the list against `searchHaystack`.

export interface DropdownOption<T = string> {
    value: T;
    label: string;
    searchHaystack?: string; // extra text to match search against (city, country, abbreviation…)
    leading?: React.ReactNode;
    secondary?: string; // dimmer text after the label
}

interface SearchableDropdownProps<T = string> {
    value: T;
    options: DropdownOption<T>[];
    onChange: (value: T) => void;
    placeholder?: string;
    searchable?: boolean;
    searchPlaceholder?: string;
    emptyText?: string;
    className?: string;
    style?: React.CSSProperties;
    width?: string | number;
    darkMode?: boolean;
}

export default function SearchableDropdown<T extends string>({
    value,
    options,
    onChange,
    placeholder,
    searchable = false,
    searchPlaceholder = "Search…",
    emptyText = "No matches",
    className,
    style,
    width = "100%",
    darkMode = false,
}: SearchableDropdownProps<T>) {
    const [open, setOpen] = useState(false);
    const [query, setQuery] = useState("");
    const wrapperRef = useRef<HTMLDivElement>(null);
    const searchRef = useRef<HTMLInputElement>(null);

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

    useEffect(() => {
        if (open && searchable) setTimeout(() => searchRef.current?.focus(), 30);
    }, [open, searchable]);

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

    const filtered = useMemo(() => {
        if (!query.trim()) return options;
        const q = query.toLowerCase();
        return options.filter((o) => {
            const hay = (o.searchHaystack || `${o.label} ${o.secondary || ""}`).toLowerCase();
            return hay.includes(q);
        });
    }, [options, query]);

    const bg = darkMode ? "#1f2937" : "#ffffff";
    const border = darkMode ? "#374151" : "#d1d5db";
    const text = darkMode ? "#e5e7eb" : "#111827";
    const muted = darkMode ? "#9ca3af" : "#6b7280";
    const hoverBg = darkMode ? "#374151" : "#f3f4f6";
    const activeBg = darkMode ? "rgba(13,148,136,0.18)" : "rgba(13,148,136,0.08)";

    return (
        <div ref={wrapperRef} className={className} style={{ position: "relative", width, ...style }}>
            <button
                type="button"
                onClick={() => setOpen((v) => !v)}
                style={{
                    width: "100%",
                    display: "flex",
                    alignItems: "center",
                    gap: 8,
                    padding: "8px 10px",
                    borderRadius: 6,
                    border: `1px solid ${border}`,
                    background: bg,
                    color: text,
                    cursor: "pointer",
                    fontSize: "0.9rem",
                    textAlign: "left",
                }}
            >
                {selected?.leading && <span style={{ display: "inline-flex" }}>{selected.leading}</span>}
                <span style={{ flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
                    {selected ? selected.label : (placeholder || "Select…")}
                </span>
                {selected?.secondary && (
                    <span style={{ color: muted, fontSize: "0.8rem", whiteSpace: "nowrap" }}>{selected.secondary}</span>
                )}
                <ChevronDown size={14} style={{ color: muted, flexShrink: 0, transform: open ? "rotate(180deg)" : "none", transition: "transform 0.15s" }} />
            </button>

            {open && (
                <div
                    style={{
                        position: "absolute",
                        top: "calc(100% + 4px)",
                        left: 0,
                        right: 0,
                        zIndex: 1000,
                        background: bg,
                        border: `1px solid ${border}`,
                        borderRadius: 8,
                        boxShadow: "0 8px 24px rgba(0,0,0,0.18)",
                        overflow: "hidden",
                        display: "flex",
                        flexDirection: "column",
                        maxHeight: 320,
                    }}
                >
                    {searchable && (
                        <div style={{ padding: 8, borderBottom: `1px solid ${border}`, display: "flex", alignItems: "center", gap: 6, background: bg }}>
                            <Search size={14} style={{ color: muted, flexShrink: 0 }} />
                            <input
                                ref={searchRef}
                                type="text"
                                value={query}
                                onChange={(e) => setQuery(e.target.value)}
                                placeholder={searchPlaceholder}
                                style={{
                                    flex: 1,
                                    border: "none",
                                    outline: "none",
                                    background: "transparent",
                                    color: text,
                                    fontSize: "0.85rem",
                                }}
                            />
                            {query && (
                                <button
                                    onClick={() => setQuery("")}
                                    style={{ background: "none", border: "none", cursor: "pointer", color: muted, padding: 2 }}
                                >
                                    <X size={12} />
                                </button>
                            )}
                        </div>
                    )}

                    <div style={{ overflowY: "auto", flex: 1 }}>
                        {filtered.length === 0 ? (
                            <div style={{ padding: 16, color: muted, fontSize: "0.85rem", textAlign: "center" }}>{emptyText}</div>
                        ) : filtered.map((opt) => {
                            const active = opt.value === value;
                            return (
                                <button
                                    key={String(opt.value)}
                                    type="button"
                                    onClick={() => {
                                        onChange(opt.value);
                                        setOpen(false);
                                        setQuery("");
                                    }}
                                    style={{
                                        width: "100%",
                                        display: "flex",
                                        alignItems: "center",
                                        gap: 8,
                                        padding: "8px 10px",
                                        border: "none",
                                        background: active ? activeBg : "transparent",
                                        color: text,
                                        cursor: "pointer",
                                        fontSize: "0.85rem",
                                        textAlign: "left",
                                    }}
                                    onMouseEnter={(e) => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = hoverBg; }}
                                    onMouseLeave={(e) => { if (!active) (e.currentTarget as HTMLButtonElement).style.background = "transparent"; }}
                                >
                                    {opt.leading && <span style={{ display: "inline-flex", flexShrink: 0 }}>{opt.leading}</span>}
                                    <span style={{ flex: 1, whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{opt.label}</span>
                                    {opt.secondary && <span style={{ color: muted, fontSize: "0.78rem", whiteSpace: "nowrap" }}>{opt.secondary}</span>}
                                </button>
                            );
                        })}
                    </div>
                </div>
            )}
        </div>
    );
}
