import { useState, useEffect } from 'react';
import {
    ChevronLeft, ChevronRight, Search, SlidersHorizontal,
    RotateCcw, ChevronDown,
} from 'lucide-react';
import * as Collapsible from '@radix-ui/react-collapsible';
import * as Slider from '@radix-ui/react-slider';
import { format } from 'date-fns';
import type { FeatureParams } from '@/Pages/Map';
import DateRangePicker, { type DateRangeValue } from './DateRangePicker';

// ─── Types ───────────────────────────────────────────────────────────────────

type GrandeFamille = 'tous' | 'dossiers' | 'annuaire';

const SOUS_FAMILLE_DOSSIERS = ['Projets', 'Chantiers', 'Stations', 'Autres'] as const;
const SOUS_FAMILLE_ANNUAIRE  = ['IR', 'TP', 'SPANCS', 'Fournisseurs', 'Prescripteurs', 'Dépanneurs'] as const;

const MIN_YEAR = 2000;

/** Couleurs des puces carte — miroir de OLMap.tsx */
const PIN_COLOR: Record<string, string> = {
    'Projets':       '#5aacaa',
    'Chantiers':     '#2d7a70',
    'Stations':      '#1b5c54',
    'Autres':        '#7a9290',
    'IR':            '#4a90d9',
    'TP':            '#1a6fb5',
    'Fournisseurs':  '#e8943a',
    'Prescripteurs': '#9b59b6',
    'SPANCS':        '#27ae60',
    'Dépanneurs':    '#e74c3c',
};

interface FilterCounts {
    grandeFamille:       Record<string, number>;
    sousFamilleDossiers: Record<string, number>;
    sousFamilleAnnuaire: Record<string, number>;
}

const EMPTY_COUNTS: FilterCounts = {
    grandeFamille:       { dossiers: 0, annuaire: 0 },
    sousFamilleDossiers: { Projets: 0, Chantiers: 0, Stations: 0, Autres: 0 },
    sousFamilleAnnuaire: { IR: 0, TP: 0, SPANCS: 0, Fournisseurs: 0, Prescripteurs: 0, Dépanneurs: 0 },
};

// ─── Sub-components ───────────────────────────────────────────────────────────

/** Badge count */
function Badge({ n, loading }: { n: number; loading?: boolean }) {
    return (
        <span className="ml-auto flex-shrink-0 inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1.5 rounded-md bg-white/10 text-white/50 text-xs font-semibold tabular-nums leading-none">
            {loading
                ? <span className="w-2.5 h-2.5 rounded-full border border-white/20 border-t-white/60 animate-spin" />
                : n.toLocaleString('fr-FR')}
        </span>
    );
}

/** Section accordéon — label pattern sidebar */
function Section({ label, children, defaultOpen = true }: {
    label: string;
    children: React.ReactNode;
    defaultOpen?: boolean;
}) {
    const [open, setOpen] = useState(defaultOpen);
    return (
        <Collapsible.Root open={open} onOpenChange={setOpen} className="border-b border-white/10">
            <Collapsible.Trigger className="w-full flex items-center justify-between px-5 py-3 text-xs font-semibold uppercase tracking-[0.08em] text-white/40 hover:text-white/70 hover:bg-white/5 transition-colors select-none">
                <span>{label}</span>
                <ChevronDown
                    size={13}
                    className={`text-white/30 transition-transform duration-200 ${open ? '' : '-rotate-90'}`}
                />
            </Collapsible.Trigger>
            <Collapsible.Content className="px-5 pb-3 pt-1 space-y-1">
                {children}
            </Collapsible.Content>
        </Collapsible.Root>
    );
}

/** Pastille couleur — miroir des pins OpenLayers */
function PinDot({ color }: { color: string }) {
    return (
        <span
            className="flex-shrink-0 rounded-full ring-1 ring-white/20"
            style={{ width: 10, height: 10, background: color }}
            aria-hidden="true"
        />
    );
}

