import React, { useState, useEffect, useRef, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
    Zap, X, ChevronDown, ChevronRight, Wifi, WifiOff, MessageSquare,
    Send, Image, FileText, Video, Music, Phone, Users, RefreshCw,
    CheckCheck, AlertCircle, QrCode, Link, Unlink, Trash2, Activity,
    ArrowDownLeft, ArrowUpRight, Filter, LayoutGrid, ShieldCheck, Clock
} from 'lucide-react';
import { io, Socket } from 'socket.io-client';

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

type EventCategory = 'all' | 'connection' | 'received' | 'sent' | 'media' | 'chat' | 'system';

interface BaileysEvent {
    id: string;
    timestamp: number;
    sessionId: string;
    event: string;
    data: any;
    category: EventCategory;
    mediaType?: 'image' | 'video' | 'audio' | 'document' | 'sticker';
    fromMe?: boolean;
}

interface SessionStats {
    received: number;
    sent: number;
    media: number;
    chats: number;
}

interface SessionInfo {
    id: string;
    name?: string;
    status: 'connected' | 'disconnected' | 'connecting' | 'qr';
    lastSeen: number;
    eventCount: number;
    events: BaileysEvent[];
    engine?: 'infinite' | 'official';
    dbStats?: SessionStats;        // contagens do banco (carregadas no mount)
    liveStats?: Partial<SessionStats>; // incrementos ao vivo (Socket.IO)
}

// ─── Método de envio: labels para o usuário final ─────────────────────────────
const METODOS = [
    {
        value: 'infinite' as const,
        label: 'Método 1',
        desc: 'Com botões',
        hint: 'Instável',
        icon: <LayoutGrid size={11} />,
        color: 'text-amber-400',
        bg: 'bg-amber-500/10',
        border: 'border-amber-500/30',
        dot: 'bg-amber-400',
    },
    {
        value: 'official' as const,
        label: 'Método 2',
        desc: 'Sem botões',
        hint: 'Estável',
        icon: <ShieldCheck size={11} />,
        color: 'text-emerald-400',
        bg: 'bg-emerald-500/10',
        border: 'border-emerald-500/30',
        dot: 'bg-emerald-400',
    },
];

// ─── Helpers ──────────────────────────────────────────────────────────────────

function fmtCount(n: number): string {
    if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
    if (n >= 1_000)     return `${(n / 1_000).toFixed(n >= 10_000 ? 0 : 1)}k`;
    return String(n);
}

function categorizeEvent(event: string, data: any): { category: EventCategory; mediaType?: BaileysEvent['mediaType']; fromMe?: boolean } {
    const e = event.toLowerCase();

    if (e.includes('connection') || e.includes('qr') || e.includes('connect') || e.includes('disconnect') || e.includes('open') || e.includes('close')) {
        return { category: 'connection' };
    }
    if (e.includes('message') || e.includes('msg')) {
        const fromMe = data?.fromMe ?? data?.key?.fromMe ?? false;
        let mediaType: BaileysEvent['mediaType'] | undefined;
        if (data?.imageMessage || data?.message?.imageMessage) mediaType = 'image';
        else if (data?.videoMessage || data?.message?.videoMessage) mediaType = 'video';
        else if (data?.audioMessage || data?.message?.audioMessage) mediaType = 'audio';
        else if (data?.documentMessage || data?.message?.documentMessage) mediaType = 'document';
        else if (data?.stickerMessage || data?.message?.stickerMessage) mediaType = 'sticker';

        if (mediaType) return { category: 'media', mediaType, fromMe };
        return { category: fromMe ? 'sent' : 'received', fromMe };
    }
    if (e.includes('chat')) return { category: 'chat' };
    return { category: 'system' };
}

function parseData(raw: any): any {
    if (typeof raw === 'string') {
        try { return JSON.parse(raw); } catch { return raw; }
    }
    return raw;
}

