// ==========================================
// VISITOR SPY DASHBOARD MODULE
// Features: Real-time List, Wealth Audit (GPU/Network), Journey Timeline
// ==========================================

export default class VisitorSpy {
    constructor(containerId) {
        this.containerId = containerId;
        this.container = document.getElementById(containerId);
        
        // Internal State Management
        this.state = {
            data: {},                 // Raw data from Firebase
            processedList: [],        // Filtered & Sorted list
            selectedVisitorId: null,  // Currently viewed visitor
            filters: {
                search: '',
                status: 'all',        // all, online, offline
                intent: 'all',        // all, checkout, cart_activity
                wealth: 'all'         // all, Elite, Aspiring, Standard
            },
            stats: {
                total: 0,
                online: 0,
                eliteCount: 0         // Count of VIPs
            },
            currentPage: 1,
            itemsPerPage: 20
        };

        // Initialize UI and Events
        this.initLayout();
        this.attachGlobalEvents();
    }

    // ============================================================
    // 1. LAYOUT & UI STRUCTURE
    // ============================================================
    initLayout() {
        if (!this.container) return;

        this.container.innerHTML = `
            <div class="flex flex-col h-[calc(100vh-140px)] bg-gray-50/50 rounded-xl overflow-hidden border border-gray-200 shadow-sm relative font-sans">
                
                <!-- TOP: Real-time Stats Bar -->
                <div class="bg-white border-b border-gray-200 p-4 grid grid-cols-3 gap-4 shrink-0">
                    <!-- Total Visitors -->
                    <div class="bg-blue-50 border border-blue-100 rounded-lg p-3 flex items-center justify-between">
                        <div>
                            <p class="text-xs text-blue-500 font-bold uppercase tracking-wider">Total Traffic</p>
                            <h3 class="text-2xl font-bold text-blue-900" id="stat-total">0</h3>
                        </div>
                        <i class="fa-solid fa-users text-blue-200 text-2xl hidden sm:block"></i>
                    </div>
                    
                    <!-- Online Now -->
                    <div class="bg-green-50 border border-green-100 rounded-lg p-3 flex items-center justify-between">
                        <div>
                            <p class="text-xs text-green-600 font-bold uppercase tracking-wider flex items-center gap-2">
                                <span class="relative flex h-2 w-2">
                                  <span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span>
                                  <span class="relative inline-flex rounded-full h-2 w-2 bg-green-500"></span>
                                </span> Live Now
                            </p>
                            <h3 class="text-2xl font-bold text-green-900" id="stat-online">0</h3>
                        </div>
                        <i class="fa-solid fa-radar text-green-200 text-2xl hidden sm:block"></i>
                    </div>
                    
                    <!-- Elite / High Net Worth -->
                    <div class="bg-purple-50 border border-purple-100 rounded-lg p-3 flex items-center justify-between">
                        <div>
                            <p class="text-xs text-purple-600 font-bold uppercase tracking-wider">💎 Elite Visitors</p>
                            <h3 class="text-2xl font-bold text-purple-900" id="stat-elite">0</h3>
                        </div>
                        <i class="fa-solid fa-gem text-purple-200 text-2xl hidden sm:block"></i>
                    </div>
                </div>

                <!-- INTELLIGENCE SLOT (Populated by spy-intelligence.js) -->
                <div id="spy-insights-slot" class="bg-white empty:hidden transition-all duration-300"></div>

                <!-- CONTROL BAR: Search & Filters -->
                <div class="bg-white border-b border-gray-200 p-3 flex flex-wrap gap-3 items-center shrink-0 z-20 shadow-sm">
                    <!-- Search -->
                    <div class="relative flex-grow min-w-[200px]">
                        <input type="text" id="spy-search" placeholder="Search ID, Location, GPU, Phone..." 
                            class="w-full pl-9 pr-3 py-2 bg-gray-100 border-transparent focus:bg-white focus:border-indigo-500 focus:ring-1 focus:ring-indigo-500 rounded-lg text-sm transition-all">
                        <i class="fa-solid fa-search absolute left-3 top-2.5 text-gray-400 text-xs"></i>
                    </div>

                    <!-- Filters -->
                    <select id="filter-status" class="text-sm bg-gray-50 border-gray-200 rounded-lg focus:ring-indigo-500 py-2 pl-2 pr-8 text-gray-600 font-medium cursor-pointer hover:bg-gray-100">
                        <option value="all">Status: All</option>
                        <option value="online">🟢 Online</option>
                        <option value="offline">⚪ Offline</option>
                    </select>

                    <select id="filter-wealth" class="text-sm bg-purple-50 border-purple-200 rounded-lg focus:ring-purple-500 py-2 pl-2 pr-8 text-purple-800 font-bold cursor-pointer hover:bg-purple-100 transition-colors">
                        <option value="all">Class: All</option>
                        <option value="Elite">💎 Rich (Elite)</option>
                        <option value="Aspiring">🚀 Mid (Aspiring)</option>
                        <option value="Standard">👤 Lower (Standard)</option>
                    </select>

                    <select id="filter-intent" class="text-sm bg-gray-50 border-gray-200 rounded-lg focus:ring-indigo-500 py-2 pl-2 pr-8 text-gray-600 font-medium cursor-pointer hover:bg-gray-100 hidden sm:block">
                        <option value="all">Activity: All</option>
                        <option value="checkout">🔥 Checkout</option>
                        <option value="cart_activity">🛒 Cart</option>
                    </select>
                </div>

                <!-- MAIN SPLIT VIEW -->
                <div class="flex flex-grow overflow-hidden relative">
                    
                    <!-- LEFT: Visitor List Panel -->
                    <div id="spy-list-panel" class="w-full lg:w-4/12 border-r border-gray-200 bg-white flex flex-col absolute lg:relative h-full z-10 transition-transform duration-300 transform translate-x-0">
                        <!-- List Container -->
                        <div id="spy-list-container" class="flex-grow overflow-y-auto p-2 space-y-2 bg-gray-50/30 custom-scrollbar">
                            <!-- Loading State -->
                            <div class="flex flex-col items-center justify-center h-48 text-gray-400 animate-pulse">
                                <i class="fa-solid fa-satellite-dish text-3xl mb-3 text-indigo-200"></i>
                                <span class="text-xs font-medium">Scanning Traffic...</span>
                            </div>
                        </div>
                        <!-- Pagination -->
                        <div id="spy-pagination" class="p-2 border-t border-gray-200 bg-white flex justify-between items-center text-xs text-gray-600 shrink-0"></div>
                    </div>

                    <!-- RIGHT: Detail View Panel -->
                    <div id="spy-detail-panel" class="w-full lg:w-8/12 bg-gray-50 flex flex-col h-full absolute lg:relative z-20 transform translate-x-full lg:translate-x-0 transition-transform duration-300 overflow-hidden">
                        
                        <!-- Mobile Header -->
                        <div class="lg:hidden bg-white border-b border-gray-200 p-3 flex items-center gap-3 shrink-0 shadow-sm z-30">
                            <button id="spy-back-btn" class="bg-gray-100 hover:bg-gray-200 text-gray-700 p-2 rounded-full transition">
                                <i class="fa-solid fa-arrow-left"></i>
                            </button>
                            <span class="font-bold text-gray-800">Deep Analysis</span>
                        </div>

                        <!-- Detail Content -->
                        <div id="spy-detail-container" class="flex-grow overflow-y-auto p-6 custom-scrollbar">
                            <!-- Empty State -->
                            <div class="h-full flex flex-col items-center justify-center text-gray-300">
                                <div class="h-24 w-24 bg-gray-100 rounded-full flex items-center justify-center mb-4">
                                    <i class="fa-solid fa-fingerprint text-4xl text-gray-300"></i>
                                </div>
                                <p class="text-lg font-medium text-gray-400">Select a visitor to view wealth profile</p>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        `;
    }