/** Checkbox — 18 px, border 2px, coche SVG */
function CheckRow({
    label, checked, onChange, count, color, countsLoading,
}: {
    label: string;
    checked: boolean;
    onChange: (v: boolean) => void;
    count?: number;
    color?: string;
    countsLoading?: boolean;
}) {
    return (
        <label className="flex items-center gap-2.5 cursor-pointer group py-1">
            <span
                role="checkbox"
                aria-checked={checked}
                onClick={() => onChange(!checked)}
                className={`w-[18px] h-[18px] flex-shrink-0 rounded border-2 flex items-center justify-center transition-all duration-150
                    ${checked
                        ? 'bg-aqua-500 border-aqua-500'
                        : 'border-white/25 bg-transparent group-hover:border-white/50'}`}
            >
                {checked && (
                    <svg width="10" height="8" viewBox="0 0 10 8" fill="none" aria-hidden="true">
                        <path fillRule="evenodd" clipRule="evenodd"
                            d="M9.68966 0.275864C10.0896 0.65675 10.105 1.28973 9.72414 1.68966L4.00985 7.68966C3.82111 7.88784 3.55939 8 3.28572 8C3.01204 8 2.75032 7.88784 2.56158 7.68966L0.275864 5.28966C-0.105022 4.88973 -0.0895837 4.25675 0.310347 3.87586C0.710277 3.49498 1.34325 3.51042 1.72414 3.91035L3.28572 5.55L8.27586 0.310347C8.65675 -0.0895837 9.28973 -0.105022 9.68966 0.275864Z"
                            fill="white"
                        />
                    </svg>
                )}
            </span>
            {color && <PinDot color={color} />}
            <span className={`flex-1 text-sm leading-tight transition-colors
                ${checked ? 'text-white font-medium' : 'text-white/60 group-hover:text-white/90'}`}>
                {label}
            </span>
            {count !== undefined && <Badge n={count} loading={countsLoading} />}
        </label>
    );
}

/** Radio — 18 px cercle, border 5px accent quand sélectionné */
function RadioRow({
    label, selected, onClick, count, countsLoading,
}: {
    label: string;
    selected: boolean;
    onClick: () => void;
    count?: number;
    countsLoading?: boolean;
}) {
    return (
        <label
            onClick={onClick}
            className={`flex items-center gap-2.5 py-1.5 px-2 rounded-lg cursor-pointer transition-colors
                ${selected ? 'bg-white/8' : 'hover:bg-white/5'}`}
        >
            <span className={`w-[18px] h-[18px] flex-shrink-0 rounded-full border-2 transition-all duration-150
                ${selected ? 'border-[5px] border-aqua-400' : 'border-white/25'}`}
            />
            <span className={`flex-1 text-sm transition-colors
                ${selected ? 'text-white font-medium' : 'text-white/60 group-hover:text-white/90'}`}>
                {label}
            </span>
            {count !== undefined && <Badge n={count} loading={countsLoading} />}
        </label>
    );
}

/** Select avec chevron */
function SelectField({ label, options, value, onChange }: {
    label: string;
    options: string[];
    value: string;
    onChange: (v: string) => void;
}) {
    return (
        <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-white/50">{label}</label>
            <div className="relative">
                <select
                    value={value}
                    onChange={e => onChange(e.target.value)}
                    className="w-full appearance-none bg-white/[0.06] border border-white/15 rounded-lg text-sm text-white/80 min-h-[38px] px-3 py-2 pr-8 focus:outline-none focus:border-white/40 focus:ring-2 focus:ring-white/10 transition-colors cursor-pointer"
                >
                    <option value="">Tous</option>
                    {options.map(o => <option key={o} value={o}>{o}</option>)}
                </select>
                <ChevronDown
                    size={16}
                    className="absolute right-2.5 top-1/2 -translate-y-1/2 text-white/30 pointer-events-none"
                />
            </div>
        </div>
    );
}

// ─── Main component ───────────────────────────────────────────────────────────

interface Props {
    onApply: (params: FeatureParams) => void;
    loading?: boolean;
}