const EVENT_META: Record<EventCategory, { color: string; bg: string; label: string }> = {
    all:        { color: 'text-slate-300',  bg: 'bg-slate-500/20',  label: 'Todos' },
    connection: { color: 'text-emerald-400', bg: 'bg-emerald-500/20', label: 'Conexão' },
    received:   { color: 'text-blue-400',   bg: 'bg-blue-500/20',   label: 'Recebidas' },
    sent:       { color: 'text-brand-400',  bg: 'bg-brand-500/20',  label: 'Enviadas' },
    media:      { color: 'text-purple-400', bg: 'bg-purple-500/20', label: 'Mídia' },
    chat:       { color: 'text-yellow-400', bg: 'bg-yellow-500/20', label: 'Chats' },
    system:     { color: 'text-slate-400',  bg: 'bg-slate-500/20',  label: 'Sistema' },
};

function EventIcon({ ev }: { ev: BaileysEvent }) {
    const cls = 'w-4 h-4 shrink-0';
    if (ev.category === 'connection') {
        if (ev.event.toLowerCase().includes('qr')) return <QrCode className={`${cls} text-yellow-400`} />;
        if (ev.event.toLowerCase().includes('disconnect') || ev.event.toLowerCase().includes('close')) return <Unlink className={`${cls} text-red-400`} />;
        return <Link className={`${cls} text-emerald-400`} />;
    }
    if (ev.category === 'sent') return <ArrowUpRight className={`${cls} text-brand-400`} />;
    if (ev.category === 'received') return <ArrowDownLeft className={`${cls} text-blue-400`} />;
    if (ev.category === 'media') {
        if (ev.mediaType === 'image') return <Image className={`${cls} text-purple-400`} />;
        if (ev.mediaType === 'video') return <Video className={`${cls} text-pink-400`} />;
        if (ev.mediaType === 'audio') return <Music className={`${cls} text-orange-400`} />;
        if (ev.mediaType === 'document') return <FileText className={`${cls} text-cyan-400`} />;
        return <Image className={`${cls} text-purple-400`} />;
    }
    if (ev.category === 'chat') return <MessageSquare className={`${cls} text-yellow-400`} />;
    return <Activity className={`${cls} text-slate-400`} />;
}

function eventSummary(ev: BaileysEvent): string {
    const d = ev.data;
    if (!d) return ev.event;
    if (ev.category === 'connection') {
        if (d.connection) return `connection → ${d.connection}`;
        if (typeof d === 'string') return d;
    }
    if (ev.category === 'sent' || ev.category === 'received') {
        const text = d.body || d.message?.conversation || d.message?.extendedTextMessage?.text || d.text;
        if (text) return String(text).slice(0, 80);
        const jid = d.key?.remoteJid || d.remoteJid || '';
        return jid ? `→ ${jid}` : ev.event;
    }
    if (ev.category === 'media') {
        const jid = d.key?.remoteJid || d.remoteJid || '';
        return `${ev.mediaType ?? 'media'} ${jid ? `→ ${jid}` : ''}`;
    }
    if (ev.category === 'chat') {
        return d.id || d.jid || ev.event;
    }
    return ev.event;
}

// ─── EventRow ─────────────────────────────────────────────────────────────────