    // ============================================================
    // 2. DATA PROCESSING LOGIC
    // ============================================================
    
    update(data) {
        this.state.data = data || {};
        this.processData();
        this.updateStatsUI();
        this.renderList();
        
        // Auto-refresh detail view if open
        if (this.state.selectedVisitorId && this.state.data[this.state.selectedVisitorId]) {
            this.renderDetail(this.state.selectedVisitorId);
        }
    }

    /**
     * Programmatic wealth filter (Detective Brain deep links, sidebar data-filter-wealth).
     * @param {'all'|'Elite'|'Aspiring'|'Standard'} wealth
     */
    setWealthFilter(wealth) {
        const allowed = ['all', 'Elite', 'Aspiring', 'Standard'];
        const w = allowed.includes(wealth) ? wealth : 'all';
        this.state.filters.wealth = w;
        const sel = document.getElementById('filter-wealth');
        if (sel) sel.value = w;
        this.state.currentPage = 1;
        this.processData();
        this.updateStatsUI();
        this.renderList();
    }

    processData() {
        const { search, status, intent, wealth } = this.state.filters;
        const now = Date.now();
        const onlineThreshold = 5 * 60 * 1000; // 5 mins

        // 1. Convert Object to Array & Enrich
        let list = Object.entries(this.state.data).map(([id, visitor]) => {
            const isOnline = (now - visitor.lastActive) < onlineThreshold;
            const logs = Object.values(visitor.logs || {});
            const meta = visitor.meta || {};
            
            // Intent Level Calculation
            let intentLevel = 'browsing';
            let hasCart = false;
            let hasCheckout = false;

            logs.forEach(log => {
                const act = (log.action || '').toLowerCase();
                const pg = (log.page || '').toLowerCase();
                if (act.includes('add') || act.includes('cart')) hasCart = true;
                if (pg.includes('checkout') || act.includes('checkout') || act.includes('purchase')) hasCheckout = true;
            });

            if (hasCheckout) intentLevel = 'checkout';
            else if (hasCart) intentLevel = 'cart_activity';

            // Wealth Data Extraction (Handle inconsistencies)
            let wealthClass = visitor.wealthClass || meta.wealthClass || 'Standard';
            if (String(wealthClass).includes('Middle Class')) wealthClass = 'Aspiring';
            const wealthScore = visitor.wealthScore || meta.wealthScore || 0;

            return {
                id, 
                ...visitor, 
                isOnline, 
                intentLevel,
                wealthClass, // 'Elite', 'Aspiring', 'Standard'
                wealthScore, // 0-100
                lastActiveTime: visitor.lastActive || 0
            };
        });

        // 2. Apply Filters
        this.state.processedList = list.filter(v => {
            // Search (Includes GPU and Device Model)
            const meta = v.meta || {};
            const searchStr = `${v.id} ${v.source} ${meta.location} ${meta.city} ${meta.gpu} ${meta.deviceModel}`.toLowerCase();
            if (search && !searchStr.includes(search.toLowerCase())) return false;

            if (status === 'online' && !v.isOnline) return false;
            if (status === 'offline' && v.isOnline) return false;
            if (intent !== 'all' && v.intentLevel !== intent) return false;
            
            // Wealth Filter Logic (Smart Matching)
            if (wealth !== 'all') {
                // Check if 'Elite' is inside 'Elite 💎'
                if (!v.wealthClass.includes(wealth)) return false;
            }

            return true;
        });

        // 3. Sort (Elite > Online > High Intent > Recent)
        this.state.processedList.sort((a, b) => {
            // Priority 1: Elite Class (Rich first)
            const isEliteA = a.wealthClass.includes('Elite');
            const isEliteB = b.wealthClass.includes('Elite');
            if (isEliteA !== isEliteB) return isEliteB - isEliteA;

            // Priority 2: Online Status
            if (a.isOnline !== b.isOnline) return b.isOnline - a.isOnline;
            
            // Priority 3: Intent
            const priority = { checkout: 3, cart_activity: 2, browsing: 1 };
            if (priority[a.intentLevel] !== priority[b.intentLevel]) {
                return priority[b.intentLevel] - priority[a.intentLevel];
            }
            return b.lastActiveTime - a.lastActiveTime;
        });

        // 4. Update Stats
        this.state.stats = {
            total: list.length,
            online: list.filter(v => v.isOnline).length,
            eliteCount: list.filter(v => (v.wealthClass || '').includes('Elite')).length
        };
    }