export default function FilterPanel({ onApply, loading = false }: Props) {
    const [open, setOpen] = useState(true);
    const PANEL_W  = 300;
    const TOGGLE_W = 20;

    // Filter state
    const [search,          setSearch]          = useState('');
    const [dateRange,       setDateRange]       = useState<DateRangeValue>({
        from: new Date(MIN_YEAR, 0, 1),
        to:   new Date(),
    });
    const [grandeFamille,   setGrandeFamille]   = useState<GrandeFamille>('tous');
    const [sousDossiers,    setSousDossiers]    = useState<Set<string>>(new Set());
    const [sousAnnuaire,    setSousAnnuaire]    = useState<Set<string>>(new Set());
    const [cadre,           setCadre]           = useState('');
    const [effluents,       setEffluents]       = useState('');
    const [dispositif,      setDispositif]      = useState('');
    const [ehRange,         setEhRange]         = useState<[number, number]>([2, 20]);
    const [ehPlus20,        setEhPlus20]        = useState(false);
    const [nomInstallateur, setNomInstallateur] = useState('');

    const [counts,        setCounts]        = useState<FilterCounts>(EMPTY_COUNTS);
    const [countsLoading, setCountsLoading] = useState(false);

    // Fetch counts, déboncé sur la période et le filtre EH
    useEffect(() => {
        setCountsLoading(true);
        const timer = setTimeout(() => {
            const qs = new URLSearchParams({
                date_from: format(dateRange.from, 'yyyy-MM-dd'),
                date_to:   format(dateRange.to,   'yyyy-MM-dd'),
                eh_min:    String(ehRange[0]),
                eh_max:    String(ehRange[1]),
                eh_plus20: ehPlus20 ? '1' : '0',
            });
            fetch(`/api/carte/counts?${qs}`)
                .then(r => r.json())
                .then((data: FilterCounts) => { setCounts(data); setCountsLoading(false); })
                .catch(() => setCountsLoading(false));
        }, 400);
        return () => clearTimeout(timer);
    }, [dateRange, ehRange, ehPlus20]);

    const showAvance = grandeFamille === 'dossiers'
        && (sousDossiers.has('Chantiers') || sousDossiers.has('Stations'));

    function toggleSet(set: Set<string>, key: string, setter: (s: Set<string>) => void) {
        const next = new Set(set);
        next.has(key) ? next.delete(key) : next.add(key);
        setter(next);
    }

    function reset() {
        setSearch('');
        setDateRange({ from: new Date(MIN_YEAR, 0, 1), to: new Date() });
        setGrandeFamille('tous');
        setSousDossiers(new Set());
        setSousAnnuaire(new Set());
        setCadre('');
        setEffluents('');
        setDispositif('');
        setEhRange([2, 20]);
        setEhPlus20(false);
        setNomInstallateur('');
    }

    function apply() {
        const types = [
            ...(grandeFamille !== 'annuaire' ? [...sousDossiers] : []),
            ...(grandeFamille !== 'dossiers' ? [...sousAnnuaire] : []),
        ];
        onApply({
            famille:    grandeFamille,
            types,
            search,
            date_from:  format(dateRange.from, 'yyyy-MM-dd'),
            date_to:    format(dateRange.to,   'yyyy-MM-dd'),
            eh_min:     ehRange[0],
            eh_max:     ehRange[1],
            eh_plus20:  ehPlus20,
        });
    }

    return (
        <div
            className="absolute right-0 top-0 h-full flex transition-transform duration-300 ease-in-out z-10"
            style={{ transform: open ? 'translateX(0)' : `translateX(${PANEL_W}px)` }}
        >
            {/* Languette — .side-panel__collapse */}
            <button
                onClick={() => setOpen(!open)}
                style={{ width: TOGGLE_W }}
                className="flex-shrink-0 flex flex-col items-center justify-center gap-1.5 bg-aqua-800 hover:bg-aqua-700 border border-r-0 border-white/10 rounded-l-xl transition-colors"
                title={open ? 'Masquer les filtres' : 'Afficher les filtres'}
                aria-label={open ? 'Masquer les filtres' : 'Afficher les filtres'}
            >
                {open
                    ? <ChevronRight size={13} className="text-aqua-300" />
                    : <ChevronLeft  size={13} className="text-aqua-300" />}
            </button>

            {/* Panel — .side-panel */}
            <div style={{ width: PANEL_W }} className="flex flex-col h-full bg-aqua-800 border-l border-white/10 overflow-hidden shadow-[-4px_0_24px_rgba(0,0,0,0.25)]">

                {/* En-tête */}
                <div className="flex items-center justify-between px-5 py-4 border-b border-white/10 flex-shrink-0">
                    <span className="flex items-center gap-2 text-sm font-semibold text-white">
                        <SlidersHorizontal size={14} className="text-white/40" />
                        Filtres
                    </span>
                    <button
                        onClick={reset}
                        className="flex items-center gap-1 text-xs font-medium text-white/40 hover:text-white/80 transition-colors"
                    >
                        <RotateCcw size={11} />
                        Réinitialiser
                    </button>
                </div>

                {/* Contenu scrollable */}
                <div className="flex-1 overflow-y-auto">

                    {/* ── Recherche — .input-wrapper */}
                    <div className="px-5 py-3 border-b border-white/10">
                        <div className="relative">
                            <Search size={14} className="absolute left-3 top-1/2 -translate-y-1/2 text-white/30 pointer-events-none" />
                            <input
                                type="text"
                                value={search}
                                onChange={e => setSearch(e.target.value)}
                                placeholder="Nom, raison sociale, ville…"
                                className="w-full min-h-[38px] bg-white/[0.06] border border-white/15 rounded-lg text-sm text-white/80 placeholder-white/25 pl-9 pr-3 py-2 focus:outline-none focus:border-white/40 focus:ring-2 focus:ring-white/10 transition-colors"
                            />
                        </div>
                    </div>

                    {/* ── Période — date range picker */}
                    <Section label="Période">
                        <div className="py-1">
                            <DateRangePicker value={dateRange} onChange={setDateRange} />
                        </div>
                    </Section>

                    {/* ── Grande famille — radio */}
                    <Section label="Famille">
                        <div className="space-y-0.5">
                            <RadioRow
                                label="Tout afficher"
                                selected={grandeFamille === 'tous'}
                                onClick={() => setGrandeFamille('tous')}
                                count={counts.grandeFamille.dossiers + counts.grandeFamille.annuaire}
                                countsLoading={countsLoading}
                            />
                            <RadioRow
                                label="Dossiers"
                                selected={grandeFamille === 'dossiers'}
                                onClick={() => setGrandeFamille('dossiers')}
                                count={counts.grandeFamille.dossiers}
                                countsLoading={countsLoading}
                            />
                            <RadioRow
                                label="Annuaire"
                                selected={grandeFamille === 'annuaire'}
                                onClick={() => setGrandeFamille('annuaire')}
                                count={counts.grandeFamille.annuaire}
                                countsLoading={countsLoading}
                            />
                        </div>
                    </Section>

                    {/* ── Sous-famille Dossiers — checkbox */}
                    {(grandeFamille === 'tous' || grandeFamille === 'dossiers') && (
                        <Section label="Type de dossier">
                            {SOUS_FAMILLE_DOSSIERS.map(sf => (
                                <CheckRow
                                    key={sf}
                                    label={sf}
                                    checked={sousDossiers.has(sf)}
                                    onChange={() => toggleSet(sousDossiers, sf, setSousDossiers)}
                                    count={counts.sousFamilleDossiers[sf] ?? 0}
                                    color={PIN_COLOR[sf]}
                                    countsLoading={countsLoading}
                                />
                            ))}
                        </Section>
                    )}

                    {/* ── Sous-famille Annuaire — checkbox */}
                    {(grandeFamille === 'tous' || grandeFamille === 'annuaire') && (
                        <Section label="Type de contact">
                            {SOUS_FAMILLE_ANNUAIRE.map(sf => (
                                <CheckRow
                                    key={sf}
                                    label={sf}
                                    checked={sousAnnuaire.has(sf)}
                                    onChange={() => toggleSet(sousAnnuaire, sf, setSousAnnuaire)}
                                    count={counts.sousFamilleAnnuaire[sf] ?? 0}
                                    color={PIN_COLOR[sf]}
                                    countsLoading={countsLoading}
                                />
                            ))}
                        </Section>
                    )}

                    {/* ── Filtres avancés Chantiers / Stations */}
                    {showAvance && (
                        <Section label="Détails chantier / station" defaultOpen={false}>
                            <SelectField
                                label="Cadre réglementaire"
                                options={['ANC', 'ICPE', 'Collectif']}
                                value={cadre}
                                onChange={setCadre}
                            />
                            <SelectField
                                label="Type d'effluents"
                                options={['Eaux usées domestiques', 'Eaux pluviales', 'Eaux industrielles']}
                                value={effluents}
                                onChange={setEffluents}
                            />
                            <SelectField
                                label="Dispositif"
                                options={['Fosse toutes eaux', 'Microstation', 'Filtre planté', 'Lagunage']}
                                value={dispositif}
                                onChange={setDispositif}
                            />
                            <div className="flex flex-col gap-1 pt-1">
                                <div className="flex items-center justify-between">
                                    <label className="text-xs font-medium text-white/50">Capacité EH</label>
                                    <span className="text-xs text-white/60 tabular-nums font-medium">
                                        {ehRange[0]} – {ehRange[1]} EH
                                    </span>
                                </div>
                                <Slider.Root
                                    min={2} max={20} step={1}
                                    value={ehRange}
                                    onValueChange={v => setEhRange(v as [number, number])}
                                    className="relative flex items-center w-full h-5 select-none touch-none mt-1"
                                >
                                    <Slider.Track className="relative h-1 flex-1 rounded-full bg-white/15">
                                        <Slider.Range className="absolute h-full rounded-full bg-aqua-500" />
                                    </Slider.Track>
                                    <Slider.Thumb className="block w-[18px] h-[18px] bg-white rounded-full shadow-md border-2 border-aqua-400 focus:outline-none focus:ring-2 focus:ring-aqua-400/50 cursor-grab active:cursor-grabbing transition-transform hover:scale-110" />
                                    <Slider.Thumb className="block w-[18px] h-[18px] bg-white rounded-full shadow-md border-2 border-aqua-400 focus:outline-none focus:ring-2 focus:ring-aqua-400/50 cursor-grab active:cursor-grabbing transition-transform hover:scale-110" />
                                </Slider.Root>
                                <div className="mt-1">
                                    <CheckRow
                                        label="+ de 20 EH"
                                        checked={ehPlus20}
                                        onChange={setEhPlus20}
                                    />
                                </div>
                            </div>
                            <div className="flex flex-col gap-1 pt-1">
                                <label className="text-xs font-medium text-white/50">Nom de l'installateur</label>
                                <input
                                    type="text"
                                    value={nomInstallateur}
                                    onChange={e => setNomInstallateur(e.target.value)}
                                    placeholder="Rechercher…"
                                    className="w-full min-h-[38px] bg-white/[0.06] border border-white/15 rounded-lg text-sm text-white/80 placeholder-white/25 px-3 py-2 focus:outline-none focus:border-white/40 focus:ring-2 focus:ring-white/10 transition-colors"
                                />
                            </div>
                        </Section>
                    )}

                </div>

                {/* Footer — btn--primary */}
                <div className="px-5 py-4 border-t border-white/10 flex-shrink-0">
                    <button
                        onClick={apply}
                        disabled={loading}
                        className="w-full bg-aqua-500 hover:bg-aqua-400 active:bg-aqua-600 disabled:opacity-40 disabled:cursor-wait text-white text-sm font-black py-[0.625rem] rounded-full transition-colors tracking-wide shadow-md"
                    >
                        {loading ? 'Chargement…' : 'Appliquer les filtres'}
                    </button>
                </div>
            </div>
        </div>
    );
}