function EventRow({ ev, index }: { ev: BaileysEvent; index: number }) {
    const [open, setOpen] = useState(false);
    const meta = EVENT_META[ev.category];

    return (
        <motion.div
            initial={{ opacity: 0, y: -4 }}
            animate={{ opacity: 1, y: 0 }}
            transition={{ duration: 0.15, delay: index < 20 ? index * 0.01 : 0 }}
            className="border-b border-white/[0.04] last:border-0"
        >
            <button
                onClick={() => setOpen(o => !o)}
                className="w-full flex items-center gap-3 px-4 py-2.5 hover:bg-white/[0.03] transition-colors text-left group"
            >
                {/* Index */}
                <span className="text-[10px] font-mono text-slate-600 w-6 shrink-0 text-right">{index + 1}</span>

                {/* Icon */}
                <EventIcon ev={ev} />

                {/* Event name badge */}
                <span className={`text-[10px] font-black uppercase tracking-wider px-2 py-0.5 rounded-full shrink-0 ${meta.bg} ${meta.color}`}>
                    {ev.event}
                </span>

                {/* Summary */}
                <span className="text-sm text-slate-400 truncate flex-1 font-mono">
                    {eventSummary(ev)}
                </span>

                {/* Time */}
                <span className="text-[10px] text-slate-600 shrink-0">
                    {new Date(ev.timestamp).toLocaleTimeString('pt-BR')}
                </span>

                {/* Chevron */}
                <span className="shrink-0 text-slate-600 group-hover:text-slate-400 transition-colors">
                    {open ? <ChevronDown size={14} /> : <ChevronRight size={14} />}
                </span>
            </button>

            <AnimatePresence>
                {open && (
                    <motion.div
                        initial={{ height: 0, opacity: 0 }}
                        animate={{ height: 'auto', opacity: 1 }}
                        exit={{ height: 0, opacity: 0 }}
                        transition={{ duration: 0.2 }}
                        className="overflow-hidden"
                    >
                        <div className="mx-4 mb-3 bg-black/60 rounded-xl border border-white/5 overflow-hidden">
                            <div className="flex items-center gap-2 px-3 py-2 border-b border-white/5 bg-white/[0.02]">
                                <span className="text-[10px] font-black uppercase tracking-widest text-slate-500">Payload</span>
                                <span className="text-[10px] text-slate-600 ml-auto">{new Date(ev.timestamp).toLocaleString('pt-BR')}</span>
                            </div>
                            <pre className="p-3 text-[11px] font-mono text-slate-300 overflow-x-auto whitespace-pre-wrap leading-relaxed max-h-60">
                                {JSON.stringify(ev.data, null, 2)}
                            </pre>
                        </div>
                    </motion.div>
                )}
            </AnimatePresence>
        </motion.div>
    );
}

// ─── Session Modal ─────────────────────────────────────────────────────────────