    updateStatsUI() {
        const set = (id, val) => { const el = document.getElementById(id); if(el) el.textContent = val; };
        set('stat-total', this.state.stats.total);
        set('stat-online', this.state.stats.online);
        set('stat-elite', this.state.stats.eliteCount);
    }

    // ============================================================
    // 3. LIST RENDERING (VISUAL DISTINCTION)
    // ============================================================
    renderList() {
        const container = document.getElementById('spy-list-container');
        if (!container) return;

        // Custom Empty States based on Filter
        if (this.state.processedList.length === 0) {
            let msg = "No visitors found.";
            let icon = "fa-satellite-dish";
            
            if (this.state.filters.wealth === 'Elite') {
                msg = "No 💎 Rich Customers detected online yet.";
                icon = "fa-gem";
            } else if (this.state.filters.status === 'online') {
                msg = "No visitors online right now.";
                icon = "fa-user-slash";
            }

            container.innerHTML = `
                <div class="flex flex-col items-center justify-center h-48 text-gray-400">
                    <div class="h-12 w-12 bg-gray-100 rounded-full flex items-center justify-center mb-3">
                        <i class="fa-solid ${icon} text-xl"></i>
                    </div>
                    <span class="text-sm font-medium">${msg}</span>
                </div>`;
            return;
        }

        const totalPages = Math.ceil(this.state.processedList.length / this.state.itemsPerPage);
        this.state.currentPage = Math.min(this.state.currentPage, totalPages) || 1;
        const start = (this.state.currentPage - 1) * this.state.itemsPerPage;
        const items = this.state.processedList.slice(start, start + this.state.itemsPerPage);

        container.innerHTML = items.map(v => {
            const isSelected = this.state.selectedVisitorId === v.id;
            const meta = v.meta || {};
            const isElite = (v.wealthClass || '').includes('Elite');
            
            // --- CARD STYLING LOGIC ---
            let borderClass = isOnline => isOnline ? 'border-l-4 border-l-green-500' : 'border-l-4 border-gray-300';
            let bgClass = 'bg-white hover:bg-gray-50';
            
            if (isSelected) bgClass = 'bg-indigo-50 ring-1 ring-indigo-500';

            // Elite Styling Overrides
            if (isElite) {
                bgClass = isSelected ? 'bg-purple-100 ring-1 ring-purple-500' : 'bg-purple-50 hover:bg-purple-100';
                if (v.isOnline) borderClass = 'border-l-4 border-l-purple-600';
            }

            // Icons & Badges
            const deviceIcon = this.getDeviceIcon(meta.os, meta.deviceType);
            const wealthBadge = isElite 
                ? `<span class="text-[10px] font-bold bg-white text-purple-700 px-1.5 py-0.5 rounded border border-purple-200 shadow-sm"><i class="fa-solid fa-gem"></i> Elite</span>` 
                : `<span class="text-[10px] font-bold text-gray-400 bg-gray-100 px-1.5 py-0.5 rounded">${v.wealthScore || 0}</span>`;

            // Clean Device Name
            const deviceName = meta.deviceModel || meta.deviceType || 'Unknown Device';

            return `
                <div class="spy-item cursor-pointer p-3 rounded-lg shadow-sm border border-gray-100 ${borderClass(v.isOnline)} ${bgClass} transition-all duration-200" data-id="${v.id}">
                    <div class="flex justify-between items-start mb-1.5">
                        <div class="flex items-center gap-2">
                            ${v.isOnline ? '<span class="relative flex h-2.5 w-2.5"><span class="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"></span><span class="relative inline-flex rounded-full h-2.5 w-2.5 bg-green-500"></span></span>' : '<span class="h-2.5 w-2.5 rounded-full bg-gray-300"></span>'}
                            <span class="font-mono text-xs font-bold text-gray-700 truncate w-20" title="${v.id}">${v.id}</span>
                            ${wealthBadge}
                        </div>
                        <span class="text-[10px] text-gray-400 font-mono">${this.formatTimeAgo(v.lastActive)}</span>
                    </div>
                    
                    <div class="flex items-center justify-between mt-2">
                        <div class="flex items-center gap-2 text-xs text-gray-700 font-medium">
                            ${deviceIcon}
                            <span class="truncate max-w-[120px]" title="${deviceName}">${deviceName}</span>
                        </div>
                    </div>

                    <div class="mt-2 pt-2 border-t border-gray-200/50 flex justify-between items-center text-[10px] text-gray-500">
                        <div class="flex items-center gap-1.5">
                            <i class="fa-solid fa-map-marker-alt text-gray-400"></i>
                            <span class="truncate max-w-[80px]" title="${meta.city || 'Unknown'}">${meta.city || 'BD'}</span>
                        </div>
                        <div class="flex items-center gap-1.5 text-gray-400">
                             ${meta.networkType === '4g' ? '<i class="fa-solid fa-signal text-green-500"></i> 4G' : '<i class="fa-solid fa-wifi"></i>'}
                        </div>
                    </div>
                </div>
            `;
        }).join('');

        // Pagination UI
        const pagEl = document.getElementById('spy-pagination');
        if(pagEl) {
            pagEl.innerHTML = `
                <button class="spy-page-btn w-8 h-8 flex items-center justify-center rounded bg-gray-100 hover:bg-gray-200 disabled:opacity-50 text-gray-600" data-dir="-1" ${this.state.currentPage === 1 ? 'disabled' : ''}><i class="fa-solid fa-chevron-left"></i></button>
                <span class="font-medium">Page ${this.state.currentPage} / ${totalPages}</span>
                <button class="spy-page-btn w-8 h-8 flex items-center justify-center rounded bg-gray-100 hover:bg-gray-200 disabled:opacity-50 text-gray-600" data-dir="+1" ${this.state.currentPage === totalPages ? 'disabled' : ''}><i class="fa-solid fa-chevron-right"></i></button>
            `;
        }
    }

