﻿        const { useState, useEffect, useMemo } = React;

        // --- SOUND ENGINE (Web Audio API) ---
        const SoundEngine = (() => {
            let ctx = null;
            const getCtx = () => {
                if (!ctx) ctx = new (window.AudioContext || window.webkitAudioContext)();
                if (ctx.state === 'suspended') ctx.resume();
                return ctx;
            };

            const playTone = (freq, duration, vol = 0.12, type = 'sine') => {
                try {
                    const c = getCtx();
                    const osc = c.createOscillator();
                    const gain = c.createGain();
                    osc.type = type;
                    osc.frequency.setValueAtTime(freq, c.currentTime);
                    gain.gain.setValueAtTime(vol, c.currentTime);
                    gain.gain.exponentialRampToValueAtTime(0.001, c.currentTime + duration);
                    osc.connect(gain);
                    gain.connect(c.destination);
                    osc.start(c.currentTime);
                    osc.stop(c.currentTime + duration);
                } catch (e) {}
            };

            return {
                hover: () => playTone(880, 0.08, 0.06, 'sine'),
                click: () => {
                    playTone(660, 0.06, 0.1, 'sine');
                    setTimeout(() => playTone(990, 0.08, 0.08, 'sine'), 50);
                },
                spin: () => {
                    for (let i = 0; i < 6; i++) {
                        setTimeout(() => playTone(300 + i * 120, 0.12, 0.04 + i * 0.01, 'triangle'), i * 80);
                    }
                },
                copy: () => {
                    playTone(523, 0.1, 0.08, 'sine');
                    setTimeout(() => playTone(659, 0.1, 0.08, 'sine'), 80);
                    setTimeout(() => playTone(784, 0.15, 0.1, 'sine'), 160);
                },
                washStart: () => {
                    // Washing machine start: low rumble + beep
                    playTone(120, 0.3, 0.08, 'sawtooth');
                    setTimeout(() => playTone(220, 0.2, 0.06, 'triangle'), 100);
                    setTimeout(() => playTone(880, 0.15, 0.1, 'sine'), 350);
                    setTimeout(() => playTone(880, 0.15, 0.1, 'sine'), 550);
                },
                knobTurn: () => playTone(440, 0.05, 0.08, 'triangle'),
            };
        })();

        // --- ICONE SVG ---
        const IconCar = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M19 17h2c.6 0 1-.4 1-1v-3c0-.9-.7-1.7-1.5-1.9C18.7 10.6 16 10 16 10s-1.3-1.4-2.2-2.3c-.5-.4-1.1-.7-1.8-.7H5c-.6 0-1.1.4-1.4.9l-1.4 2.9A3.7 3.7 0 0 0 2 12v4c0 .6.4 1 1 1h2"/><circle cx="7" cy="17" r="2"/><path d="M9 17h6"/><circle cx="17" cy="17" r="2"/></svg>
        );
        const IconRefreshCw = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"/><path d="M3 3v5h5"/></svg>
        );
        const IconCopy = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
        );
        const IconCheck = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><polyline points="20 6 9 17 4 12"/></svg>
        );
        const IconChevronRight = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="m9 18 6-6-6-6"/></svg>
        );
        const IconInfo = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>
        );
        const IconMessageSquare = ({ size = 24, className = "" }) => (
            <svg xmlns="http://www.w3.org/2000/svg" width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className={className}><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
        );

        // --- CONFIGURAZIONE PROMPT CONDIVISA ---
        const PROMPT_CONFIG = window.PROMPT_CONFIG;
        const SIMULATOR_CONFIG = PROMPT_CONFIG.simulator;
        const OPTIMIZER_CONFIG = PROMPT_CONFIG.optimizer;
        const PLUTCHIK_EMOTIONS = SIMULATOR_CONFIG.options.emotions;
        const SALES_PHASES = SIMULATOR_CONFIG.options.phases;
        const CHANNELS = SIMULATOR_CONFIG.options.channels;
        const VEHICLES = SIMULATOR_CONFIG.options.vehicles;
        const MSG_TYPES = OPTIMIZER_CONFIG.options.messageTypes;
        const STYLES = OPTIMIZER_CONFIG.options.styles;
        const SIMULATOR_DEFAULTS = SIMULATOR_CONFIG.options.defaults;
        const SIMULATOR_SHORT_LABELS = SIMULATOR_CONFIG.options.shortLabels;
        const OPTIMIZER_DEFAULTS = OPTIMIZER_CONFIG.options.defaults;

        // --- FUNZIONI DI SUPPORTO MATEMATICO (SVG) ---
        const polarToCartesian = (centerX, centerY, radius, angleInDegrees) => {
            const angleInRadians = (angleInDegrees * Math.PI) / 180.0;
            return { x: centerX + radius * Math.cos(angleInRadians), y: centerY + radius * Math.sin(angleInRadians) };
        };

        const getAnnularSectorPath = (cx, cy, r1, r2, startAngle, endAngle) => {
            const startOuter = polarToCartesian(cx, cy, r2, endAngle);
            const endOuter = polarToCartesian(cx, cy, r2, startAngle);
            const startInner = polarToCartesian(cx, cy, r1, endAngle);
            const endInner = polarToCartesian(cx, cy, r1, startAngle);
            const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1';
            return ['M', startOuter.x, startOuter.y, 'A', r2, r2, 0, largeArcFlag, 0, endOuter.x, endOuter.y, 'L', endInner.x, endInner.y, 'A', r1, r1, 0, largeArcFlag, 1, startInner.x, startInner.y, 'Z'].join(' ');
        };

        const normalizeAngle = (angle) => ((angle % 360) + 360) % 360;
        const getTargetRotation = (index, totalItems) => { const itemAngle = (index + 0.5) * (360 / totalItems); return 270 - itemAngle; };
        const calculateShortestSpin = (currentRot, targetRotMod360, forceSpin = false) => {
            const curMod = normalizeAngle(currentRot);
            let diff = targetRotMod360 - curMod;
            if (!forceSpin) { if (diff > 180) diff -= 360; if (diff < -180) diff += 360; return currentRot + diff; }
            else { if (diff < 0) diff += 360; return currentRot + diff + (360 * 3); }
        };

        // ============================================================
        // COMPONENTE OTTIMIZZATORE (Lavatrice)
        // ============================================================
        function OptimizerTab() {
            const [msgType, setMsgType] = useState(OPTIMIZER_DEFAULTS.messageType);
            const [style, setStyle] = useState(OPTIMIZER_DEFAULTS.style);
            const [message, setMessage] = useState('');
            const [objective, setObjective] = useState('');
            const [mode, setMode] = useState(null); // 'fix' | 'feedback'
            const [isWashing, setIsWashing] = useState(false);
            const [generatedPrompt, setGeneratedPrompt] = useState('');
            const [copied, setCopied] = useState(false);
            const [showPrompt, setShowPrompt] = useState(false);

            const canStart = message.trim().length >= OPTIMIZER_DEFAULTS.minMessageLength;

            const generatePrompt = (actionMode) => {
                const typeLabel = MSG_TYPES.find(t => t.id === msgType)?.label || msgType;
                const styleLabel = STYLES.find(s => s.id === style)?.label || style;
                const obj = objective.trim() || OPTIMIZER_CONFIG.defaultObjective;
                return OPTIMIZER_CONFIG.buildPrompt({
                    mode: actionMode,
                    message: message.trim(),
                    typeLabel,
                    styleLabel,
                    objective: obj,
                });
            };

            const handleStart = (actionMode) => {
                if (!canStart) return;
                SoundEngine.washStart();
                setMode(actionMode);
                setIsWashing(true);
                setShowPrompt(false);

                setTimeout(() => {
                    const prompt = generatePrompt(actionMode);
                    setGeneratedPrompt(prompt);
                    setIsWashing(false);
                    setShowPrompt(true);
                }, 2000);
            };

            const copyToClipboard = async () => {
                try {
                    if (navigator.clipboard && navigator.clipboard.writeText) {
                        await navigator.clipboard.writeText(generatedPrompt);
                    } else {
                        const textArea = document.createElement("textarea");
                        textArea.value = generatedPrompt;
                        textArea.style.position = "fixed";
                        textArea.style.opacity = "0";
                        document.body.appendChild(textArea);
                        textArea.select();
                        document.execCommand('copy');
                        document.body.removeChild(textArea);
                    }
                    SoundEngine.copy();
                    setCopied(true);
                    setTimeout(() => setCopied(false), 2000);
                } catch (err) {
                    console.error("Errore durante la copia:", err);
                }
            };

            // --- Knob Selector component ---
            const KnobSelector = ({ items, value, onChange, label, renderItem }) => (
                <div className="mb-6">
                    <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-3">{label}</label>
                    <div className="flex flex-wrap gap-2">
                        {items.map(item => {
                            const isActive = (item.id || item) === value;
                            return (
                                <button
                                    key={item.id || item}
                                    onClick={() => { SoundEngine.knobTurn(); onChange(item.id || item); }}
                                    className={`relative px-4 py-2.5 rounded-full border-2 font-medium text-sm transition-all duration-200 ${
                                        isActive
                                            ? 'bg-cyan-500/20 border-cyan-500 text-cyan-300 shadow-lg shadow-cyan-900/30 scale-105'
                                            : 'bg-slate-800/60 border-slate-700 text-slate-400 hover:border-slate-500 hover:text-slate-300'
                                    }`}
                                >
                                    {renderItem ? renderItem(item) : (item.icon ? `${item.icon} ${item.label}` : item.label)}
                                    {isActive && (
                                        <span className="absolute -top-1 -right-1 w-3 h-3 bg-cyan-400 rounded-full border-2 border-slate-950"></span>
                                    )}
                                </button>
                            );
                        })}
                    </div>
                </div>
            );

            return (
                <div className="flex flex-col lg:flex-row gap-6 lg:gap-10 flex-grow items-start animate-fade-in">
                    {/* COLONNA SINISTRA - Input & Lavatrice */}
                    <div className="w-full lg:w-1/2 flex flex-col">

                        {/* Textarea messaggio */}
                        <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5 shadow-xl">
                            <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">
                                Incolla qui il tuo messaggio
                            </label>
                            <textarea
                                value={message}
                                onChange={e => setMessage(e.target.value)}
                                rows={6}
                                className="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-base text-slate-200 resize-none custom-scroll"
                                placeholder="Scrivi o incolla qui il messaggio che vuoi ottimizzare..."
                            />
                            {message.trim().length > 0 && message.trim().length < OPTIMIZER_DEFAULTS.minMessageLength && (
                                <p className="text-amber-500/80 text-xs mt-2">Il messaggio deve contenere almeno {OPTIMIZER_DEFAULTS.minMessageLength} caratteri.</p>
                            )}
                        </div>

                        {/* Obiettivo */}
                        <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5 shadow-xl">
                            <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">
                                Cosa vuoi ottenere con questa comunicazione?
                            </label>
                            <textarea
                                value={objective}
                                onChange={e => setObjective(e.target.value)}
                                rows={2}
                                className="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-sm text-slate-200 resize-none"
                                placeholder="Es. Convincere il cliente a fissare un appuntamento per il test drive..."
                            />
                        </div>

                        {/* PANNELLO LAVATRICE */}
                        <div className="bg-gradient-to-b from-slate-800 to-slate-900 border border-slate-700 rounded-3xl p-5 sm:p-7 shadow-2xl relative overflow-hidden">
                            {/* Subtle metallic texture */}
                            <div className="absolute inset-0 opacity-[0.03]" style={{ backgroundImage: 'repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(255,255,255,0.1) 2px, rgba(255,255,255,0.1) 4px)' }}></div>

                            <div className="relative z-10">
                                {/* Knob selectors */}
                                <KnobSelector
                                    items={MSG_TYPES}
                                    value={msgType}
                                    onChange={setMsgType}
                                    label="Tipo di messaggio"
                                    renderItem={item => `${item.icon} ${item.label}`}
                                />

                                <KnobSelector
                                    items={STYLES}
                                    value={style}
                                    onChange={setStyle}
                                    label="Stile di comunicazione"
                                />

                                {/* Separator */}
                                <div className="border-t border-slate-700/60 my-6"></div>

                                {/* OBLO (washing machine door) - action buttons */}
                                <div className="flex flex-col items-center">
                                    <div className={`relative w-56 h-56 sm:w-64 sm:h-64 rounded-full border-[6px] ${isWashing ? 'border-cyan-400 glow-pulse' : 'border-slate-600'} bg-slate-950 flex items-center justify-center transition-all duration-500 shadow-inner`}>

                                        {/* Inner glass effect */}
                                        <div className={`absolute inset-3 rounded-full border-2 ${isWashing ? 'border-cyan-500/40' : 'border-slate-700/40'} transition-colors duration-500`}></div>

                                        {/* Spinning drum when washing */}
                                        {isWashing && (
                                            <div className="absolute inset-6 rounded-full border border-dashed border-cyan-500/30 drum-spin"></div>
                                        )}

                                        {/* Content inside the door */}
                                        <div className="relative z-10 flex flex-col items-center gap-3 px-4">
                                            {isWashing ? (
                                                <div className="text-center">
                                                    <div className="text-3xl mb-2 wash-spinning">🌀</div>
                                                    <span className="text-cyan-400 text-sm font-semibold animate-pulse">
                                                        {mode === 'fix' ? 'Ottimizzazione...' : 'Analisi...'}
                                                    </span>
                                                </div>
                                            ) : showPrompt ? (
                                                <div className="text-center">
                                                    <div className="text-3xl mb-2">{'\u2705'}</div>
                                                    <span className="text-green-400 text-sm font-semibold">Pronto!</span>
                                                    <p className="text-slate-500 text-xs mt-1">Scorri per il prompt</p>
                                                </div>
                                            ) : (
                                                <div className="text-center">
                                                    <div className="text-4xl mb-2 opacity-40">👔</div>
                                                    <span className="text-slate-500 text-xs">Seleziona un programma</span>
                                                </div>
                                            )}
                                        </div>
                                    </div>

                                    {/* Two big round START buttons */}
                                    <div className="flex gap-4 sm:gap-6 mt-6">
                                        <button
                                            onClick={() => handleStart('fix')}
                                            disabled={!canStart || isWashing}
                                            className={`group w-28 h-28 sm:w-32 sm:h-32 rounded-full border-4 flex flex-col items-center justify-center gap-1.5 transition-all duration-300 ${
                                                canStart && !isWashing
                                                    ? 'bg-gradient-to-br from-cyan-600 to-cyan-800 border-cyan-400 text-white shadow-xl shadow-cyan-900/50 hover:scale-105 hover:shadow-cyan-800/60 active:scale-95 cursor-pointer'
                                                    : 'bg-slate-800/50 border-slate-700 text-slate-600 cursor-not-allowed'
                                            }`}
                                        >
                                            <span className="text-2xl">🔧</span>
                                            <span className="text-[11px] sm:text-xs font-bold uppercase tracking-wide leading-tight text-center px-2">Aiutami a sistemarla</span>
                                        </button>

                                        <button
                                            onClick={() => handleStart('feedback')}
                                            disabled={!canStart || isWashing}
                                            className={`group w-28 h-28 sm:w-32 sm:h-32 rounded-full border-4 flex flex-col items-center justify-center gap-1.5 transition-all duration-300 ${
                                                canStart && !isWashing
                                                    ? 'bg-gradient-to-br from-amber-600 to-orange-800 border-amber-400 text-white shadow-xl shadow-amber-900/50 hover:scale-105 hover:shadow-amber-800/60 active:scale-95 cursor-pointer'
                                                    : 'bg-slate-800/50 border-slate-700 text-slate-600 cursor-not-allowed'
                                            }`}
                                        >
                                            <span className="text-2xl">💬</span>
                                            <span className="text-[11px] sm:text-xs font-bold uppercase tracking-wide leading-tight text-center px-2">Dammi feedback</span>
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    {/* COLONNA DESTRA - Output prompt */}
                    <div className="w-full lg:w-1/2 flex flex-col">
                        {showPrompt && generatedPrompt ? (
                            <div className="animate-fade-in">
                                <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5">
                                    <h3 className="text-base sm:text-lg font-bold text-white mb-3">Riepilogo configurazione:</h3>
                                    <ul className="space-y-2">
                                        <li className="flex items-center gap-3">
                                            <span className="text-lg">{MSG_TYPES.find(t => t.id === msgType)?.icon}</span>
                                            <span className="text-slate-300 text-sm font-medium w-16">Canale:</span>
                                            <span className="text-white font-bold text-sm">{MSG_TYPES.find(t => t.id === msgType)?.label}</span>
                                        </li>
                                        <li className="flex items-center gap-3">
                                            <span className="text-lg">🎨</span>
                                            <span className="text-slate-300 text-sm font-medium w-16">Stile:</span>
                                            <span className="text-white font-bold text-sm">{STYLES.find(s => s.id === style)?.label}</span>
                                        </li>
                                        <li className="flex items-center gap-3">
                                            <span className="text-lg">{mode === 'fix' ? '🔧' : '💬'}</span>
                                            <span className="text-slate-300 text-sm font-medium w-16">Azione:</span>
                                            <span className="text-white font-bold text-sm">{mode === 'fix' ? 'Riscrittura' : 'Feedback'}</span>
                                        </li>
                                    </ul>
                                </div>

                                <div className="relative flex-grow flex flex-col bg-slate-950 border-2 border-slate-800 rounded-2xl overflow-hidden shadow-2xl min-h-[300px] sm:min-h-[400px]">
                                    <div className="bg-slate-900 border-b border-slate-800 px-4 sm:px-6 py-3 sm:py-4 flex justify-between items-center sticky top-0 gap-3">
                                        <span className="font-semibold text-slate-300 text-sm sm:text-base">Prompt Generato</span>
                                        <button
                                            onClick={copyToClipboard}
                                            className={`flex items-center gap-2 px-3 sm:px-4 py-2 rounded-lg font-medium transition-all text-sm shrink-0 ${
                                                copied
                                                    ? 'bg-green-500/20 text-green-400 border border-green-500/50'
                                                    : 'bg-cyan-600 text-white hover:bg-cyan-500 border border-transparent'
                                            }`}
                                        >
                                            {copied ? <IconCheck size={16} /> : <IconCopy size={16} />}
                                            {copied ? 'Copiato!' : 'Copia Prompt'}
                                        </button>
                                    </div>
                                    <div className="p-4 sm:p-6 overflow-auto max-h-[400px] sm:max-h-[500px] custom-scroll">
                                        <pre className="whitespace-pre-wrap font-mono text-xs sm:text-sm leading-relaxed text-slate-300">
                                            {generatedPrompt}
                                        </pre>
                                    </div>
                                </div>

                                <div className="mt-5 flex items-start gap-3 bg-slate-900/50 p-3 sm:p-4 rounded-xl border border-slate-800 text-sm text-slate-400">
                                    <IconInfo className="flex-shrink-0 text-cyan-500 mt-0.5" size={18} />
                                    <p>Copia il prompt e incollalo in ChatGPT, Claude, Copilot o Gemini. L'IA analizzerà il tuo messaggio e ti fornirà il risultato.</p>
                                </div>
                            </div>
                        ) : (
                            <div className="flex flex-col items-center justify-center py-16 sm:py-24 text-center">
                                <div className="text-6xl mb-4 opacity-20">🧹</div>
                                <h3 className="text-lg font-semibold text-slate-500 mb-2">Il cesto è vuoto</h3>
                                <p className="text-slate-600 text-sm max-w-xs">
                                    Incolla il tuo messaggio, configura le impostazioni e premi uno dei due pulsanti per avviare il lavaggio.
                                </p>
                            </div>
                        )}
                    </div>
                </div>
            );
        }

        // ============================================================
        // COMPONENTE LOGIN GATE
        // ============================================================
        function LoginGate() {
            const [authUser, setAuthUser] = useState(null);
            const [authError, setAuthError] = useState(null);
            const [pendingDisclaimers, setPendingDisclaimers] = useState([]);
            const [disclaimerChecks, setDisclaimerChecks] = useState({});
            const [sessionCode, setSessionCode] = useState('');
            const [sessionCodeLocked, setSessionCodeLocked] = useState(false);
            const [email, setEmail] = useState('');
            const [name, setName] = useState('');
            const [isLoading, setIsLoading] = useState(false);
            const [authStep, setAuthStep] = useState('login'); // 'login' | 'disclaimers' | 'authenticated'
            const [accessDate, setAccessDate] = useState(null);
            const [sessionChecked, setSessionChecked] = useState(false);
            const [loginFields, setLoginFields] = useState('both'); // 'both' | 'email' | 'name'

            // On mount: read ?s= URL param and check existing session + fetch settings in parallel
            useEffect(() => {
                const urlCode = new URLSearchParams(location.search).get('s');
                if (urlCode) {
                    setSessionCode(urlCode.trim().toUpperCase());
                    setSessionCodeLocked(true);
                }

                (async () => {
                    const [settingsResult, authResult] = await Promise.allSettled([
                        fetch('/api/autoprompter/settings', { credentials: 'include' }),
                        fetch('/api/autoprompter/auth/check', { credentials: 'include' }),
                    ]);
                    if (settingsResult.status === 'fulfilled' && settingsResult.value.ok) {
                        try {
                            const d = await settingsResult.value.json();
                            if (d.loginFields) setLoginFields(d.loginFields);
                        } catch (_) {}
                    }
                    if (authResult.status === 'fulfilled' && authResult.value.ok) {
                        try {
                            const data = await authResult.value.json();
                            if (data.authenticated && data.user) {
                                setAuthUser({ user: data.user });
                                setAuthStep('authenticated');
                            }
                        } catch (_) {}
                    }
                    setSessionChecked(true);
                })();
            }, []);

            const handleLogin = async (e) => {
                e.preventDefault();
                if (!sessionCode.trim()) return;
                const identityMissing =
                    (loginFields === 'email' && !email.trim()) ||
                    (loginFields === 'name' && !name.trim()) ||
                    (loginFields === 'both' && !email.trim() && !name.trim());
                if (identityMissing) return;
                setIsLoading(true);
                setAuthError(null);
                try {
                    const res = await fetch('/api/autoprompter/auth', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                        body: JSON.stringify({
                            session_code: sessionCode.trim(),
                            email: email.trim() || null,
                            name: name.trim() || null
                        })
                    });
                    const data = await res.json();
                    if (res.status === 429) {
                        setAuthError({ type: 'rate_limit', message: 'Troppi tentativi. Riprova tra un minuto.' });
                    } else if (res.status === 403 && data.error === 'invalid_session') {
                        setAuthError({ type: 'invalid_session', message: data.message || 'Codice sessione non valido.' });
                    } else if (res.status === 403 && (data.error === 'access_denied' || data.error === 'not_found')) {
                        setAuthError({ type: 'access_denied', message: data.message || 'Non è stato possibile verificare l\'accesso. Controlla l\'indirizzo email o contatta l\'amministratore.' });
                    } else if (res.status === 403 && data.error === 'not_yet') {
                        setAuthError({ type: 'not_yet', message: `Il tuo accesso sarà attivo dal ${data.date || 'data non disponibile'}.` });
                        setAccessDate(data.date || null);
                    } else if (res.status === 403 && data.error === 'expired') {
                        setAuthError({ type: 'expired', message: 'Il tuo periodo di accesso è terminato.' });
                    } else if (res.ok) {
                        if (data.disclaimers && data.disclaimers.length > 0) {
                            setPendingDisclaimers(data.disclaimers);
                            const checks = {};
                            data.disclaimers.forEach((d, i) => { checks[i] = false; });
                            setDisclaimerChecks(checks);
                            setAuthStep('disclaimers');
                            setAuthUser(data);
                        } else {
                            setAuthUser(data);
                            setAuthStep('authenticated');
                        }
                    } else {
                        setAuthError({ type: 'unknown', message: 'Errore durante l\'autenticazione. Riprova.' });
                    }
                } catch (err) {
                    setAuthError({ type: 'network', message: 'Impossibile contattare il server. Verifica la connessione e riprova.' });
                }
                setIsLoading(false);
            };

            const allDisclaimersChecked = pendingDisclaimers.length > 0 && pendingDisclaimers.every((d, i) => !d.enabled || disclaimerChecks[i]);

            const handleAcceptDisclaimers = async () => {
                setIsLoading(true);
                try {
                    const body = { disclaimer1_accepted: false, disclaimer2_accepted: false };
                    pendingDisclaimers.forEach((d, i) => {
                        if (d.slot === 'disclaimer1') body.disclaimer1_accepted = !!disclaimerChecks[i];
                        if (d.slot === 'disclaimer2') body.disclaimer2_accepted = !!disclaimerChecks[i];
                    });
                    const res = await fetch('/api/autoprompter/auth/accept', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        credentials: 'include',
                        body: JSON.stringify(body)
                    });
                    if (res.ok) {
                        setAuthStep('authenticated');
                    } else {
                        setAuthError({ type: 'accept_error', message: 'Errore nell\'accettazione. Riprova.' });
                    }
                } catch (err) {
                    setAuthError({ type: 'network', message: 'Impossibile contattare il server. Verifica la connessione e riprova.' });
                }
                setIsLoading(false);
            };

            const handleLogout = async () => {
                try {
                    await fetch('/api/autoprompter/auth/logout', {
                        method: 'POST',
                        credentials: 'include'
                    });
                } catch (err) {
                    // Logout request failed, reset local state anyway
                }
                setAuthUser(null);
                setAuthError(null);
                setPendingDisclaimers([]);
                setDisclaimerChecks({});
                if (!sessionCodeLocked) setSessionCode('');
                setEmail('');
                setName('');
                setAuthStep('login');
                setAccessDate(null);
            };

            const Branding = () => (
                <div className="flex items-center gap-2.5 mb-8">
                    <div className="w-12 h-12 rounded-xl bg-gradient-to-br from-cyan-500 to-cyan-700 flex items-center justify-center shadow-lg shadow-cyan-900/40">
                        <IconCar className="text-white" size={24} />
                    </div>
                    <div className="flex flex-col">
                        <span className="text-sm font-semibold text-cyan-400 tracking-widest uppercase leading-none">AutoPrompt</span>
                        <span className="text-xs text-slate-500 font-medium tracking-wide leading-tight">by <span className="text-cyan-400/70 font-semibold">Logotel</span></span>
                    </div>
                </div>
            );

            // --- SESSION CHECK LOADING ---
            if (!sessionChecked) {
                return (
                    <div className="min-h-screen flex items-center justify-center p-4 font-sans">
                        <div className="w-full max-w-md text-center">
                            <div className="bg-slate-900 border border-slate-800 rounded-2xl p-8 shadow-2xl flex flex-col items-center">
                                <Branding />
                                <div className="animate-subtle-pulse text-slate-400 text-sm">Verifica sessione in corso...</div>
                            </div>
                        </div>
                    </div>
                );
            }

            // --- LOGIN SCREEN ---
            if (authStep === 'login') {
                return (
                    <div className="min-h-screen flex items-center justify-center p-4 font-sans">
                        <div className="w-full max-w-md">
                            <div className="bg-slate-900 border border-slate-800 rounded-2xl p-8 shadow-2xl">
                                <div className="flex flex-col items-center">
                                    <Branding />
                                    <h2 className="text-xl font-bold text-white mb-2 text-center">Accedi alla piattaforma</h2>
                                    <p className="text-slate-400 text-sm mb-6 text-center">
                                        {loginFields === 'email'
                                            ? 'Inserisci la tua email per accedere.'
                                            : loginFields === 'name'
                                            ? 'Inserisci il tuo nome per accedere.'
                                            : 'Inserisci la tua email e/o il tuo nome per accedere.'}
                                    </p>
                                </div>
                                <form onSubmit={handleLogin}>
                                    {!sessionCodeLocked && (
                                        <div className="mb-4">
                                            <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Codice sessione</label>
                                            <input
                                                type="text"
                                                value={sessionCode}
                                                onChange={e => setSessionCode(e.target.value)}
                                                required
                                                className="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-base text-slate-200"
                                                placeholder="es. TEAM2026"
                                                disabled={isLoading}
                                                autoCapitalize="characters"
                                            />
                                        </div>
                                    )}
                                    {(loginFields === 'email' || loginFields === 'both') && (
                                        <div className="mb-4">
                                            <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Email</label>
                                            <input
                                                type="email"
                                                value={email}
                                                onChange={e => setEmail(e.target.value)}
                                                className="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-base text-slate-200"
                                                placeholder="nome@azienda.com"
                                                disabled={isLoading}
                                                autoComplete="email"
                                            />
                                        </div>
                                    )}
                                    {(loginFields === 'name' || loginFields === 'both') && (
                                        <div className="mb-4">
                                            <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">
                                                {loginFields === 'both' ? "Nome (alternativo all'email)" : 'Nome'}
                                            </label>
                                            <input
                                                type="text"
                                                value={name}
                                                onChange={e => setName(e.target.value)}
                                                className="w-full bg-slate-950 border border-slate-700 rounded-xl px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-base text-slate-200"
                                                placeholder="Mario Rossi"
                                                disabled={isLoading}
                                                autoComplete="name"
                                            />
                                        </div>
                                    )}
                                    {(() => {
                                        const identityMissing =
                                            (loginFields === 'email' && !email.trim()) ||
                                            (loginFields === 'name' && !name.trim()) ||
                                            (loginFields === 'both' && !email.trim() && !name.trim());
                                        const btnDisabled = isLoading || !sessionCode.trim() || identityMissing;
                                        return (
                                            <button
                                                type="submit"
                                                disabled={btnDisabled}
                                                className={`w-full py-3 rounded-xl font-semibold text-sm transition-all ${
                                                    btnDisabled
                                                        ? 'bg-slate-800 text-slate-600 cursor-not-allowed'
                                                        : 'bg-cyan-600 hover:bg-cyan-500 text-white shadow-lg shadow-cyan-900/40 active:scale-[0.98]'
                                                }`}
                                            >
                                                {isLoading ? 'Verifica in corso...' : 'Accedi'}
                                            </button>
                                        );
                                    })()}
                                </form>

                                {/* Error states */}
                                {authError && (authError.type === 'access_denied' || authError.type === 'rate_limit') && (
                                    <div className="mt-5 p-4 bg-red-950/40 border border-red-800/60 rounded-xl animate-fade-in">
                                        <p className="text-red-400 text-sm font-medium">{authError.message}</p>
                                    </div>
                                )}
                                {authError && authError.type === 'invalid_session' && (
                                    <div className="mt-5 p-4 bg-red-950/40 border border-red-800/60 rounded-xl animate-fade-in">
                                        <p className="text-red-400 text-sm font-medium">{authError.message}</p>
                                    </div>
                                )}
                                {authError && authError.type === 'not_yet' && (
                                    <div className="mt-5 animate-fade-in">
                                        <div className="p-4 bg-amber-950/40 border border-amber-700/60 rounded-xl mb-4">
                                            <p className="text-amber-400 text-sm font-medium">{authError.message}</p>
                                        </div>
                                        <div className="bg-slate-800/60 border border-slate-700 rounded-xl p-6 text-center">
                                            <div className="text-4xl mb-3">&#128197;</div>
                                            <h3 className="text-white font-semibold text-lg mb-2">Il tuo accesso non è ancora attivo</h3>
                                            <p className="text-slate-400 text-sm leading-relaxed">Ti informeremo quando il tuo account sarà pronto. Controlla la tua email per aggiornamenti.</p>
                                            {accessDate && <p className="text-amber-400 text-sm font-semibold mt-3">Data di attivazione: {accessDate}</p>}
                                        </div>
                                    </div>
                                )}
                                {authError && authError.type === 'expired' && (
                                    <div className="mt-5 animate-fade-in">
                                        <div className="p-4 bg-red-950/40 border border-red-800/60 rounded-xl mb-4">
                                            <p className="text-red-400 text-sm font-medium">{authError.message}</p>
                                        </div>
                                        <div className="bg-slate-800/60 border border-slate-700 rounded-xl p-6 text-center">
                                            <div className="text-4xl mb-3">&#9203;</div>
                                            <h3 className="text-white font-semibold text-lg mb-2">Periodo di accesso terminato</h3>
                                            <p className="text-slate-400 text-sm leading-relaxed">Il tuo periodo di utilizzo è scaduto. Contatta il tuo referente per informazioni sul rinnovo.</p>
                                        </div>
                                    </div>
                                )}
                                {authError && (authError.type === 'unknown' || authError.type === 'network') && (
                                    <div className="mt-5 p-4 bg-red-950/40 border border-red-800/60 rounded-xl animate-fade-in">
                                        <p className="text-red-400 text-sm font-medium">{authError.message}</p>
                                    </div>
                                )}
                            </div>
                            <p className="text-slate-600 text-xs text-center mt-6">
                                Riservato ai soggetti che hanno sottoscritto un accordo con <span className="text-slate-500">Logotel</span>.
                            </p>
                        </div>
                    </div>
                );
            }

            // --- DISCLAIMERS SCREEN ---
            if (authStep === 'disclaimers') {
                return (
                    <div className="min-h-screen flex items-center justify-center p-4 font-sans">
                        <div className="w-full max-w-lg">
                            <div className="bg-slate-900 border border-slate-800 rounded-2xl p-8 shadow-2xl">
                                <div className="flex flex-col items-center">
                                    <Branding />
                                    <h2 className="text-xl font-bold text-white mb-2 text-center">Condizioni di utilizzo</h2>
                                    <p className="text-slate-400 text-sm mb-6 text-center">Per procedere, leggi e accetta le seguenti condizioni.</p>
                                </div>
                                <div className="space-y-4 max-h-[50vh] overflow-y-auto custom-scroll pr-1">
                                    {pendingDisclaimers.map((d, i) => (
                                        <div key={i} className="bg-slate-800/60 border border-slate-700 rounded-xl p-5">
                                            <div className="text-slate-200 text-sm leading-relaxed mb-4 whitespace-pre-wrap">{d.content}</div>
                                            {d.enabled !== false && (
                                                <label className="flex items-center gap-3 cursor-pointer group">
                                                    <input
                                                        type="checkbox"
                                                        checked={!!disclaimerChecks[i]}
                                                        onChange={e => setDisclaimerChecks(prev => ({ ...prev, [i]: e.target.checked }))}
                                                        className="w-5 h-5 rounded border-2 border-slate-600 bg-slate-950 text-cyan-500 focus:ring-cyan-500 focus:ring-offset-0 cursor-pointer accent-cyan-500"
                                                    />
                                                    <span className="text-slate-300 text-sm font-medium group-hover:text-white transition-colors">Ho letto e accetto</span>
                                                </label>
                                            )}
                                        </div>
                                    ))}
                                </div>
                                {authError && authError.type === 'accept_error' && (
                                    <div className="mt-4 p-3 bg-red-950/40 border border-red-800/60 rounded-xl">
                                        <p className="text-red-400 text-sm font-medium">{authError.message}</p>
                                    </div>
                                )}
                                <button
                                    onClick={handleAcceptDisclaimers}
                                    disabled={!allDisclaimersChecked || isLoading}
                                    className={`w-full mt-6 py-3 rounded-xl font-semibold text-sm transition-all ${
                                        !allDisclaimersChecked || isLoading
                                            ? 'bg-slate-800 text-slate-600 cursor-not-allowed'
                                            : 'bg-cyan-600 hover:bg-cyan-500 text-white shadow-lg shadow-cyan-900/40 active:scale-[0.98]'
                                    }`}
                                >
                                    {isLoading ? 'Invio in corso...' : 'Accedi'}
                                </button>
                            </div>
                        </div>
                    </div>
                );
            }

            // --- AUTHENTICATED: show app ---
            return <App authUser={authUser} onLogout={handleLogout} />;
        }

        // ============================================================
        // COMPONENTE PRINCIPALE APP
        // ============================================================
        function App({ authUser, onLogout }) {
            const [activeTab, setActiveTab] = useState('simulator');
            const [simulatorEnabled, setSimulatorEnabled] = useState(true);
            const [optimizerEnabled, setOptimizerEnabled] = useState(false);

            // Load app settings (tab visibility)
            useEffect(() => {
                fetch('/api/autoprompter/settings', { credentials: 'include' })
                    .then(r => r.json())
                    .then(data => {
                        const simOn = data.simulatorEnabled !== false;
                        const optOn = data.optimizerEnabled !== false;
                        setSimulatorEnabled(simOn);
                        setOptimizerEnabled(optOn);
                        // Set active tab to first available
                        if (!simOn && optOn) setActiveTab('optimizer');
                        else if (simOn) setActiveTab('simulator');
                    })
                    .catch(() => {});
            }, []);

            // --- SIMULATORE STATE ---
            const isDesktop = () => window.innerWidth >= 1024;
            const [openSections, setOpenSections] = useState({ 1: isDesktop(), 2: false, 3: false, 4: false });
            const [stepsDone, setStepsDone] = useState({ 1: false, 2: false, 3: false, 4: false });
            const [idxEmotion, setIdxEmotion] = useState(SIMULATOR_DEFAULTS.emotionIndex);
            const [idxPhase, setIdxPhase] = useState(SIMULATOR_DEFAULTS.phaseIndex);
            const [idxChannel, setIdxChannel] = useState(SIMULATOR_DEFAULTS.channelIndex);
            const [idxVehicle, setIdxVehicle] = useState(SIMULATOR_DEFAULTS.vehicleIndex);
            const [rotEmotion, setRotEmotion] = useState(0);
            const [rotPhase, setRotPhase] = useState(0);
            const [rotChannel, setRotChannel] = useState(0);
            const [copied, setCopied] = useState(false);
            const [hoveredItem, setHoveredItem] = useState(null);

            useEffect(() => {
                setRotEmotion(getTargetRotation(SIMULATOR_DEFAULTS.emotionIndex, PLUTCHIK_EMOTIONS.length));
                setRotPhase(getTargetRotation(SIMULATOR_DEFAULTS.phaseIndex, SALES_PHASES.length));
                setRotChannel(getTargetRotation(SIMULATOR_DEFAULTS.channelIndex, CHANNELS.length));
            }, []);

            const toggleSection = (num) => { setOpenSections(prev => ({ ...prev, [num]: !prev[num] })); };
            const markStepDone = (num) => { setStepsDone(prev => ({ ...prev, [num]: true })); };

            const updateRotation = (type, newIndex, forceSpin = false) => {
                if (forceSpin) SoundEngine.spin(); else SoundEngine.click();
                if (type === 'emotion') { setRotEmotion(prev => calculateShortestSpin(prev, getTargetRotation(newIndex, PLUTCHIK_EMOTIONS.length), forceSpin)); setIdxEmotion(newIndex); }
                else if (type === 'phase') { setRotPhase(prev => calculateShortestSpin(prev, getTargetRotation(newIndex, SALES_PHASES.length), forceSpin)); setIdxPhase(newIndex); }
                else if (type === 'channel') { setRotChannel(prev => calculateShortestSpin(prev, getTargetRotation(newIndex, CHANNELS.length), forceSpin)); setIdxChannel(newIndex); }
                markStepDone(1);
            };

            const handleVehicleChange = (idx) => { setIdxVehicle(idx); markStepDone(1); };

            const handleRandomize = () => {
                const rE = Math.floor(Math.random() * PLUTCHIK_EMOTIONS.length);
                const rP = Math.floor(Math.random() * SALES_PHASES.length);
                const rC = Math.floor(Math.random() * CHANNELS.length);
                const rV = Math.floor(Math.random() * VEHICLES.length);
                setIdxVehicle(rV);
                updateRotation('emotion', rE, true); updateRotation('phase', rP, true); updateRotation('channel', rC, true);
                markStepDone(1); setOpenSections(prev => ({ ...prev, 1: true }));
            };

            const copyToClipboard = async () => {
                try {
                    if (navigator.clipboard && navigator.clipboard.writeText) { await navigator.clipboard.writeText(generatedPrompt); }
                    else { const t = document.createElement("textarea"); t.value = generatedPrompt; t.style.position = "fixed"; t.style.opacity = "0"; document.body.appendChild(t); t.select(); document.execCommand('copy'); document.body.removeChild(t); }
                    SoundEngine.copy(); setCopied(true); markStepDone(2);
                    setOpenSections(prev => ({ ...prev, 2: false, 3: true }));
                    setTimeout(() => setCopied(false), 2000);
                } catch (err) { console.error("Errore durante la copia:", err); }
            };

            const generatedPrompt = useMemo(() => {
                const emotion = PLUTCHIK_EMOTIONS[idxEmotion]; const phase = SALES_PHASES[idxPhase]; const channel = CHANNELS[idxChannel];
                const vehicle = VEHICLES[idxVehicle];
                return SIMULATOR_CONFIG.buildPrompt({
                    emotion,
                    phase,
                    channel,
                    vehicle,
                });
            }, [idxEmotion, idxPhase, idxChannel, idxVehicle]);

            // --- COMPONENTI UI SIMULATORE ---
            const CX = 500; const CY = 500;
            const getShortLabel = (name) => SIMULATOR_SHORT_LABELS[name] || name;

            const renderRing = (items, radius1, radius2, type, activeIndex) => {
                const total = items.length; const step = 360 / total;
                return items.map((item, i) => {
                    const startAngle = i * step + 0.5; const endAngle = (i + 1) * step - 0.5;
                    const midAngle = startAngle + (endAngle - startAngle) / 2;
                    const textRadius = radius1 + (radius2 - radius1) / 2;
                    const textPos = polarToCartesian(CX, CY, textRadius, midAngle);
                    const isSelected = i === activeIndex;
                    const isHovered = hoveredItem && hoveredItem.type === type && hoveredItem.index === i;
                    let fillColor = item.color;
                    let textColor = item.text || (type !== 'emotion' ? (isSelected ? 'white' : '#94a3b8') : 'white');
                    const opacity = isHovered ? 1 : (isSelected ? 1 : 0.55);
                    let fontSize; if (type === 'emotion') fontSize = 22; else if (type === 'phase') fontSize = 16; else fontSize = 17;
                    const ringLabel = type === 'emotion' ? 'Emozione' : (type === 'phase' ? 'Fase' : 'Canale');
                    return (
                        <g key={i} onClick={() => updateRotation(type, i)}
                            onMouseEnter={() => { SoundEngine.hover(); setHoveredItem({ type, index: i, name: item.name, color: item.color, textColor: item.text || 'white', ringLabel }); }}
                            onMouseLeave={() => setHoveredItem(null)}
                            onTouchStart={(e) => { e.stopPropagation(); SoundEngine.hover(); setHoveredItem({ type, index: i, name: item.name, color: item.color, textColor: item.text || 'white', ringLabel }); }}
                            onTouchEnd={() => setTimeout(() => setHoveredItem(null), 1200)}
                            className="cursor-pointer transition-opacity" style={{ opacity }}>
                            <path d={getAnnularSectorPath(CX, CY, radius1, radius2, startAngle, endAngle)} fill={fillColor}
                                stroke={isHovered ? '#22d3ee' : (isSelected ? '#ffffff' : 'rgba(255,255,255,0.08)')}
                                strokeWidth={isHovered ? 4 : (isSelected ? 3 : 1)} className="transition-all duration-200"
                                style={isHovered ? { filter: 'brightness(1.3) drop-shadow(0 0 8px rgba(34,211,238,0.4))' } : {}} />
                            {isHovered && (
                                <path d={getAnnularSectorPath(CX, CY, radius1 - 22, radius2 + 24, startAngle - 3, endAngle + 3)}
                                    fill={fillColor} stroke="#22d3ee" strokeWidth={3}
                                    style={{ filter: 'brightness(1.3) drop-shadow(0 0 14px rgba(34,211,238,0.5))', opacity: 0.95 }}
                                    className="pointer-events-none" />
                            )}
                            <text x={textPos.x} y={textPos.y} fill={textColor} fontSize={isHovered ? fontSize + 4 : fontSize}
                                fontWeight={isSelected || isHovered ? '700' : '500'} textAnchor="middle" dominantBaseline="middle"
                                transform={`translate(${textPos.x}, ${textPos.y}) rotate(${midAngle + 90}) translate(${-textPos.x}, ${-textPos.y})`}
                                className="pointer-events-none select-none"
                                style={{ fontFamily: "'DM Sans', sans-serif", letterSpacing: '0.02em', filter: (isSelected || isHovered) ? 'drop-shadow(0 0 4px rgba(0,0,0,0.6))' : 'none', transition: 'font-size 0.2s ease' }}>
                                {isHovered ? item.name : getShortLabel(item.name)}
                            </text>
                        </g>
                    );
                });
            };

            const AccordionHeader = ({ num, title }) => {
                const isOpen = openSections[num]; const isDone = stepsDone[num];
                return (
                    <div onClick={() => toggleSection(num)}
                        className={`w-full flex items-center gap-3 sm:gap-4 mb-3 cursor-pointer group transition-all p-3 sm:p-4 rounded-2xl border ${isOpen ? 'bg-slate-800/80 border-cyan-500/50 shadow-md shadow-cyan-900/20' : 'bg-slate-900/60 border-slate-800 hover:border-slate-600'}`}>
                        <button className={`flex items-center justify-center w-10 h-10 sm:w-12 sm:h-12 rounded-full shrink-0 shadow-lg transition-colors ${isDone ? 'bg-green-500 text-white' : (isOpen ? 'bg-cyan-500 text-slate-900' : 'bg-slate-800 text-slate-400 group-hover:bg-slate-700')}`}>
                            {isDone ? <IconCheck size={22} /> : <span className="text-lg sm:text-xl font-bold">{num}</span>}
                        </button>
                        <h2 className={`text-base sm:text-lg md:text-xl font-semibold leading-tight flex-grow transition-colors ${isOpen ? 'text-white' : 'text-slate-300 group-hover:text-slate-200'}`}>{title}</h2>
                        <div className={`transition-transform duration-300 ${isOpen ? 'rotate-90 text-cyan-400' : 'text-slate-500'}`}><IconChevronRight size={22} /></div>
                    </div>
                );
            };

            const SelectionLegend = () => (
                <div className="flex flex-wrap gap-2 sm:gap-3 justify-center mt-4 mb-2">
                    <div className="flex items-center gap-2 bg-slate-800/80 px-3 py-1.5 rounded-full border border-slate-700">
                        <div className="w-3 h-3 rounded-full" style={{ backgroundColor: PLUTCHIK_EMOTIONS[idxEmotion].color }}></div>
                        <span className="text-sm font-medium text-white">{PLUTCHIK_EMOTIONS[idxEmotion].name}</span>
                    </div>
                    <div className="flex items-center gap-2 bg-slate-800/80 px-3 py-1.5 rounded-full border border-slate-700">
                        <div className="w-3 h-3 rounded-full bg-slate-500"></div>
                        <span className="text-sm font-medium text-white">{SALES_PHASES[idxPhase].name}</span>
                    </div>
                    <div className="flex items-center gap-2 bg-slate-800/80 px-3 py-1.5 rounded-full border border-slate-700">
                        <div className="w-3 h-3 rounded-full bg-slate-400"></div>
                        <span className="text-sm font-medium text-white">{CHANNELS[idxChannel].name}</span>
                    </div>
                </div>
            );

            // --- TAB CONFIG ---
            const TAB_CONFIG = {
                simulator: { title: 'Simulatore di gestione emotiva di Clienti', desc: 'Segui i passaggi per creare la tua simulazione su misura. Clicca sui pannelli per aprire e chiudere le varie sezioni.' },
                optimizer: { title: 'Ottimizzatore di messaggi e comunicazioni', desc: 'Incolla un tuo messaggio, scegli stile e obiettivo, e lascia che la lavatrice faccia il lavoro sporco.' },
            };

            return (
                <div className="min-h-screen text-slate-200 font-sans p-4 sm:p-6 md:p-8 flex flex-col max-w-[1600px] mx-auto">
                    {/* HEADER */}
                    <header className="mb-6 sm:mb-8 pb-0">
                        <div className="flex flex-col sm:flex-row items-start sm:items-end justify-between gap-4 mb-6">
                            <div>
                                <div className="flex items-center gap-2.5 mb-3">
                                    <div className="w-10 h-10 sm:w-12 sm:h-12 rounded-xl bg-gradient-to-br from-cyan-500 to-cyan-700 flex items-center justify-center shadow-lg shadow-cyan-900/40">
                                        <IconCar className="text-white" size={24} />
                                    </div>
                                    <div className="flex flex-col">
                                        <span className="text-xs sm:text-sm font-semibold text-cyan-400 tracking-widest uppercase leading-none">AutoPrompt</span>
                                        <span className="text-[10px] sm:text-xs text-slate-500 font-medium tracking-wide leading-tight">by <a href="https://www.logotel.it" target="_blank" rel="noopener noreferrer" className="text-cyan-400/70 font-semibold hover:text-cyan-300 transition-colors">Logotel</a></span>
                                    </div>
                                    {onLogout && (
                                        <button
                                            onClick={onLogout}
                                            className="ml-4 px-3 py-1.5 text-xs font-medium text-slate-400 hover:text-white bg-slate-800/60 hover:bg-slate-700 border border-slate-700 rounded-lg transition-all"
                                        >
                                            Esci
                                        </button>
                                    )}
                                </div>
                                <h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-white leading-tight tracking-tight">
                                    {TAB_CONFIG[activeTab].title}
                                </h1>
                                <p className="text-slate-400 mt-2 max-w-xl text-sm sm:text-base leading-relaxed">
                                    {TAB_CONFIG[activeTab].desc}
                                </p>
                            </div>
                        </div>

                        {/* TAB BAR — hidden when only one tab is available */}
                        {(simulatorEnabled && optimizerEnabled) && <div className="flex gap-1 bg-slate-900/80 p-1 rounded-xl border border-slate-800 w-fit">
                            {simulatorEnabled && <button
                                onClick={() => { setActiveTab('simulator'); SoundEngine.click(); }}
                                className={`flex items-center gap-2 px-4 sm:px-5 py-2.5 rounded-lg font-medium text-sm transition-all ${
                                    activeTab === 'simulator'
                                        ? 'bg-cyan-600 text-white shadow-lg shadow-cyan-900/40'
                                        : 'text-slate-400 hover:text-white hover:bg-slate-800/60'
                                }`}
                            >
                                <IconCar size={18} />
                                <span className="hidden sm:inline">Simulatore</span>
                            </button>}
                            {optimizerEnabled && <button
                                onClick={() => { setActiveTab('optimizer'); SoundEngine.click(); }}
                                className={`flex items-center gap-2 px-4 sm:px-5 py-2.5 rounded-lg font-medium text-sm transition-all ${
                                    activeTab === 'optimizer'
                                        ? 'bg-cyan-600 text-white shadow-lg shadow-cyan-900/40'
                                        : 'text-slate-400 hover:text-white hover:bg-slate-800/60'
                                }`}
                            >
                                <IconMessageSquare size={18} />
                                <span className="hidden sm:inline">Ottimizzatore</span>
                            </button>}
                        </div>}
                    </header>

                    {/* CONTENT */}
                    {activeTab === 'simulator' ? (
                        /* ==================== TAB SIMULATORE ==================== */
                        <div className="flex flex-col lg:flex-row gap-4 lg:gap-10 flex-grow items-start">
                            {/* COLONNA SINISTRA (Step 1) */}
                            <div className="w-full lg:w-1/2 flex flex-col">
                                <AccordionHeader num={1} title="Definisci lo stato emotivo e la situazione del cliente." />
                                {openSections[1] && (
                                    <div className="w-full flex flex-col items-center animate-fade-in mb-6">
                                        <div className="w-full bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-6 shadow-xl">
                                            <div>
                                                <label className="block text-xs font-semibold text-slate-400 uppercase tracking-wider mb-2">Veicolo di interesse</label>
                                                <select
                                                    value={idxVehicle}
                                                    onChange={e => handleVehicleChange(Number(e.target.value))}
                                                    className="w-full bg-slate-950 border border-slate-700 rounded-lg px-4 py-3 focus:outline-none focus:border-cyan-500 focus:ring-1 focus:ring-cyan-500 transition-colors text-base text-white appearance-none cursor-pointer"
                                                    style={{ backgroundImage: "url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M2 4l4 4 4-4' fill='none' stroke='%2394a3b8' stroke-width='2'/%3E%3C/svg%3E\")", backgroundRepeat: 'no-repeat', backgroundPosition: 'right 16px center' }}
                                                >
                                                    {VEHICLES.map((v, i) => (
                                                        <option key={i} value={i}>{v.name}</option>
                                                    ))}
                                                </select>
                                            </div>
                                            <div className="mt-4 flex justify-center">
                                                <button onClick={handleRandomize}
                                                    className="px-5 py-2.5 sm:px-6 sm:py-3 bg-cyan-600 hover:bg-cyan-500 text-white rounded-full font-medium flex items-center gap-2 transition-all shadow-lg shadow-cyan-900/50 active:scale-95 text-sm sm:text-base">
                                                    <IconRefreshCw size={18} /> Gira la Ruota!
                                                </button>
                                            </div>
                                        </div>

                                        <div className="relative w-full max-w-lg sm:max-w-xl aspect-square mx-auto">
                                            <div className="absolute top-0 left-1/2 -translate-x-1/2 -translate-y-3 z-10 drop-shadow-lg">
                                                <svg width="36" height="28" viewBox="0 0 40 30" fill="none"><path d="M20 30L40 0H0L20 30Z" fill="#22d3ee" /></svg>
                                            </div>
                                            <svg viewBox="0 0 1000 1000" className="w-full h-full filter drop-shadow-2xl">
                                                <circle cx="500" cy="500" r="480" fill="#020617" />
                                                <g style={{ transform: `rotate(${rotEmotion}deg)`, transformOrigin: '500px 500px', transition: 'transform 1.2s cubic-bezier(0.25, 1, 0.5, 1)' }}>
                                                    {renderRing(PLUTCHIK_EMOTIONS, 310, 460, 'emotion', idxEmotion)}
                                                </g>
                                                <g style={{ transform: `rotate(${rotPhase}deg)`, transformOrigin: '500px 500px', transition: 'transform 1s cubic-bezier(0.25, 1, 0.5, 1) 0.1s' }}>
                                                    {renderRing(SALES_PHASES, 185, 295, 'phase', idxPhase)}
                                                </g>
                                                <g style={{ transform: `rotate(${rotChannel}deg)`, transformOrigin: '500px 500px', transition: 'transform 0.8s cubic-bezier(0.25, 1, 0.5, 1) 0.2s' }}>
                                                    {renderRing(CHANNELS, 85, 170, 'channel', idxChannel)}
                                                </g>
                                                <circle cx="500" cy="500" r="72" fill="#0f172a" stroke="#1e293b" strokeWidth="4" />
                                                <circle cx="500" cy="500" r="18" fill="#334155" />
                                            </svg>
                                            {hoveredItem && (
                                                <div className="absolute pointer-events-none" style={{ top: '50%', left: '50%', transform: 'translate(-50%, -50%)', zIndex: 20 }}>
                                                    <div className="bg-slate-900/95 backdrop-blur-sm border-2 border-cyan-500/60 rounded-xl px-5 py-3 shadow-2xl shadow-cyan-900/40 text-center whitespace-nowrap"
                                                         style={{ animation: 'fadeIn 0.15s ease-out' }}>
                                                        <div className="text-[10px] sm:text-xs font-semibold text-slate-400 uppercase tracking-widest mb-1">{hoveredItem.ringLabel}</div>
                                                        <div className="text-base sm:text-lg font-bold" style={{ color: (hoveredItem.color === '#0f172a' || hoveredItem.color === '#1e293b' || hoveredItem.color === '#334155') ? '#22d3ee' : hoveredItem.color }}>
                                                            {hoveredItem.name}
                                                        </div>
                                                    </div>
                                                </div>
                                            )}
                                        </div>
                                        <SelectionLegend />
                                        <div className="mt-4 flex items-start gap-3 bg-slate-900/50 p-3 sm:p-4 rounded-xl border border-slate-800 text-sm text-slate-400 w-full max-w-lg">
                                            <IconInfo className="flex-shrink-0 text-cyan-500 mt-0.5" size={18} />
                                            <p>Seleziona i livelli cliccando sugli spicchi o usa la randomizzazione. Le scelte si allineano sul puntatore in alto.</p>
                                        </div>
                                        <div className="mt-5 w-full flex justify-end">
                                            <button onClick={() => { markStepDone(1); setOpenSections(prev => ({...prev, 1: false, 2: true})); }}
                                                className="px-5 py-2.5 bg-slate-800 hover:bg-slate-700 border border-slate-700 text-white rounded-lg transition-colors flex items-center gap-2 text-sm sm:text-base">
                                                Conferma e Vai al Prompt <IconChevronRight size={18} />
                                            </button>
                                        </div>
                                    </div>
                                )}
                            </div>

                            {/* COLONNA DESTRA (Steps 2, 3, 4) */}
                            <div className="w-full lg:w-1/2 flex flex-col gap-2">
                                <AccordionHeader num={2} title="Genera il prompt da copiare nel LLM." />
                                {openSections[2] && (
                                    <div className="animate-fade-in mb-5">
                                        <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5">
                                            <h3 className="text-base sm:text-lg font-bold text-white mb-3">La tua configurazione:</h3>
                                            <ul className="space-y-2.5">
                                                <li className="flex items-center gap-3"><div className="w-4 h-4 rounded-full shrink-0" style={{backgroundColor: PLUTCHIK_EMOTIONS[idxEmotion].color}}></div><span className="text-slate-300 font-medium w-20 sm:w-24 text-sm">Emozione:</span><span className="text-white font-bold text-sm sm:text-base">{PLUTCHIK_EMOTIONS[idxEmotion].name}</span></li>
                                                <li className="flex items-center gap-3"><div className="w-4 h-4 rounded-full bg-slate-600 shrink-0"></div><span className="text-slate-300 font-medium w-20 sm:w-24 text-sm">Fase:</span><span className="text-white font-bold text-sm sm:text-base">{SALES_PHASES[idxPhase].name}</span></li>
                                                <li className="flex items-center gap-3"><div className="w-4 h-4 rounded-full bg-slate-600 shrink-0"></div><span className="text-slate-300 font-medium w-20 sm:w-24 text-sm">Canale:</span><span className="text-white font-bold text-sm sm:text-base">{CHANNELS[idxChannel].name}</span></li>
                                            </ul>
                                        </div>
                                        <div className="relative flex-grow flex flex-col bg-slate-950 border-2 border-slate-800 rounded-2xl overflow-hidden shadow-2xl min-h-[300px] sm:min-h-[400px]">
                                            <div className="bg-slate-900 border-b border-slate-800 px-4 sm:px-6 py-3 sm:py-4 flex justify-between items-center sticky top-0 gap-3">
                                                <span className="font-semibold text-slate-300 text-sm sm:text-base">Prompt di Addestramento</span>
                                                <button onClick={copyToClipboard}
                                                    className={`flex items-center gap-2 px-3 sm:px-4 py-2 rounded-lg font-medium transition-all text-sm shrink-0 ${copied ? 'bg-green-500/20 text-green-400 border border-green-500/50' : 'bg-cyan-600 text-white hover:bg-cyan-500 border border-transparent'}`}>
                                                    {copied ? <IconCheck size={16} /> : <IconCopy size={16} />}
                                                    {copied ? 'Copiato!' : 'Copia Prompt'}
                                                </button>
                                            </div>
                                            <div className="p-4 sm:p-6 overflow-auto max-h-[400px] sm:max-h-[500px] custom-scroll">
                                                <pre className="whitespace-pre-wrap font-mono text-xs sm:text-sm leading-relaxed text-slate-300">{generatedPrompt}</pre>
                                            </div>
                                        </div>
                                    </div>
                                )}

                                <AccordionHeader num={3} title="Simula l'interazione con il cliente!" />
                                {openSections[3] && (
                                    <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5 animate-fade-in shadow-lg">
                                        <h3 className="text-lg sm:text-xl font-bold text-white mb-4">Come procedere all'allenamento:</h3>
                                        <div className="space-y-4 sm:space-y-5 text-slate-300">
                                            <div className="flex gap-3 sm:gap-4 items-start"><div className="bg-slate-800 p-2 rounded-lg shrink-0 text-xl sm:text-2xl">🤖</div><div><strong className="text-white block text-sm sm:text-base mb-1">Incolla nel tuo LLM preferito</strong><p className="text-xs sm:text-sm leading-relaxed">Apri ChatGPT, Claude, Copilot o Gemini e incolla il prompt che hai appena copiato. L'IA entrerà istantaneamente nella parte del cliente e ti rivolgerà la prima frase.</p></div></div>
                                            <div className="flex gap-3 sm:gap-4 items-start"><div className="bg-cyan-900/50 border border-cyan-800 p-2 rounded-lg shrink-0 text-xl sm:text-2xl animate-subtle-pulse">🎙️</div><div><strong className="text-cyan-400 block text-sm sm:text-base mb-1">Consiglio PRO: Usa la Voce!</strong><p className="text-xs sm:text-sm leading-relaxed">Se usi l'App dal tuo smartphone (o l'estensione vocale su PC), puoi abilitare la <strong className="text-white">Conversazione Vocale</strong>. Non serve scrivere nulla: parla con l'IA naturalmente come faresti con un vero cliente nel salone. La simulazione diventerà incredibilmente realistica!</p></div></div>
                                            <div className="flex gap-3 sm:gap-4 items-start"><div className="bg-slate-800 p-2 rounded-lg shrink-0 text-xl sm:text-2xl">🎯</div><div><strong className="text-white block text-sm sm:text-base mb-1">L'obiettivo: Customer Centricity</strong><p className="text-xs sm:text-sm leading-relaxed">Rispondi con calma alle sue obiezioni. Se usi il giusto tono empatico e trovi la soluzione al suo problema, vedrai il cliente "sciogliersi" e l'emozione diventerà positiva. Se sbagli approccio, peggiorerà.</p></div></div>
                                        </div>
                                        <div className="mt-5 pt-4 border-t border-slate-800 flex justify-end">
                                            <button onClick={() => { markStepDone(3); setOpenSections(prev => ({...prev, 3: false, 4: true})); }}
                                                className="px-4 sm:px-5 py-2.5 bg-slate-800 hover:bg-slate-700 border border-slate-700 text-white rounded-lg transition-colors flex items-center gap-2 text-sm">
                                                <IconCheck size={18} /> Ho capito, sono pronto!
                                            </button>
                                        </div>
                                    </div>
                                )}

                                <AccordionHeader num={4} title="Ricevi il feedback e l'analisi finale." />
                                {openSections[4] && (
                                    <div className="bg-slate-900 border border-slate-800 rounded-2xl p-4 sm:p-6 mb-5 animate-fade-in shadow-lg">
                                        <h3 className="text-lg sm:text-xl font-bold text-white mb-4">Come terminare e farsi valutare</h3>
                                        <p className="text-slate-300 mb-4 leading-relaxed text-sm sm:text-base">Quando ritieni di aver chiuso la trattativa, risolto il problema, o semplicemente se senti di non riuscire a gestire la situazione, puoi fermare il gioco di ruolo. Ti basta pronunciare o scrivere le parole magiche:</p>
                                        <div className="bg-slate-950 border border-slate-800 p-4 rounded-xl text-center mb-5"><strong className="text-xl sm:text-2xl tracking-wider text-cyan-400 font-mono">FINE SIMULAZIONE</strong></div>
                                        <p className="text-slate-300 mb-3 font-semibold text-white text-sm sm:text-base">Il Bot ti consegnerà una vera e propria pagella strutturata in 4 punti:</p>
                                        <ul className="space-y-3 text-slate-300 bg-slate-800/50 p-4 sm:p-5 rounded-xl border border-slate-700/50">
                                            <li className="flex gap-3 items-start"><span className="text-blue-400 text-lg shrink-0">🎯</span><p className="text-sm"><strong className="text-white">Customer Centricity:</strong> Analisi di come hai saputo accogliere e (se sei stato bravo) ribaltare l'emozione iniziale del cliente.</p></li>
                                            <li className="flex gap-3 items-start"><span className="text-green-500 text-lg shrink-0">🟢</span><p className="text-sm"><strong className="text-white">Punti di forza:</strong> Quali argomentazioni e comportamenti empatici hanno funzionato meglio.</p></li>
                                            <li className="flex gap-3 items-start"><span className="text-red-500 text-lg shrink-0">🔴</span><p className="text-sm"><strong className="text-white">Aree di miglioramento:</strong> Errori commessi, frasi da evitare o momenti in cui hai forzato troppo la mano.</p></li>
                                            <li className="flex gap-3 items-start"><span className="text-yellow-400 text-lg shrink-0">📊</span><p className="text-sm"><strong className="text-white">Valutazione:</strong> Un voto oggettivo da 1 a 10 sull'intera performance.</p></li>
                                        </ul>
                                        <div className="mt-5 pt-4 border-t border-slate-800 flex justify-end">
                                            <button onClick={() => { markStepDone(4); setOpenSections(prev => ({...prev, 4: false})); }}
                                                className="px-4 sm:px-5 py-2.5 bg-slate-800 hover:bg-slate-700 border border-slate-700 text-white rounded-lg transition-colors flex items-center gap-2 text-sm">
                                                <IconCheck size={18} /> Segna come completato
                                            </button>
                                        </div>
                                    </div>
                                )}
                            </div>
                        </div>
                    ) : (
                        /* ==================== TAB OTTIMIZZATORE ==================== */
                        <OptimizerTab />
                    )}

                    {/* FOOTER DISCLAIMER */}
                    <footer className="mt-10 pt-5 border-t border-slate-800/60 text-center">
                        <p className="text-slate-600 text-xs leading-relaxed max-w-2xl mx-auto">
                            Questo strumento è riservato ai soggetti che hanno sottoscritto un accordo con <a href="https://www.logotel.it" target="_blank" rel="noopener noreferrer" className="text-slate-500 hover:text-cyan-400 underline transition-colors">Logotel</a>. L'utilizzo al di fuori di tale contesto non è autorizzato.
                        </p>
                    </footer>
                </div>
            );
        }

        const root = ReactDOM.createRoot(document.getElementById('root'));
        root.render(<LoginGate />);