function SessionModal({ session, onClose }: { session: SessionInfo; onClose: () => void }) {
    const [filter, setFilter] = useState<EventCategory>('all');

    const filtered = filter === 'all' ? session.events : session.events.filter(e => e.category === filter);

    const counts = session.events.reduce<Record<string, number>>((acc, e) => {
        acc[e.category] = (acc[e.category] || 0) + 1;
        return acc;
    }, {});

    const categories: EventCategory[] = ['all', 'connection', 'received', 'sent', 'media', 'chat', 'system'];

    return (
        <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            className="fixed inset-0 z-50 flex items-center justify-center p-4"
            onClick={onClose}
        >
            <div className="absolute inset-0 bg-black/80 backdrop-blur-sm" />

            <motion.div
                initial={{ scale: 0.95, opacity: 0, y: 10 }}
                animate={{ scale: 1, opacity: 1, y: 0 }}
                exit={{ scale: 0.95, opacity: 0, y: 10 }}
                transition={{ duration: 0.2 }}
                className="relative w-full max-w-4xl max-h-[85vh] bg-[#0d0f18] border border-white/10 rounded-2xl shadow-2xl shadow-black/60 flex flex-col overflow-hidden"
                onClick={e => e.stopPropagation()}
            >
                {/* Header */}
                <div className="flex items-center gap-3 px-5 py-4 border-b border-white/[0.06] bg-white/[0.02] shrink-0">
                    <div className={`w-2.5 h-2.5 rounded-full shrink-0 ${
                        session.status === 'connected' ? 'bg-emerald-500 shadow-[0_0_8px_#10b981]' :
                        session.status === 'qr' ? 'bg-yellow-400 shadow-[0_0_8px_#facc15]' :
                        'bg-red-500'
                    }`} />
                    <div>
                        <h2 className="text-white font-bold text-sm">{session.name || session.id.slice(0, 8)}</h2>
                        <p className="text-[10px] text-slate-500 uppercase tracking-widest font-black">
                            {session.status} · {session.eventCount} eventos
                        </p>
                    </div>
                    <button
                        onClick={onClose}
                        className="ml-auto p-1.5 hover:bg-white/10 rounded-lg text-slate-500 hover:text-white transition-colors"
                    >
                        <X size={16} />
                    </button>
                </div>

                {/* Filter Tabs */}
                <div className="flex items-center gap-1 px-4 py-2 border-b border-white/[0.06] bg-black/20 overflow-x-auto shrink-0">
                    <Filter size={12} className="text-slate-600 mr-1 shrink-0" />
                    {categories.map(cat => {
                        const meta = EVENT_META[cat];
                        const count = cat === 'all' ? session.events.length : (counts[cat] || 0);
                        if (count === 0 && cat !== 'all') return null;
                        return (
                            <button
                                key={cat}
                                onClick={() => setFilter(cat)}
                                className={`flex items-center gap-1.5 px-3 py-1 rounded-full text-[10px] font-black uppercase tracking-wider transition-all whitespace-nowrap ${
                                    filter === cat
                                        ? `${meta.bg} ${meta.color} border border-current/20`
                                        : 'text-slate-500 hover:text-slate-300 hover:bg-white/5'
                                }`}
                            >
                                {meta.label}
                                <span className={`px-1.5 py-0.5 rounded-full text-[9px] ${filter === cat ? 'bg-black/30' : 'bg-white/5'}`}>
                                    {count}
                                </span>
                            </button>
                        );
                    })}
                </div>

                {/* Events List */}
                <div className="flex-1 overflow-y-auto">
                    {filtered.length === 0 ? (
                        <div className="flex flex-col items-center justify-center h-40 text-slate-600">
                            <Activity size={24} className="mb-2 opacity-40" />
                            <span className="text-sm">Nenhum evento nesta categoria</span>
                        </div>
                    ) : (
                        <div>
                            {[...filtered].reverse().map((ev, i) => (
                                <EventRow key={ev.id} ev={ev} index={i} />
                            ))}
                        </div>
                    )}
                </div>

                {/* Footer */}
                <div className="px-5 py-2.5 border-t border-white/[0.06] bg-black/20 shrink-0 flex items-center gap-2">
                    <span className="text-[10px] text-slate-600 font-mono">
                        Última atividade: {new Date(session.lastSeen).toLocaleString('pt-BR')}
                    </span>
                    <span className="ml-auto text-[10px] text-slate-600">
                        Exibindo {filtered.length} de {session.eventCount} eventos
                    </span>
                </div>
            </motion.div>
        </motion.div>
    );
}

// ─── Session Card ──────────────────────────────────────────────────────────────