    // ============================================================
    // 4. DETAIL VIEW (WEALTH & TECH PROFILE)
    // ============================================================
    renderDetail(id) {
        const container = document.getElementById('spy-detail-container');
        if (!container) return;
        
        const visitor = this.state.data[id];
        if (!visitor) {
            container.innerHTML = `<div class="flex flex-col items-center justify-center h-full text-red-400"><i class="fa-regular fa-circle-xmark text-4xl mb-2"></i><p>Visitor data not found.</p></div>`;
            return;
        }

        const logs = visitor.logs ? Object.values(visitor.logs).sort((a, b) => b.timestamp - a.timestamp) : [];
        const meta = visitor.meta || {};
        const isOnline = (Date.now() - visitor.lastActive) < 5 * 60 * 1000;
        
        // Wealth Data Extraction
        const wealthScore = visitor.wealthScore || meta.wealthScore || 0;
        let wealthClass = visitor.wealthClass || meta.wealthClass || 'Standard';
        if (String(wealthClass).includes('Middle Class')) wealthClass = 'Aspiring';
        const isElite = wealthClass.includes('Elite');
        
        // GPU Cleanup for Display
        const rawGPU = meta.gpu || 'Generic GPU';
        const cleanGPU = rawGPU.replace('ANGLE (', '').replace('Direct3D11', '').replace('vs_5_0 ps_5_0)', '').substring(0, 30);

        // Progress Bar Color
        let progressColor = 'bg-gray-400';
        if (wealthScore > 80) progressColor = 'bg-purple-600';
        else if (wealthScore > 50) progressColor = 'bg-blue-500';

        // Container
        container.innerHTML = `
            <!-- 1. Header Profile -->
            <div class="bg-white rounded-xl p-5 border border-gray-200 shadow-sm mb-6 relative overflow-hidden group">
                <div class="absolute top-0 right-0 p-4 opacity-5 group-hover:opacity-10 transition"><i class="fa-solid fa-fingerprint text-9xl"></i></div>
                <div class="relative z-10">
                    <div class="flex justify-between items-start">
                        <div>
                            <div class="flex items-center gap-3">
                                <h2 class="text-2xl font-bold text-gray-800 font-mono tracking-tight">${id}</h2>
                                ${isElite ? '<span class="animate-pulse text-xl">💎</span>' : ''}
                            </div>
                            <div class="flex items-center gap-2 mt-2">
                                ${isOnline 
                                    ? '<span class="inline-flex items-center gap-1.5 bg-green-50 text-green-600 px-3 py-1 rounded-full text-xs font-bold border border-green-200"><span class="h-2 w-2 rounded-full bg-green-500 block"></span> Online</span>' 
                                    : '<span class="inline-flex items-center gap-1.5 bg-gray-100 text-gray-500 px-3 py-1 rounded-full text-xs font-bold border border-gray-200">Offline</span>'}
                                <span class="bg-indigo-50 text-indigo-700 px-3 py-1 rounded-full text-xs font-bold border border-indigo-200 uppercase">${meta.city || 'Unknown City'}</span>
                            </div>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 2. WEALTH & TECH ANALYSIS (The New Engine) -->
            <div class="bg-slate-50 border border-slate-200 rounded-xl p-5 shadow-inner mb-6">
                <h3 class="text-xs font-bold text-slate-500 uppercase mb-4 flex items-center gap-2">
                    <i class="fa-solid fa-sack-dollar text-indigo-500"></i> Buying Power Analysis
                </h3>
                
                <!-- Score Bar -->
                <div class="mb-5">
                    <div class="flex justify-between text-sm mb-1">
                        <span class="font-bold text-gray-700">Wealth Score</span>
                        <span class="font-bold ${isElite ? 'text-purple-600' : 'text-gray-600'}">${wealthScore}/100 (${wealthClass})</span>
                    </div>
                    <div class="w-full bg-gray-200 rounded-full h-2.5">
                        <div class="${progressColor} h-2.5 rounded-full transition-all duration-1000" style="width: ${wealthScore}%"></div>
                    </div>
                </div>

                <!-- Hardware Grid -->
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                    <div class="bg-white p-3 rounded-lg border border-gray-200">
                        <span class="text-xs text-gray-400 block uppercase mb-1">Device Power (GPU)</span>
                        <div class="flex items-center gap-2">
                            <i class="fa-solid fa-microchip text-indigo-500"></i>
                            <span class="font-mono text-xs font-bold text-gray-800 truncate" title="${rawGPU}">${cleanGPU}</span>
                        </div>
                    </div>
                    <div class="bg-white p-3 rounded-lg border border-gray-200">
                        <span class="text-xs text-gray-400 block uppercase mb-1">Network Profile</span>
                        <div class="flex items-center gap-3">
                            <span class="font-bold text-xs text-gray-700">
                                ${meta.networkType === '4g' ? '<i class="fa-solid fa-signal text-green-500"></i> Cellular 4G' : '<i class="fa-solid fa-wifi text-blue-500"></i> WiFi'}
                            </span>
                            <span class="text-[10px] px-2 py-0.5 rounded ${meta.isDataSaver ? 'bg-red-50 text-red-600' : 'bg-green-50 text-green-600'} border">
                                ${meta.isDataSaver ? 'Data Saver ON' : 'Data Saver OFF'}
                            </span>
                        </div>
                    </div>
                </div>
            </div>

            <!-- 3. Journey Timeline -->
            <div class="bg-white border border-gray-200 rounded-xl p-5 shadow-sm min-h-[300px]">
                <h3 class="text-sm font-bold text-gray-700 flex items-center gap-2 mb-6">
                    <i class="fa-solid fa-timeline text-indigo-500"></i> Live Activity Log
                    <span class="bg-indigo-50 text-indigo-600 text-xs px-2 py-0.5 rounded-full ml-auto font-mono">${logs.length} Events</span>
                </h3>

                <div class="relative pl-4 space-y-0">
                    <div class="absolute left-[23px] top-3 bottom-6 w-0.5 bg-gray-100"></div>

                    ${logs.length > 0 ? logs.map((log, idx) => {
                        let icon = 'fa-circle';
                        let color = 'bg-gray-100 text-gray-400';
                        const act = (log.action || '').toLowerCase();
                        
                        // Smart Icon Logic (pageview, click, scroll, cart for session replay)
                        if (idx === 0) { icon = 'fa-clock'; color = 'bg-indigo-100 text-indigo-600 ring-4 ring-indigo-50'; }
                        else if (log.type === 'pageview' || (act.includes('page') && act.includes('view'))) { icon = 'fa-file-alt'; color = 'bg-blue-100 text-blue-600'; }
                        else if (log.type === 'click' || act === 'click') { icon = 'fa-mouse-pointer'; color = 'bg-gray-100 text-gray-600'; }
                        else if (log.type === 'scroll' || act === 'scroll') { icon = 'fa-arrows-up-down'; color = 'bg-emerald-100 text-emerald-600'; }
                        else if (act.includes('cart')) { icon = 'fa-cart-plus'; color = 'bg-orange-100 text-orange-600'; }
                        else if (act.includes('checkout')) { icon = 'fa-bag-shopping'; color = 'bg-red-100 text-red-600'; }

                        return `
                            <div class="relative flex gap-4 pb-6 group last:pb-0">
                                <div class="relative z-10 h-10 w-10 shrink-0 rounded-full flex items-center justify-center ${color} border border-white shadow-sm transition-transform group-hover:scale-110">
                                    <i class="fa-solid ${icon} text-sm"></i>
                                </div>
                                <div class="flex-grow pt-1">
                                    <div class="flex justify-between items-start">
                                        <p class="text-sm font-bold text-gray-800 group-hover:text-indigo-600 transition-colors">${log.action}</p>
                                        <span class="text-[10px] font-mono text-gray-400 bg-gray-50 px-1.5 rounded border border-gray-100">${new Date(log.timestamp).toLocaleTimeString()}</span>
                                    </div>
                                    <p class="text-xs text-gray-500 mt-0.5">${log.details || ''}</p>
                                </div>
                            </div>
                        `;
                    }).join('') : '<div class="text-center text-gray-400 py-10 italic">No activity recorded yet.</div>'}
                </div>
            </div>
        `;
    }

