import { AsyncOption, ENDPOINT_MODUL_MAP } from '@/Components/AsyncSelect';
import { ModulAdi, useModulModalOptional } from '@/Components/ModulModalProvider';
import { Popover, PopoverButton, PopoverPanel, Transition } from '@headlessui/react';
import { Check, ChevronDown, Loader2, Plus, Search } from 'lucide-react';
import { Fragment, ReactNode, useEffect, useMemo, useRef, useState } from 'react';

/**
 * AJAX tabanlı çoklu seçim. Headless UI Popover ile dropdown portal'a render edilir.
 */
interface Props {
    endpoint: string;
    value: Array<number | string>;
    onChange: (value: Array<number | string>) => void;
    initialOptions?: AsyncOption[];
    cozumleEndpoint?: string;
    cozumleTip?: string;
    placeholder?: string;
    disabled?: boolean;
    maxChip?: number;
    renderOption?: (opt: AsyncOption) => ReactNode;
    /** Hızlı ekleme "+" butonunu manuel modüle bağla. Verilmezse endpoint'ten otomatik algılanır. */
    hizliEkleModul?: ModulAdi;
    /** Hızlı ekleme "+" butonunu tamamen gizle. */
    hizliEkleGizle?: boolean;
}

export default function AsyncMultiSelect({
    endpoint, value, onChange, initialOptions = [], cozumleEndpoint, cozumleTip,
    placeholder = 'Seç veya ara...', disabled, maxChip = 4, renderOption,
    hizliEkleModul, hizliEkleGizle,
}: Props) {
    const modulModal = useModulModalOptional();
    const otoModul = hizliEkleModul ?? ENDPOINT_MODUL_MAP[endpoint];
    const hizliEkleAktif = !hizliEkleGizle && !disabled && !!otoModul && !!modulModal;
    const [arama, setArama] = useState('');
    const [items, setItems] = useState<AsyncOption[]>([]);
    const [yukleniyor, setYukleniyor] = useState(false);
    const [secililerOpts, setSecililerOpts] = useState<AsyncOption[]>(initialOptions);
    const [acik, setAcik] = useState(false);

    const inputRef = useRef<HTMLInputElement>(null);
    const fetchSeq = useRef(0);

    const valueSet = useMemo(() => new Set(value.map(String)), [value]);

    useEffect(() => {
        if (initialOptions.length > 0 && secililerOpts.length === 0) {
            setSecililerOpts(initialOptions);
        }
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [initialOptions]);

    // Seçili ama opt'u bilinmeyen id'leri çözümle
    useEffect(() => {
        if (!cozumleEndpoint || !cozumleTip || value.length === 0) return;
        const bilinmeyenler = value.filter((v) => !secililerOpts.some((o) => o.value === v));
        if (bilinmeyenler.length === 0) return;

        const params = new URLSearchParams();
        params.set('tip', cozumleTip);
        bilinmeyenler.forEach((id) => params.append('ids[]', String(id)));

        fetch(`${cozumleEndpoint}?${params.toString()}`, { headers: { Accept: 'application/json' } })
            .then((r) => r.json())
            .then((d: { items: AsyncOption[] }) => {
                if (d.items?.length) {
                    setSecililerOpts((prev) => {
                        const yeni = [...prev];
                        d.items.forEach((it) => { if (!yeni.some((o) => o.value === it.value)) yeni.push(it); });
                        return yeni;
                    });
                }
            }).catch(() => {});
    // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [value]);

    useEffect(() => {
        if (!acik) return;
        const tur = ++fetchSeq.current;
        const t = setTimeout(async () => {
            setYukleniyor(true);
            try {
                const r = await fetch(`${endpoint}?q=${encodeURIComponent(arama)}`, {
                    headers: { Accept: 'application/json' },
                });
                const d = await r.json();
                if (fetchSeq.current === tur) setItems(d.items ?? []);
            } catch { if (fetchSeq.current === tur) setItems([]); }
            finally { if (fetchSeq.current === tur) setYukleniyor(false); }
        }, arama ? 250 : 0);
        return () => clearTimeout(t);
    }, [acik, arama, endpoint]);

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

    const toggle = (opt: AsyncOption) => {
        const k = String(opt.value);
        if (valueSet.has(k)) {
            onChange(value.filter((v) => String(v) !== k));
            setSecililerOpts((p) => p.filter((o) => String(o.value) !== k));
        } else {
            onChange([...value, opt.value]);
            setSecililerOpts((p) => p.some((o) => o.value === opt.value) ? p : [...p, opt]);
        }
    };

    const gosterilenChipler = secililerOpts.slice(0, maxChip);
    const ekstra = secililerOpts.length - gosterilenChipler.length;

    return (
        <Popover className="relative">
            {({ open }) => {
                if (open !== acik) setTimeout(() => setAcik(open), 0);
                return (
                    <>
                        <PopoverButton
                            disabled={disabled}
                            className={`flex w-full min-h-[38px] items-center gap-2 rounded-lg border border-slate-300 bg-white py-1 pl-2 text-sm transition focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 ${
                                hizliEkleAktif ? 'pr-14' : 'pr-9'
                            } ${disabled ? 'cursor-not-allowed bg-slate-50 text-slate-400' : 'hover:border-slate-400'}`}
                        >
                            <div className="flex min-w-0 flex-1 flex-wrap items-center gap-1">
                                {secililerOpts.length === 0 && (
                                    <span className="px-1 text-slate-400">{placeholder}</span>
                                )}
                                {gosterilenChipler.map((opt) => (
                                    <span key={opt.value}
                                        className="inline-flex items-center gap-1 rounded-md bg-blue-50 px-2 py-0.5 text-xs font-medium text-blue-700">
                                        {opt.icon}
                                        {opt.label}
                                    </span>
                                ))}
                                {ekstra > 0 && (
                                    <span className="inline-flex items-center rounded-md bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">
                                        +{ekstra} daha
                                    </span>
                                )}
                            </div>
                        </PopoverButton>
                        {/*
                         * SAĞ İKONLAR — tek absolute container, garantili yan yana.
                         * Container pointer-events-none: tıklama PopoverButton'a geçer (dropdown açılır).
                         * + butonu pointer-events-auto: kendi tıklamasını yakalar, dropdown açılmaz.
                         */}
                        <div className="pointer-events-none absolute inset-y-0 right-0 flex items-center gap-1.5 pr-3">
                            {hizliEkleAktif && (
                                <button type="button" title="Yeni ekle"
                                    className="pointer-events-auto text-slate-400 transition hover:text-blue-600"
                                    onClick={(e) => {
                                        e.stopPropagation();
                                        e.preventDefault();
                                        modulModal!.ac(otoModul, 'yeni', {
                                            onEklendi: (d) => {
                                                // Kaydet ve Ekle: yeni kaydı listeye ekle + seç
                                                onChange([...value, d.id]);
                                                setSecililerOpts((prev) =>
                                                    prev.some((o) => String(o.value) === String(d.id))
                                                        ? prev
                                                        : [...prev, { value: d.id, label: d.label }],
                                                );
                                            },
                                        });
                                    }}>
                                    <Plus className="h-4 w-4" />
                                </button>
                            )}
                            <ChevronDown className={`h-4 w-4 text-slate-400 transition-transform ${open ? 'rotate-180' : ''}`} />
                        </div>

                        <Transition as={Fragment}
                            enter="transition ease-out duration-100"
                            enterFrom="opacity-0 translate-y-1"
                            enterTo="opacity-100 translate-y-0"
                            leave="transition ease-in duration-75"
                            leaveFrom="opacity-100 translate-y-0"
                            leaveTo="opacity-0 translate-y-1">
                            <PopoverPanel
                                anchor="bottom start"
                                className="z-50 mt-1 w-[var(--button-width)] min-w-[280px] overflow-hidden rounded-lg border border-slate-200 bg-white shadow-xl ring-1 ring-black/5"
                            >
                                <div className="border-b border-slate-100 p-2">
                                    <div className="relative">
                                        <Search className="pointer-events-none absolute left-2.5 top-1/2 h-4 w-4 -translate-y-1/2 text-slate-400" />
                                        <input ref={inputRef} type="text" value={arama}
                                            onChange={(e) => setArama(e.target.value)}
                                            onKeyDown={(e) => e.stopPropagation()}
                                            placeholder="Ara..."
                                            className="w-full rounded-md border-slate-200 bg-slate-50 pl-8 pr-2 py-1.5 text-sm focus:border-blue-500 focus:bg-white focus:ring-blue-500" />
                                        {yukleniyor && (
                                            <Loader2 className="absolute right-2 top-1/2 h-4 w-4 -translate-y-1/2 animate-spin text-blue-500" />
                                        )}
                                    </div>
                                </div>

                                <div className="max-h-72 overflow-y-auto">
                                    {yukleniyor && items.length === 0 ? (
                                        <div className="px-3 py-4 text-center text-sm text-slate-500">Yükleniyor...</div>
                                    ) : items.length === 0 ? (
                                        <div className="px-3 py-4 text-center text-sm text-slate-500">
                                            {arama ? 'Sonuç bulunamadı' : 'Kayıt yok'}
                                        </div>
                                    ) : (
                                        items.map((opt) => {
                                            const aktif = valueSet.has(String(opt.value));
                                            return (
                                                <button key={opt.value} type="button"
                                                    onClick={() => toggle(opt)}
                                                    className={`flex w-full items-center justify-between gap-2 px-3 py-2 text-left text-sm transition ${
                                                        aktif ? 'bg-blue-50 text-blue-900' : 'text-slate-700 hover:bg-slate-50'
                                                    }`}
                                                >
                                                    {renderOption ? renderOption(opt) : (
                                                        <div className="flex min-w-0 flex-1 items-center gap-2">
                                                            {opt.icon}
                                                            <div className="min-w-0 flex-1">
                                                                <div className="truncate font-medium">{opt.label}</div>
                                                                {opt.description && (
                                                                    <div className="truncate text-xs text-slate-500">{opt.description}</div>
                                                                )}
                                                            </div>
                                                        </div>
                                                    )}
                                                    <div className={`flex h-4 w-4 flex-shrink-0 items-center justify-center rounded border ${
                                                        aktif ? 'border-blue-600 bg-blue-600' : 'border-slate-300'
                                                    }`}>
                                                        {aktif && <Check className="h-3 w-3 text-white" />}
                                                    </div>
                                                </button>
                                            );
                                        })
                                    )}
                                </div>
                                {!arama && items.length > 0 && (
                                    <div className="border-t border-slate-100 bg-slate-50 px-3 py-1.5 text-[10px] text-slate-500">
                                        Son {items.length} kayıt — daha fazlası için yazarak arayın
                                    </div>
                                )}
                            </PopoverPanel>
                        </Transition>
                    </>
                );
            }}
        </Popover>
    );
}