function SessionCard({
    session,
    onClick,
    onEngineChange,
}: {
    session: SessionInfo;
    onClick: () => void;
    onEngineChange: (instanceId: string, engine: 'infinite' | 'official') => Promise<void>;
}) {
    const [switching, setSwitching] = useState(false);
    const [cooldownSec, setCooldownSec] = useState(0);

    // Soma contagens do banco (base) + eventos ao vivo da sessão atual
    const liveCounts = session.events.reduce<Record<string, number>>((acc, e) => {
        acc[e.category] = (acc[e.category] || 0) + 1;
        return acc;
    }, {});

    const db = session.dbStats;
    const counts = {
        received: (db?.received ?? 0) + (liveCounts.received ?? 0),
        sent:     (db?.sent     ?? 0) + (liveCounts.sent     ?? 0),
        media:    (db?.media    ?? 0) + (liveCounts.media    ?? 0),
        chat:     (db?.chats    ?? 0) + (liveCounts.chat     ?? 0),
    };

    const statusColor = session.status === 'connected'
        ? 'text-emerald-400 bg-emerald-500/10 border-emerald-500/20'
        : session.status === 'qr'
        ? 'text-yellow-400 bg-yellow-500/10 border-yellow-500/20'
        : 'text-red-400 bg-red-500/10 border-red-500/20';

    const dotColor = session.status === 'connected'
        ? 'bg-emerald-500 shadow-[0_0_8px_#10b981] animate-pulse'
        : session.status === 'qr'
        ? 'bg-yellow-400 shadow-[0_0_8px_#facc15] animate-pulse'
        : 'bg-red-500';

    const currentEngine = session.engine ?? 'infinite';

    const handleMethod = async (e: React.MouseEvent, value: 'infinite' | 'official') => {
        e.stopPropagation();
        if (value === currentEngine || switching || cooldownSec > 0) return;
        setSwitching(true);
        try {
            await onEngineChange(session.id, value);
        } catch (err: any) {
            // Extrai segundos do cooldown se retornou 429
            const match = String(err?.message ?? '').match(/(\d+)s/);
            if (match) {
                let secs = parseInt(match[1]);
                setCooldownSec(secs);
                const tick = setInterval(() => {
                    secs--;
                    setCooldownSec(secs);
                    if (secs <= 0) clearInterval(tick);
                }, 1000);
            }
        } finally {
            setSwitching(false);
        }
    };

    return (
        <motion.div
            initial={{ opacity: 0, scale: 0.95 }}
            animate={{ opacity: 1, scale: 1 }}
            whileHover={{ y: -2, borderColor: 'rgba(255,255,255,0.12)' }}
            className="w-full text-left bg-white/[0.03] border border-white/[0.06] rounded-xl p-4 hover:bg-white/[0.05] transition-all group"
        >
            {/* Header — clicável para abrir modal */}
            <button onClick={onClick} className="w-full text-left">
                <div className="flex items-start justify-between mb-3">
                    <div className="flex items-center gap-2 min-w-0">
                        <div className={`w-2 h-2 rounded-full shrink-0 ${dotColor}`} />
                        <span className="text-white font-bold text-sm truncate">{session.name || session.id.slice(0, 8)}</span>
                    </div>
                    <span className={`text-[9px] font-black uppercase tracking-widest px-2 py-0.5 rounded-full border shrink-0 ml-2 ${statusColor}`}>
                        {session.status}
                    </span>
                </div>

                {/* Stats row */}
                <div className="grid grid-cols-4 gap-1.5 mb-3">
                    {[
                        { icon: <ArrowDownLeft size={10} />, val: counts.received, color: 'text-blue-400' },
                        { icon: <ArrowUpRight size={10} />, val: counts.sent,     color: 'text-brand-400' },
                        { icon: <Image size={10} />,        val: counts.media,    color: 'text-purple-400' },
                        { icon: <MessageSquare size={10} />, val: counts.chat,    color: 'text-yellow-400' },
                    ].map((s, i) => (
                        <div key={i} className="bg-black/40 rounded-lg py-1.5 px-2 flex flex-col items-center gap-0.5">
                            <span className={s.color}>{s.icon}</span>
                            <span className="text-[11px] font-black text-white">{fmtCount(s.val)}</span>
                        </div>
                    ))}
                </div>
            </button>

            {/* Método de envio */}
            <div className="mt-2">
                <p className="text-[10px] font-black uppercase tracking-widest text-slate-500 mb-2">
                    Modo de envio
                </p>
                <div className="flex gap-2">
                    {METODOS.map(m => {
                        const isActive = currentEngine === m.value;
                        return (
                            <button
                                key={m.value}
                                onClick={(e) => handleMethod(e, m.value)}
                                disabled={switching || cooldownSec > 0}
                                title={isActive ? 'Método atual' : `Trocar para ${m.label}`}
                                className={`flex-1 flex flex-col gap-1 px-3 py-2.5 rounded-xl border text-left transition-all
                                    ${isActive
                                        ? `${m.bg} ${m.border} ${m.color}`
                                        : 'bg-white/[0.02] border-white/[0.06] text-slate-500 hover:border-white/20 hover:text-slate-300'
                                    }
                                    ${(switching || cooldownSec > 0) ? 'opacity-60 cursor-not-allowed' : 'cursor-pointer'}
                                `}
                            >
                                <div className="flex items-center gap-1.5">
                                    {switching && !isActive
                                        ? <RefreshCw size={12} className="animate-spin" />
                                        : m.icon
                                    }
                                    <span className="text-[11px] font-black leading-none">{m.label}</span>
                                    {isActive && (
                                        <span className={`w-1.5 h-1.5 rounded-full ${m.dot} ml-auto shrink-0`} />
                                    )}
                                </div>
                                <span className="text-[11px] leading-tight font-semibold">{m.desc}</span>
                                <span className={`text-[10px] leading-tight ${isActive ? 'opacity-90 font-bold' : 'opacity-50'}`}>
                                    {m.hint}
                                </span>
                            </button>
                        );
                    })}
                </div>

                {/* Cooldown warning */}
                {cooldownSec > 0 && (
                    <div className="mt-2 flex items-center gap-1.5 text-[10px] text-amber-500/80">
                        <Clock size={10} />
                        <span>Aguarde {cooldownSec}s para trocar novamente</span>
                    </div>
                )}
            </div>

            {/* Footer */}
            <div className="flex items-center justify-between mt-2 pt-2 border-t border-white/[0.04]">
                <span className="text-[10px] text-slate-600 font-mono">
                    {session.eventCount} eventos
                </span>
                <span className="text-[10px] text-slate-600 font-mono">
                    {new Date(session.lastSeen).toLocaleTimeString('pt-BR')}
                </span>
            </div>
        </motion.div>
    );
}