    // ============================================================
    // 5. EVENTS & HELPERS
    // ============================================================
    attachGlobalEvents() {
        // Filter Inputs (Added filter-wealth)
        const inputs = [
            { id: 'spy-search', key: 'search', event: 'input' },
            { id: 'filter-status', key: 'status', event: 'change' },
            { id: 'filter-intent', key: 'intent', event: 'change' },
            { id: 'filter-wealth', key: 'wealth', event: 'change' } // New Wealth Filter
        ];

        inputs.forEach(({ id, key, event }) => {
            const el = document.getElementById(id);
            if(el) {
                el.addEventListener(event, (e) => {
                    this.state.filters[key] = e.target.value;
                    this.state.currentPage = 1;
                    this.processData();
                    this.renderList();
                    // Clear detail if filtered out
                    if (this.state.selectedVisitorId && !this.state.processedList.find(v => v.id === this.state.selectedVisitorId)) {
                        document.getElementById('spy-detail-container').innerHTML = '';
                    }
                });
            }
        });

        // Click Delegation
        const listPanel = document.getElementById('spy-list-panel');
        if (listPanel) {
            listPanel.addEventListener('click', (e) => {
                // Item Click
                const item = e.target.closest('.spy-item');
                if (item) {
                    const id = item.dataset.id;
                    this.state.selectedVisitorId = id;
                    this.renderList(); // Refresh for active state
                    this.renderDetail(id);
                    this.toggleMobileView(true);
                }

                // Pagination
                const btn = e.target.closest('.spy-page-btn');
                if (btn && !btn.disabled) {
                    const dir = parseInt(btn.dataset.dir);
                    this.state.currentPage += dir;
                    this.renderList();
                }
            });
        }

        // Mobile Back
        const detailPanel = document.getElementById('spy-detail-panel');
        if (detailPanel) {
            detailPanel.addEventListener('click', (e) => {
                if (e.target.closest('#spy-back-btn')) {
                    this.toggleMobileView(false);
                }
            });
        }
    }

