import { ModulAdi, useModulModalOptional } from '@/Components/ModulModalProvider';
import { HizliEkleModal } from '@/Components/Select';
import { router } from '@inertiajs/react';
import { Check, ChevronDown, Plus, Search } from 'lucide-react';
import { useAnchoredPanel } from '@/lib/useAnchoredPanel';
import { ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom';

export interface MultiSelectOption {
    value: number | string;
    label: string;
    description?: string;
    /** Solda gösterilecek özel görsel (avatar, ikon vs.) */
    icon?: ReactNode;
}

export interface MultiSelectProps {
    value: Array<number | string>;
    onChange: (yeni: Array<number | string>) => void;
    options: MultiSelectOption[];
    placeholder?: string;
    aramaPlaceholder?: string;
    bosMesaji?: string;
    disabled?: boolean;
    /** Maksimum chip sayısı (üstü "+N daha") */
    maxChip?: number;
    /**
     * Arama-tabanlı mod. Dropdown ilk açıldığında liste BOŞ gösterilir;
     * kullanıcı arama yazdıkça sonuçlar gelir. Büyük listeler için performans.
     * Default: true (büyük listeleri varsayalım).
     */
    aramaTabanli?: boolean;
    /** Arama yazısı boşken gösterilecek max sonuç (aramaTabanli=false ise tümü) */
    maxSonuc?: number;
    /** Hızlı ekleme — provider modülü aç (Cari, Musteri, Urun vs.) */
    hizliEkleModul?: ModulAdi;
    /** Hızlı ekleme — tanımlama tipi POST endpoint'i ("/tanimlamalar/tip/{slug}") */
    hizliEkleUrl?: string;
    /** Hızlı ekleme "+" butonunu gizle */
    hizliEkleGizle?: boolean;
    /** Ekleme sonrası tetiklenir (liste yenileme) */
    onHizliEklendi?: () => void;
}

/**
 * Aranabilir çoklu seçim — büyük listeler için canlı arama, chip-bazlı seçim göstergesi.
 */
export default function MultiSelect({
    value, onChange, options: gelenOptions, placeholder, aramaPlaceholder, bosMesaji, disabled, maxChip = 4,
    aramaTabanli = true, maxSonuc = 50,
    hizliEkleModul, hizliEkleUrl, hizliEkleGizle, onHizliEklendi,
}: MultiSelectProps) {
    const modulModal = useModulModalOptional();

    // Hızlı ekleme ile eklenen kayıtlar — parent'ın `options` listesi (fetch/Inertia payload)
    // henüz tazelenmemiş olabilir. Yeni kayıt listede yoksa chip hiç render edilmez ve
    // kullanıcı "eklendi ama seçilmedi" görür. Bu yüzden yerelde saklanır.
    const [ekstraSecenekler, setEkstraSecenekler] = useState<MultiSelectOption[]>([]);
    const options = useMemo(() => {
        if (!ekstraSecenekler.length) return gelenOptions;
        const yeni = ekstraSecenekler.filter(
            (e) => !gelenOptions.some((o) => String(o.value) === String(e.value)),
        );
        return yeni.length ? [...gelenOptions, ...yeni] : gelenOptions;
    }, [gelenOptions, ekstraSecenekler]);
    // İki yol da desteklenir:
    //   hizliEkleModul → ModulModalProvider modalı (Cari/Musteri/Kullanici...)
    //   hizliEkleUrl   → tanımlama tipi (dinamik şemalı HizliEkleModal)
    const hizliEkleAktif = !hizliEkleGizle && !disabled
        && ((!!hizliEkleModul && !!modulModal) || !!hizliEkleUrl);
    const [hizliEkleAcik, setHizliEkleAcik] = useState(false);
    const [acik, setAcik] = useState(false);

    /** Yeni kaydı listeye ekle + seç — hem provider hem url yolunda kullanılır */
    const yeniKaydiAta = (d: { id: number | string; label: string }) => {
        setEkstraSecenekler((p) =>
            p.some((o) => String(o.value) === String(d.id)) ? p : [...p, { value: d.id, label: d.label }],
        );
        onChange([...value, d.id]);
        onHizliEklendi?.();
    };
    const [arama, setArama] = useState('');
    const aramaInputRef = useRef<HTMLInputElement>(null);

    // Panel body'e portal edilir — modal içindeki overflow alanına hapsolup
    // kırpılmasın ve modalda gereksiz scroll oluşturmasın.
    const kapat = useCallback(() => { setAcik(false); setArama(''); }, []);
    const { containerRef, panelRef, panelStil } = useAnchoredPanel(acik, kapat, {
        genislik: 'anchor',
        tahminiYukseklik: 340,
    });

    // Escape → kapat (dışarı tık hook içinde ele alınır)
    useEffect(() => {
        if (!acik) return;
        const escapeHandler = (e: KeyboardEvent) => {
            if (e.key === 'Escape') kapat();
        };
        document.addEventListener('keydown', escapeHandler);
        return () => document.removeEventListener('keydown', escapeHandler);
    }, [acik, kapat]);

    // Dropdown açıldığında arama kutusuna odakla
    useEffect(() => {
        if (acik) setTimeout(() => aramaInputRef.current?.focus(), 50);
    }, [acik]);

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

    const filtreli = useMemo(() => {
        const q = arama.trim().toLowerCase();
        if (q) {
            // Arama yazılı → tüm liste içinde filtre
            return options.filter((o) =>
                o.label.toLowerCase().includes(q) ||
                (o.description ?? '').toLowerCase().includes(q),
            );
        }
        // Arama boş
        if (aramaTabanli && options.length > maxSonuc) {
            // Büyük liste → sadece SEÇİLİ olanları göster + boş bilgi mesajı için "tümü" döndürme
            return options.filter((o) => secili.has(String(o.value)));
        }
        // Küçük liste veya aramaTabanli=false → tümünü göster
        return options;
    }, [arama, options, aramaTabanli, maxSonuc, secili]);

    const aramaIstenenMi = aramaTabanli && options.length > maxSonuc && arama.trim() === '';

    // Tek bir option satırı render edici (DRY)
    const renderOption = (opt: MultiSelectOption) => {
        const aktif = secili.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'
                }`}
            >
                <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>
        );
    };

    const toggle = (opt: MultiSelectOption) => {
        const key = String(opt.value);
        if (secili.has(key)) {
            onChange(value.filter((v) => String(v) !== key));
        } else {
            onChange([...value, opt.value]);
        }
    };

    const seciliOptionlari = options.filter((o) => secili.has(String(o.value)));
    const gosterilenChipler = seciliOptionlari.slice(0, maxChip);
    const ekstraSayi = seciliOptionlari.length - gosterilenChipler.length;

    return (
        <div ref={containerRef} className="relative">
            {/* Trigger */}
            <button type="button"
                disabled={disabled}
                onClick={() => setAcik((a) => !a)}
                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">
                    {seciliOptionlari.length === 0 && (
                        <span className="px-1 text-slate-400">{placeholder ?? 'Seç'}</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>
                    ))}
                    {ekstraSayi > 0 && (
                        <span className="inline-flex items-center rounded-md bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">
                            +{ekstraSayi} daha
                        </span>
                    )}
                </div>
            </button>
            {/*
             * SAĞ İKONLAR — tek absolute container, garantili yan yana.
             * Container pointer-events-none: tıklama trigger button'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();
                            if (hizliEkleModul && modulModal) {
                                modulModal.ac(hizliEkleModul, 'yeni', { onEklendi: yeniKaydiAta });
                            } else if (hizliEkleUrl) {
                                setHizliEkleAcik(true);
                            }
                        }}>
                        <Plus className="h-4 w-4" />
                    </button>
                )}
                <ChevronDown className={`h-4 w-4 text-slate-400 transition-transform ${acik ? 'rotate-180' : ''}`} />
            </div>

            {/* Dropdown — body'e portal edilir (modal overflow'una hapsolmasın) */}
            {acik && typeof document !== 'undefined' && createPortal(
                <div
                    ref={panelRef}
                    style={panelStil}
                    className="fixed z-[200] overflow-hidden rounded-lg border border-slate-200 bg-white shadow-xl"
                >
                    <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={aramaInputRef}
                                type="text" value={arama}
                                onChange={(e) => setArama(e.target.value)}
                                placeholder={aramaPlaceholder ?? 'Ara...'}
                                className="w-full rounded-md border-slate-200 pl-8 text-sm focus:border-blue-500 focus:ring-blue-500"
                            />
                        </div>
                    </div>

                    <div className="max-h-64 overflow-y-auto py-1">
                        {aramaIstenenMi && filtreli.length === 0 ? (
                            <div className="py-6 text-center text-sm text-slate-500">
                                <Search className="mx-auto mb-1.5 h-5 w-5 text-slate-300" />
                                <div>Aramaya başla...</div>
                                <div className="mt-0.5 text-xs text-slate-400">
                                    {options.length} kayıt mevcut
                                </div>
                            </div>
                        ) : aramaIstenenMi && filtreli.length > 0 ? (
                            <>
                                <div className="px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-slate-400">
                                    Seçili ({filtreli.length})
                                </div>
                                {filtreli.map((opt) => renderOption(opt))}
                                <div className="mt-1 border-t border-slate-100 px-3 py-2 text-center text-xs text-slate-500">
                                    Daha fazla eklemek için ara
                                </div>
                            </>
                        ) : filtreli.length === 0 ? (
                            <div className="py-6 text-center text-sm text-slate-500">
                                {bosMesaji ?? `"${arama}" için sonuç yok.`}
                            </div>
                        ) : (
                            filtreli.map((opt) => renderOption(opt))
                        )}
                    </div>

                    {seciliOptionlari.length > 0 && (
                        <div className="flex items-center justify-between border-t border-slate-100 bg-slate-50/50 px-3 py-1.5 text-xs">
                            <span className="text-slate-600">
                                <strong>{seciliOptionlari.length}</strong> seçili
                            </span>
                            <button type="button" onClick={() => onChange([])}
                                className="text-rose-600 hover:text-rose-700">
                                Tümünü Temizle
                            </button>
                        </div>
                    )}
                </div>,
                document.body,
            )}

            {/* Tanımlama tipi hızlı ekleme (hizliEkleUrl yolu) */}
            {hizliEkleUrl && (
                <HizliEkleModal
                    acik={hizliEkleAcik}
                    onClose={() => setHizliEkleAcik(false)}
                    url={hizliEkleUrl}
                    baslik="Yeni Kayıt"
                    onEklendi={() => { onHizliEklendi?.(); router.reload(); }}
                    onKaydetVeEkle={(d) => { yeniKaydiAta(d); setHizliEkleAcik(false); router.reload(); }}
                />
            )}
        </div>
    );
}