// ─── Main Page ─────────────────────────────────────────────────────────────────

export default function BaileysPage() {
    const [sessions, setSessions] = useState<Map<string, SessionInfo>>(new Map());
    const [selectedSession, setSelectedSession] = useState<SessionInfo | null>(null);
    const [listening, setListening] = useState(true);
    const socketRef = useRef<Socket | null>(null);

    const handleEngineChange = useCallback(async (instanceId: string, engine: 'infinite' | 'official') => {
        const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8008';
        const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
        const res = await fetch(`${API_URL}/api/instances/${instanceId}/engine`, {
            method: 'PATCH',
            headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${token}` },
            body: JSON.stringify({ engine }),
        });
        if (res.status === 429) {
            const data = await res.json().catch(() => ({}));
            throw new Error(data.error ?? 'Cooldown ativo');
        }
        if (!res.ok) throw new Error('Falha ao trocar engine');
        // Atualiza engine na sessão local imediatamente
        setSessions(prev => {
            const next = new Map(prev);
            const existing = next.get(instanceId);
            if (existing) next.set(instanceId, { ...existing, engine });
            return next;
        });
    }, []);

    const addEvent = useCallback((raw: Omit<BaileysEvent, 'id' | 'category' | 'mediaType' | 'fromMe'> & { data: any }) => {
        const data = parseData(raw.data);
        const { category, mediaType, fromMe } = categorizeEvent(raw.event, data);
        const ev: BaileysEvent = {
            // crypto.randomUUID garante unicidade — evita colisões nos keys do React
            id: typeof crypto !== 'undefined' && crypto.randomUUID ? crypto.randomUUID() : `${Date.now()}-${Math.random()}`,
            timestamp: raw.timestamp ?? Date.now(),
            sessionId: raw.sessionId,
            event: raw.event,
            data,
            category,
            mediaType,
            fromMe,
        };

        setSessions(prev => {
            const next = new Map(prev);
            const existing = next.get(ev.sessionId) ?? {
                id: ev.sessionId,
                status: 'connecting' as const,
                lastSeen: ev.timestamp,
                eventCount: 0,
                events: [],
            };

            let status = existing.status;
            if (category === 'connection') {
                const e = ev.event.toLowerCase();
                const connVal = data?.connection;
                if (connVal === 'open' || e.includes('connected')) status = 'connected';
                else if (connVal === 'close' || e.includes('disconnected')) status = 'disconnected';
                else if (e.includes('qr')) status = 'qr';
            }

            const events = [...existing.events, ev].slice(-300);
            const updated: SessionInfo = {
                ...existing,
                status,
                lastSeen: ev.timestamp,
                eventCount: existing.eventCount + 1,
                events,
            };
            next.set(ev.sessionId, updated);
            return next;
        });
    }, []);

    // Mantém o modal sincronizado com o estado mais recente da sessão selecionada.
    // Feito via useEffect (fora do updater de setSessions) para evitar o anti-pattern
    // de chamar setState dentro de outro setState updater.
    useEffect(() => {
        if (!selectedSession) return;
        setSelectedSession(sel => {
            if (!sel) return sel;
            const fresh = sessions.get(sel.id);
            return fresh ?? sel;
        });
    }, [sessions]);

    // Carrega estado inicial das instâncias via API
    useEffect(() => {
        const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8008';
        const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
        if (!token) return;

        const headers = { Authorization: `Bearer ${token}` };

        fetch(`${API_URL}/api/instances`, { headers })
            .then(r => r.json())
            .then(async (instances: any[]) => {
                if (!Array.isArray(instances)) return;

                // Busca stats de cada instância em paralelo
                const statsResults = await Promise.allSettled(
                    instances.map(inst =>
                        fetch(`${API_URL}/api/instances/${inst.id}/stats`, { headers })
                            .then(r => r.ok ? r.json() : null)
                            .catch(() => null)
                    )
                );

                setSessions(prev => {
                    const next = new Map(prev);
                    const statusMap: Record<string, SessionInfo['status']> = {
                        CONNECTED: 'connected', DISCONNECTED: 'disconnected',
                        CONNECTING: 'connecting', QR_PENDING: 'qr', BANNED: 'disconnected',
                    };
                    instances.forEach((inst, idx) => {
                        const existing = next.get(inst.id);
                        const engine: 'infinite' | 'official' = inst.engine === 'official' ? 'official' : 'infinite';
                        const statsResult = statsResults[idx];
                        const dbStats: SessionStats | undefined =
                            statsResult.status === 'fulfilled' && statsResult.value
                                ? statsResult.value
                                : undefined;
                        if (existing) {
                            next.set(inst.id, {
                                ...existing,
                                ...(inst.name ? { name: inst.name } : {}),
                                engine,
                                ...(dbStats ? { dbStats } : {}),
                            });
                        } else {
                            next.set(inst.id, {
                                id: inst.id,
                                name: inst.name || undefined,
                                status: statusMap[inst.status] ?? 'disconnected',
                                lastSeen: Date.now(),
                                eventCount: 0,
                                events: [],
                                engine,
                                dbStats,
                            });
                        }
                    });
                    return next;
                });
            })
            .catch(() => {});
    }, []);

    useEffect(() => {
        if (!listening) return;
        const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8008';
        const token = typeof window !== 'undefined' ? localStorage.getItem('token') : null;
        if (!token) return;

        let socket: ReturnType<typeof io> | null = null;

        // Defer connection so React StrictMode's synchronous unmount/remount
        // cycle clears the timer before the WebSocket handshake starts.
        const timer = setTimeout(() => {
            const socketUrl = (() => {
                try { return new URL(API_URL).origin } catch { return API_URL }
            })()
            socket = io(socketUrl, {
                transports: ['websocket', 'polling'],
                auth: { token },
            });
            socketRef.current = socket;

            socket.on('connect_error', (err) => {
                console.warn('[Baileys] Socket connect error:', err.message);
            });

            socket.on('baileys:log', (log: any) => {
                addEvent({
                    timestamp: log.timestamp ? new Date(log.timestamp).getTime() : Date.now(),
                    sessionId: log.sessionId || 'unknown',
                    event: log.event || 'unknown',
                    data: log.data,
                });
            });
        }, 0);

        return () => {
            clearTimeout(timer);
            socket?.disconnect();
            socketRef.current = null;
        };
    }, [listening, addEvent]);

    const sessionList = Array.from(sessions.values()).sort((a, b) => b.lastSeen - a.lastSeen);

    return (
        <div className="p-8 max-w-7xl mx-auto h-full overflow-y-auto pb-20">
            {/* Header */}
            <motion.div initial={{ opacity: 0, y: -10 }} animate={{ opacity: 1, y: 0 }} className="flex items-center justify-between mb-8">
                <div className="flex items-center gap-4">
                    <div className="w-12 h-12 rounded-2xl bg-brand-500/10 border border-brand-500/20 flex items-center justify-center">
                        <Zap size={24} className="text-brand-400" />
                    </div>
                    <div>
                        <h1 className="text-2xl font-black text-white tracking-tight">Baileys Engine</h1>
                        <p className="text-slate-500 text-xs mt-0.5">
                            {sessionList.length} {sessionList.length === 1 ? 'sessão' : 'sessões'} monitoradas
                        </p>
                    </div>
                </div>

                <div className="flex items-center gap-2">
                    <button
                        onClick={() => { setSessions(new Map()); setSelectedSession(null); }}
                        className="p-2 hover:bg-white/5 rounded-lg text-slate-500 hover:text-white transition-colors"
                        title="Limpar"
                    >
                        <Trash2 size={16} />
                    </button>
                    <button
                        onClick={() => setListening(l => !l)}
                        className={`flex items-center gap-2 px-3 py-1.5 rounded-full text-[11px] font-black uppercase tracking-wider border transition-all ${
                            listening
                                ? 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20'
                                : 'bg-red-500/10 text-red-400 border-red-500/20'
                        }`}
                    >
                        <span className={`w-1.5 h-1.5 rounded-full ${listening ? 'bg-emerald-400 animate-pulse' : 'bg-red-400'}`} />
                        {listening ? 'Live' : 'Paused'}
                    </button>
                </div>
            </motion.div>

            {/* Sessions Grid */}
            {sessionList.length === 0 ? (
                <motion.div
                    initial={{ opacity: 0 }}
                    animate={{ opacity: 1 }}
                    className="flex flex-col items-center justify-center py-24 text-slate-600"
                >
                    <div className="w-16 h-16 rounded-2xl bg-white/[0.02] border border-white/5 flex items-center justify-center mb-4">
                        <Zap size={28} className="opacity-30" />
                    </div>
                    <p className="text-sm font-semibold mb-1">Nenhuma sessão detectada</p>
                    <p className="text-xs text-slate-700">Aguardando eventos do servidor Baileys...</p>
                </motion.div>
            ) : (
                <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 xl:grid-cols-4 gap-4">
                    <AnimatePresence>
                        {sessionList.map(session => (
                            <SessionCard
                                key={session.id}
                                session={session}
                                onClick={() => setSelectedSession(session)}
                                onEngineChange={handleEngineChange}
                            />
                        ))}
                    </AnimatePresence>
                </div>
            )}

            {/* Legend */}
            <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.3 }} className="mt-8 flex flex-wrap gap-3">
                {[
                    { icon: <ArrowDownLeft size={12} />, label: 'Recebida', color: 'text-blue-400' },
                    { icon: <ArrowUpRight size={12} />, label: 'Enviada', color: 'text-brand-400' },
                    { icon: <Image size={12} />, label: 'Imagem', color: 'text-purple-400' },
                    { icon: <Video size={12} />, label: 'Vídeo', color: 'text-pink-400' },
                    { icon: <Music size={12} />, label: 'Áudio', color: 'text-orange-400' },
                    { icon: <FileText size={12} />, label: 'Documento', color: 'text-cyan-400' },
                    { icon: <MessageSquare size={12} />, label: 'Chat', color: 'text-yellow-400' },
                    { icon: <Link size={12} />, label: 'Conexão', color: 'text-emerald-400' },
                ].map((item, i) => (
                    <div key={i} className={`flex items-center gap-1.5 text-[11px] ${item.color} bg-white/[0.03] px-2.5 py-1 rounded-full border border-white/5`}>
                        {item.icon}
                        <span className="font-semibold">{item.label}</span>
                    </div>
                ))}
            </motion.div>

            {/* Modal */}
            <AnimatePresence>
                {selectedSession && (
                    <SessionModal
                        session={selectedSession}
                        onClose={() => setSelectedSession(null)}
                    />
                )}
            </AnimatePresence>
        </div>
    );
}