    // Helper: Mobile Slide View
    toggleMobileView(showDetail) {
        const listPanel = document.getElementById('spy-list-panel');
        const detailPanel = document.getElementById('spy-detail-panel');
        if (!listPanel || !detailPanel) return;

        if (showDetail) {
            listPanel.classList.add('-translate-x-full');
            detailPanel.classList.remove('translate-x-full');
        } else {
            listPanel.classList.remove('-translate-x-full');
            detailPanel.classList.add('translate-x-full');
        }
    }

    // Helper: Time Format
    formatTimeAgo(timestamp) {
        if (!timestamp) return '';
        const seconds = Math.floor((Date.now() - timestamp) / 1000);
        if (seconds < 60) return 'Just now';
        const m = Math.floor(seconds / 60);
        if (m < 60) return `${m}m ago`;
        const h = Math.floor(m / 60);
        if (h < 24) return `${h}h ago`;
        return `${Math.floor(h / 24)}d ago`;
    }

    // Helper: Smart Device Icons
    getDeviceIcon(os, type) {
        const o = (os || '').toLowerCase();
        const t = (type || '').toLowerCase();
        
        if (o.includes('ios') || o.includes('mac')) return '<i class="fa-brands fa-apple"></i>';
        if (o.includes('android')) return '<i class="fa-brands fa-android text-green-600"></i>';
        if (o.includes('win')) return '<i class="fa-brands fa-windows text-blue-500"></i>';
        
        if (t.includes('mobile')) return '<i class="fa-solid fa-mobile-screen"></i>';
        return '<i class="fa-solid fa-desktop"></i>';
    }
}