﻿/* global React */
/* eslint-disable */
const { useState: useStateWA, useEffect: useEffectWA, useRef: useRefWA } = React;
const gm = window.getMsg;

/* ── Tour steps ── */
const WA_STEPS = [
  /* 0 — welcome */
  {
    id: 'welcome', progress: 5,
    msgs: [
      { from: 'aimy', kind: 'recall' },
      { from: 'aimy', text: gm(
        '¡Bienvenido al módulo <strong>Workspace</strong>! 🎉 Aquí vas a aprender a <strong>crear proyectos web completos</strong> usando solo lenguaje natural.',
        'Bienvenue dans le module <strong>Workspace</strong> ! 🎉 Ici tu vas apprendre à <strong>créer des projets web complets</strong> en utilisant uniquement le langage naturel.',
        'Welcome to the <strong>Workspace</strong> module! 🎉 Here you\'ll learn to <strong>create complete web projects</strong> using only natural language.'
      ) },
      { from: 'aimy', text: gm('¿Empezamos? 🚀', 'On commence ? 🚀', 'Shall we start? 🚀') },
    ],
    quickReplies: [
      gm('¡Vamos! 🚀', 'Allons-y ! 🚀', 'Let\'s go! 🚀'),
      gm('¿Qué es el Workspace?', 'C\'est quoi le Workspace ?', 'What is the Workspace?'),
    ],
  },

  /* 1 — what is vibecoding */
  {
    id: 'what-is', progress: 14,
    msgs: [
      { from: 'aimy', text: gm(
        '<em>"El Workspace es tu entorno de vibecoding — creas código simplemente <strong>describiendo</strong> lo que quieres."</em>',
        '<em>"Le Workspace est ton environnement de vibecoding — tu crées du code simplement en <strong>décrivant</strong> ce que tu veux."</em>',
        '<em>"The Workspace is your vibecoding environment — you create code simply by <strong>describing</strong> what you want."</em>'
      ), kind: 'quote' },
      { from: 'aimy', text: gm(
        'No necesitas saber programar. Dile a la IA qué quieres y ella genera el código HTML, CSS y JavaScript por ti.',
        'Pas besoin de savoir coder. Dis à l\'IA ce que tu veux et elle génère le code HTML, CSS et JavaScript pour toi.',
        'No need to know how to code. Tell the AI what you want and it generates HTML, CSS, and JavaScript code for you.'
      ) },
      { from: 'aimy', kind: 'wsstats' },
    ],
  },

  /* 2 — library */
  {
    id: 'library', progress: 25,
    spotlight: '[data-tour="ws-library-btn"]',
    spotlightLabel: gm('Plantillas listas para usar', 'Modèles prêts à l\'emploi', 'Ready-to-use templates'),
    msgs: [
      { from: 'aimy', text: gm(
        '¿Ves el botón <strong>From Library</strong>? Ahí hay <strong>6 plantillas</strong> listas: Landing Page, Portfolio, Dashboard, E-commerce, Blog y Formulario de contacto.',
        'Tu vois le bouton <strong>From Library</strong> ? Il y a <strong>6 modèles</strong> prêts : Landing Page, Portfolio, Dashboard, E-commerce, Blog et Formulaire de contact.',
        'See the <strong>From Library</strong> button? There are <strong>6 ready templates</strong>: Landing Page, Portfolio, Dashboard, E-commerce, Blog, and Contact Form.'
      ) },
      { from: 'aimy', text: gm(
        'Cada plantilla ya viene con HTML completo — ¡solo la seleccionas, le pones nombre y listo!',
        'Chaque modèle inclut déjà du HTML complet — tu le sélectionnes, tu lui donnes un nom et c\'est parti !',
        'Each template already comes with full HTML — just select it, give it a name, and you\'re ready!'
      ) },
    ],
    quickReplies: [
      gm('Entendido 👍', 'Compris 👍', 'Got it 👍'),
      gm('¿Cómo creo un workspace?', 'Comment créer un workspace ?', 'How do I create a workspace?'),
    ],
  },

  /* 3 — create workspace */
  {
    id: 'create', progress: 35,
    spotlight: '[data-tour="ws-new-btn"]',
    spotlightLabel: gm('Crea tu primer workspace', 'Crée ton premier workspace', 'Create your first workspace'),
    msgs: [
      { from: 'aimy', text: gm(
        'Ahora <strong>crea tu primer workspace</strong>. Haz clic en <strong>+ Nuevo Workspace</strong> (o en "From Library" para empezar con una plantilla).',
        'Maintenant <strong>crée ton premier workspace</strong>. Clique sur <strong>+ New Workspace</strong> (ou sur "From Library" pour commencer avec un modèle).',
        'Now <strong>create your first workspace</strong>. Click <strong>+ New Workspace</strong> (or "From Library" to start with a template).'
      ) },
      { from: 'aimy', text: gm(
        'Ponle un nombre y una descripción opcional. ¡Te espero!',
        'Donne-lui un nom et une description optionnelle. Je t\'attends !',
        'Give it a name and an optional description. I\'ll wait for you!'
      ) },
    ],
    gate: (ctx) => ctx.wsCreated,
    gateHint: gm(
      'Crea un workspace para continuar',
      'Crée un workspace pour continuer',
      'Create a workspace to continue'
    ),
  },

  /* 4 — inside editor: chat panel */
  {
    id: 'chat-intro', progress: 46,
    spotlight: '[data-tour="ws-chat-panel"]',
    spotlightLabel: gm('El motor de vibecoding', 'Le moteur de vibecoding', 'The vibecoding engine'),
    msgs: [
      { from: 'aimy', text: gm(
        '🎉 ¡Workspace creado! Ahora estás en el <strong>editor</strong>. A la izquierda tienes el <strong>AI Chat</strong> — es donde le describes a la IA lo que quieres crear.',
        '🎉 Workspace créé ! Tu es maintenant dans l\'<strong>éditeur</strong>. À gauche tu as l\'<strong>AI Chat</strong> — c\'est là que tu décris à l\'IA ce que tu veux créer.',
        '🎉 Workspace created! You\'re now in the <strong>editor</strong>. On the left is the <strong>AI Chat</strong> — that\'s where you describe to the AI what you want to create.'
      ) },
      { from: 'aimy', text: gm(
        'Puedes pedirle cosas como: <em>"crea una landing page"</em>, <em>"añade un header azul"</em>, <em>"ponle animaciones"</em>…',
        'Tu peux lui demander des choses comme : <em>"crée une landing page"</em>, <em>"ajoute un header bleu"</em>, <em>"ajoute des animations"</em>…',
        'You can ask things like: <em>"create a landing page"</em>, <em>"add a blue header"</em>, <em>"add animations"</em>…'
      ) },
    ],
    quickReplies: [
      gm('¡Voy a probar!', 'Je vais essayer !', 'I\'ll try it!'),
    ],
  },

  /* 5 — use the chat (gate) */
  {
    id: 'use-chat', progress: 56,
    spotlight: '[data-tour="ws-chat-panel"]',
    spotlightLabel: gm('¡Escribe tu primer prompt!', 'Écris ton premier prompt !', 'Write your first prompt!'),
    msgs: [
      { from: 'aimy', text: gm(
        'Pruébalo ahora. Escribe algo en el chat como <strong>"crea una landing page"</strong> y presiona Enter o el botón de enviar.',
        'Essaie maintenant. Écris quelque chose dans le chat comme <strong>"crée une landing page"</strong> et appuie sur Entrée ou le bouton d\'envoi.',
        'Try it now. Write something in the chat like <strong>"create a landing page"</strong> and press Enter or the send button.'
      ) },
      { from: 'aimy', text: gm(
        'La IA generará el código y lo verás aparecer en el Explorer. 👀',
        'L\'IA va générer le code et tu le verras apparaître dans l\'Explorer. 👀',
        'The AI will generate the code and you\'ll see it appear in the Explorer. 👀'
      ) },
    ],
    gate: (ctx) => ctx.chatUsed,
    gateHint: gm(
      'Envía un mensaje al chat para continuar',
      'Envoie un message dans le chat pour continuer',
      'Send a message in the chat to continue'
    ),
  },

  /* 6 — code view + explorer */
  {
    id: 'code-view', progress: 65,
    spotlight: '[data-tour="ws-explorer"]',
    spotlightLabel: gm('Tus archivos generados', 'Tes fichiers générés', 'Your generated files'),
    msgs: [
      { from: 'aimy', text: gm(
        '¡La IA generó código! A la derecha tienes el panel <strong>Code / Preview</strong>.',
        'L\'IA a généré du code ! À droite tu as le panneau <strong>Code / Preview</strong>.',
        'The AI generated code! On the right you have the <strong>Code / Preview</strong> panel.'
      ) },
      { from: 'aimy', text: gm(
        'En la pestaña <strong>Code</strong>: el <strong>Explorer</strong> muestra todos tus archivos. Haz clic en uno para ver su código completo con resaltado de sintaxis.',
        'Dans l\'onglet <strong>Code</strong> : l\'<strong>Explorer</strong> affiche tous tes fichiers. Clique sur un pour voir son code complet avec coloration syntaxique.',
        'In the <strong>Code</strong> tab: the <strong>Explorer</strong> shows all your files. Click one to see its full code with syntax highlighting.'
      ) },
      { from: 'aimy', kind: 'wscode-tip' },
    ],
    quickReplies: [
      gm('¿Y el Preview?', 'Et le Preview ?', 'What about Preview?'),
    ],
  },

  /* 7 — preview */
  {
    id: 'preview', progress: 74,
    spotlight: '[data-tour="ws-preview-tab"]',
    spotlightLabel: gm('Vista previa en vivo', 'Aperçu en direct', 'Live preview'),
    msgs: [
      { from: 'aimy', text: gm(
        'La pestaña <strong>Preview</strong> renderiza tu HTML en tiempo real, como si estuvieras abriendo la página en un navegador.',
        'L\'onglet <strong>Preview</strong> affiche ton HTML en temps réel, comme si tu ouvrais la page dans un navigateur.',
        'The <strong>Preview</strong> tab renders your HTML in real time, just like opening the page in a browser.'
      ) },
      { from: 'aimy', text: gm(
        'Haz clic en <strong>Preview</strong> para ver cómo queda visualmente tu página. ¡Te vas a sorprender!',
        'Clique sur <strong>Preview</strong> pour voir le rendu visuel de ta page. Tu vas être surpris !',
        'Click <strong>Preview</strong> to see the visual result of your page. You\'ll be surprised!'
      ) },
    ],
    gate: (ctx) => ctx.hasFiles,
    gateHint: gm(
      'Genera al menos un archivo con el chat',
      'Génère au moins un fichier avec le chat',
      'Generate at least one file with the chat'
    ),
  },

  /* 8 — download */
  {
    id: 'download', progress: 82,
    msgs: [
      { from: 'aimy', text: gm(
        'Una vez satisfecho con tu proyecto, puedes hacer clic en <strong>Descargar</strong> (arriba a la derecha) para obtener los archivos listos para subir a cualquier servidor.',
        'Une fois satisfait de ton projet, tu peux cliquer sur <strong>Télécharger</strong> (en haut à droite) pour obtenir les fichiers prêts à être hébergés.',
        'Once happy with your project, click <strong>Download</strong> (top right) to get files ready to upload to any server.'
      ) },
      { from: 'aimy', text: gm(
        '¡El ciclo completo: <strong>idea → prompt → código → preview → descarga</strong>. Eso es el vibecoding. ✨',
        'Le cycle complet : <strong>idée → prompt → code → preview → téléchargement</strong>. C\'est le vibecoding. ✨',
        'The full cycle: <strong>idea → prompt → code → preview → download</strong>. That\'s vibecoding. ✨'
      ) },
    ],
    quickReplies: [
      gm('¡Increíble! 🤩', 'Incroyable ! 🤩', 'Incredible! 🤩'),
      gm('¿Hay quiz?', 'Il y a un quiz ?', 'Is there a quiz?'),
    ],
  },

  /* 9 — quiz */
  {
    id: 'quiz', progress: 90,
    msgs: [
      { from: 'aimy', text: gm(
        '¡Perfecto! Antes de tu insignia, un pequeño quiz. 🧠',
        'Parfait ! Avant ton insigne, un petit quiz. 🧠',
        'Perfect! Before your badge, a quick quiz. 🧠'
      ) },
      { from: 'aimy', kind: 'quiz' },
    ],
    gate: (ctx) => ctx.quizDone,
    gateHint: gm('Responde las 3 preguntas', 'Réponds aux 3 questions', 'Answer all 3 questions'),
  },

  /* 10 — badge */
  {
    id: 'done', progress: 100,
    msgs: [
      { from: 'aimy', kind: 'badge' },
      { from: 'aimy', text: gm(
        '¡Ya sabes crear proyectos web completos con IA! El vibecoding te convierte en un creador sin barreras. <strong>El mundo es tu lienzo.</strong> 🌍',
        'Tu sais maintenant créer des projets web complets avec l\'IA ! Le vibecoding fait de toi un créateur sans barrières. <strong>Le monde est ta toile.</strong> 🌍',
        'You now know how to create complete web projects with AI! Vibecoding makes you a barrier-free creator. <strong>The world is your canvas.</strong> 🌍'
      ) },
    ],
  },
];

/* ── Stats widget ── */
function WsStats() {
  return (
    <div className="aimy-cards">
      <div className="stat-card">
        <div className="v">6</div>
        <div className="l">{gm('Plantillas listas','Modèles prêts','Ready templates')}</div>
      </div>
      <div className="stat-card">
        <div className="v">0</div>
        <div className="l">{gm('Código requerido','Code requis','Code required')}</div>
      </div>
      <div className="stat-card">
        <div className="v">✨</div>
        <div className="l">{gm('Vibecoding puro','Vibecoding pur','Pure vibecoding')}</div>
      </div>
    </div>
  );
}

/* ── Code tip widget ── */
function WsCodeTip() {
  return (
    <div style={{
      background:'#1e1e2e', borderRadius:10, padding:'10px 14px',
      fontFamily:"'Fira Code',monospace", fontSize:12, color:'#cdd6f4',
      lineHeight:1.6, marginTop:4,
    }}>
      <div style={{color:'#a6e3a1'}}>{'<'}<span style={{color:'#89b4fa'}}>div</span> <span style={{color:'#f9e2af'}}>class</span>=<span style={{color:'#a6e3a1'}}>"hero"</span>{'>'}</div>
      <div style={{paddingLeft:14,color:'#cdd6f4'}}>  {'<'}<span style={{color:'#89b4fa'}}>h1</span>{'>'}<span style={{color:'#a6e3a1'}}>Votre App 🚀</span>{'</'}<span style={{color:'#89b4fa'}}>h1</span>{'>'}</div>
      <div style={{color:'#a6e3a1'}}>{'</'}<span style={{color:'#89b4fa'}}>div</span>{'>'}</div>
      <div style={{borderTop:'1px solid #313244',marginTop:8,paddingTop:8,color:'#6c7086',fontSize:11}}>
        {gm('← Así luce el código generado por la IA','← Voilà ce que génère l\'IA','← This is what the AI-generated code looks like')}
      </div>
    </div>
  );
}

/* ── Recall ── */
function WsRecall() {
  const p = window.AIMakerProgress ? window.AIMakerProgress.get() : { modules:{}, badges:[], points:0 };
  const completed = Object.entries(p.modules).filter(([_,v])=>v).map(([k])=>k);
  const labels = {
    data:     gm('Banco de Datos','Banque de données','Data Bank'),
    fablab:   'Fablab Chat',
    apps:     gm('Apps Mgmt','Apps Mgmt','Apps Mgmt'),
    products: gm('Productos','Produits','Products'),
    server:   gm('Servidor','Serveur','Server'),
    external: gm('Acceso Externo','Accès Externe','External Access'),
  };
  if (completed.length === 0) {
    return (
      <div className="aimy-recall" dangerouslySetInnerHTML={{__html: gm(
        '¡Hola! 👋 Soy <b>DIAS</b>, tu copiloto AIMaker. Este módulo de <b>Workspace</b> te enseña a crear proyectos web con IA usando solo descripciones en lenguaje natural.',
        '👋 Bonjour ! Je suis <b>DIAS</b>, ton copilote AIMaker. Ce module <b>Workspace</b> t\'apprend à créer des projets web avec l\'IA en utilisant uniquement des descriptions en langage naturel.',
        '👋 Hi! I\'m <b>DIAS</b>, your AIMaker copilot. This <b>Workspace</b> module teaches you to create web projects with AI using only natural language descriptions.'
      )}}/>
    );
  }
  return (
    <div className="aimy-recall">
      {gm('¡Hola de nuevo! 👋 Ya completaste','Rebonjour ! 👋 Tu as déjà complété','Welcome back! 👋 You\'ve already completed')}{' '}
      <b>{completed.map(c => labels[c] || c).join(', ')}</b>.{' '}
      {gm('Llevas','Tu as','You have')} <b>{p.points} {window.t('quiz.pts')}</b>.
      {p.badges.length > 0 && (
        <div className="badges">
          {p.badges.map(b => <span key={b} className="badge-mini">🛡️ {b}</span>)}
        </div>
      )}
    </div>
  );
}

/* ── Quiz ── */
const WA_QUIZ = [
  {
    q: gm(
      '¿Qué es el vibecoding?',
      'Qu\'est-ce que le vibecoding ?',
      'What is vibecoding?'
    ),
    opts: [
      gm('Una técnica avanzada de programación', 'Une technique avancée de programmation', 'An advanced programming technique'),
      gm('Crear código describiendo lo que quieres en lenguaje natural', 'Créer du code en décrivant ce qu\'on veut en langage naturel', 'Creating code by describing what you want in natural language'),
      gm('Un editor de código visual', 'Un éditeur de code visuel', 'A visual code editor'),
    ],
    correct: 1,
  },
  {
    q: gm(
      '¿Para qué sirve la pestaña Preview en el Workspace?',
      'À quoi sert l\'onglet Preview dans le Workspace ?',
      'What is the Preview tab for in the Workspace?'
    ),
    opts: [
      gm('Editar los estilos CSS directamente', 'Éditer les styles CSS directement', 'Edit CSS styles directly'),
      gm('Ver el resultado visual de tu código en tiempo real', 'Voir le résultat visuel du code en temps réel', 'See the visual result of your code in real time'),
      gm('Exportar los archivos al servidor', 'Exporter les fichiers vers le serveur', 'Export files to the server'),
    ],
    correct: 1,
  },
  {
    q: gm(
      '¿Cuál es la ventaja principal de usar una plantilla de la Librería?',
      'Quel est l\'avantage principal d\'utiliser un modèle de la Bibliothèque ?',
      'What is the main advantage of using a Library template?'
    ),
    opts: [
      gm('Las plantillas son gratis y sin límites', 'Les modèles sont gratuits et sans limites', 'Templates are free and unlimited'),
      gm('Empezar con una base de código funcional sin escribir nada', 'Commencer avec une base de code fonctionnelle sans rien écrire', 'Start with a functional code base without writing anything'),
      gm('Tienen más funciones que los proyectos creados manualmente', 'Ils ont plus de fonctions que les projets créés manuellement', 'They have more features than manually created projects'),
    ],
    correct: 1,
  },
];

function WaQuiz({ onDone }) {
  const [i, setI] = useStateWA(0);
  const [picked, setPicked] = useStateWA(null);
  const [points, setPoints] = useStateWA(0);
  const [failed, setFailed] = useStateWA(false);
  function pick(idx) {
    if (picked !== null) return;
    setPicked(idx);
    const np = points + (idx === WA_QUIZ[i].correct ? 25 : 0);
    setPoints(np);
    setTimeout(() => {
      if (i + 1 >= WA_QUIZ.length) {
        if (np === 75) { onDone(np); }
        else { setFailed(true); }
      } else { setI(i + 1); setPicked(null); }
    }, 950);
  }
  if (failed) {
    const correct = Math.round(points / 25);
    return (
      <div style={{textAlign:'center', padding:'12px 8px'}}>
        <div style={{fontSize:28, marginBottom:8}}>😅</div>
        <p style={{color:'var(--text-soft)', fontSize:13, marginBottom:12}}>
          {correct}/3 {gm('correctas. Necesitas las 3 para continuar.','correctes. Il te faut les 3 pour continuer.','correct. You need all 3 to continue.')}
        </p>
        <button className="aimy-btn primary" style={{width:'100%'}} onClick={()=>{ setI(0); setPicked(null); setPoints(0); setFailed(false); }}>
          {gm('Reintentar 🔄','Réessayer 🔄','Retry 🔄')}
        </button>
      </div>
    );
  }
  const q = WA_QUIZ[i];
  return (
    <div>
      <div style={{display:'flex',justifyContent:'space-between',fontSize:11,color:'var(--text-soft)',marginBottom:6}}>
        <span>{window.t('quiz.q')} {i + 1} / {WA_QUIZ.length}</span>
        <span><strong style={{color:'var(--brand)'}}>{points}</strong> {window.t('quiz.pts')}</span>
      </div>
      <p className="quiz-q">{q.q}</p>
      <div className="quiz-opts">
        {q.opts.map((o, idx) => {
          let cls = 'quiz-opt';
          if (picked !== null) {
            if (idx === q.correct) cls += ' right';
            else if (idx === picked) cls += ' wrong';
          }
          return <button key={idx} className={cls} onClick={() => pick(idx)}>{o}</button>;
        })}
      </div>
    </div>
  );
}

/* ── Badge ── */
function WaBadge({ points }) {
  return (
    <div className="badge-trophy">
      <div className="seal" style={{background:'radial-gradient(circle at 30% 30%, #e0e7ff, #6366f1 60%, #312e81)'}}>✨</div>
      <h3>{window.t('badge.workspace')}</h3>
      <div style={{color:'var(--text-soft)',fontSize:13}}>{window.t('badge.sub.workspace')}</div>
      <div className="pts">{points} {window.t('quiz.pts')} ⭐</div>
    </div>
  );
}

/* ── Message renderer ── */
function WaMessage({ m, slot }) {
  if (m.kind === 'recall') {
    return (
      <div className="msg">
        <div className="av">A</div>
        <div className="bubble" style={{maxWidth:'94%',padding:'10px 12px'}}><WsRecall/></div>
      </div>
    );
  }
  if (m.kind === 'quote') {
    return (
      <div className="msg">
        <div className="av">A</div>
        <div className="bubble"><div className="quote" dangerouslySetInnerHTML={{__html: m.text}}/></div>
      </div>
    );
  }
  if (m.kind && slot) {
    return (
      <div className="msg">
        <div className="av">A</div>
        <div className="bubble" style={{maxWidth:'94%'}}>{slot}</div>
      </div>
    );
  }
  return (
    <div className={'msg' + (m.from === 'user' ? ' user' : '')}>
      <div className="av">{m.from === 'user' ? gm('Tú','Toi','You') : 'A'}</div>
      <div className="bubble" dangerouslySetInnerHTML={{__html: m.text}}/>
    </div>
  );
}

/* ── Spotlight ── */
function WaSpotlight({ selector, label }) {
  const [rect, setRect] = useStateWA(null);
  useEffectWA(() => {
    if (!selector) { setRect(null); return; }
    function update() {
      const el = document.querySelector(selector);
      if (!el) { setRect(null); return; }
      const r = el.getBoundingClientRect();
      setRect({ top: r.top - 6, left: r.left - 6, width: r.width + 12, height: r.height + 12 });
    }
    update();
    window.addEventListener('resize', update);
    window.addEventListener('scroll', update, true);
    const interval = setInterval(update, 300);
    return () => {
      window.removeEventListener('resize', update);
      window.removeEventListener('scroll', update, true);
      clearInterval(interval);
    };
  }, [selector]);
  if (!rect) return null;
  return (
    <div className="spotlight">
      <div className="spot-ring" style={{ top: rect.top, left: rect.left, width: rect.width, height: rect.height }}>
        {label && <span className="spot-label" style={{ left: 0, top: 0 }}>{label}</span>}
      </div>
    </div>
  );
}

/* ── Main AimyWorkspace component ── */
function AimyWorkspace() {
  const [open, setOpen]         = useStateWA(true);
  const [stepIdx, setStepIdx]   = useStateWA(0);
  const [wsCreated, setWsCreated] = useStateWA(false);
  const [chatUsed, setChatUsed] = useStateWA(false);
  const [hasFiles, setHasFiles] = useStateWA(false);
  const [quizDone, setQuizDone] = useStateWA(false);
  const [quizPoints, setQuizPoints] = useStateWA(0);
  const [unread, setUnread]     = useStateWA(0);
  const bodyRef = useRefWA(null);

  /* Listen to workspace events */
  useEffectWA(() => {
    function onCreated()  { setWsCreated(true); }
    function onChatUsed() { setChatUsed(true); }
    function onHasFiles() { setHasFiles(true); }
    window.addEventListener('aimy:wsCreated',  onCreated);
    window.addEventListener('aimy:wsChatUsed', onChatUsed);
    window.addEventListener('aimy:wsHasFiles', onHasFiles);
    return () => {
      window.removeEventListener('aimy:wsCreated',  onCreated);
      window.removeEventListener('aimy:wsChatUsed', onChatUsed);
      window.removeEventListener('aimy:wsHasFiles', onHasFiles);
    };
  }, []);

  /* Auto-advance when gate condition is met */
  useEffectWA(() => {
    const step = WA_STEPS[stepIdx];
    if (!step || !step.gate) return;
    const ctx = { wsCreated, chatUsed, hasFiles, quizDone };
    if (step.gate(ctx)) {
      const t = setTimeout(() => {
        setStepIdx(i => Math.min(i + 1, WA_STEPS.length - 1));
      }, 700);
      return () => clearTimeout(t);
    }
  }, [wsCreated, chatUsed, hasFiles, quizDone, stepIdx]);

  /* Scroll to bottom on new messages */
  useEffectWA(() => {
    if (!open) return;
    requestAnimationFrame(() => {
      if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight + 200;
    });
  }, [stepIdx, wsCreated, chatUsed, hasFiles, quizDone, open]);

  const step       = WA_STEPS[stepIdx];
  const ctx        = { wsCreated, chatUsed, hasFiles, quizDone };
  const canContinue = !step.gate || step.gate(ctx);

  function next() {
    if (stepIdx < WA_STEPS.length - 1) {
      const newIdx = stepIdx + 1;
      setStepIdx(newIdx);
      if (!open) setUnread(u => u + 1);
      if (WA_STEPS[newIdx].id === 'done' && window.AIMakerProgress) {
        window.AIMakerProgress.complete('workspace', {
          badge: window.t('badge.workspace'),
          points: 75 + quizPoints,
        });
      }
    }
  }
  function back() { if (stepIdx > 0) setStepIdx(stepIdx - 1); }

  /* Minimized state — FAB button */
  if (!open) {
    return (
      <button className="aimy-fab" onClick={() => { setOpen(true); setUnread(0); }}>
        <span className="pulse"/>
        <svg width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
          <path d="M12 8V4H8"/><rect x="2" y="2" width="20" height="8" rx="2"/>
          <path d="M2 14h20"/><path d="M2 14v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6"/>
        </svg>
        {unread > 0 && <span className="nudge">{unread}</span>}
      </button>
    );
  }

  return (
    <>
      <WaSpotlight selector={step.spotlight} label={step.spotlightLabel}/>
      <div className="aimy-panel">
        {/* Header */}
        <div className="aimy-header">
          <div className="aimy-avatar">🤖</div>
          <div className="aimy-meta">
            <div className="name">DIAS</div>
            <div className="role">{window.t('aimy.role.workspace')}</div>
          </div>
          <button className="min" title={window.t('aimy.minimize')} onClick={() => setOpen(false)}>
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round">
              <line x1="5" y1="12" x2="19" y2="12"/>
            </svg>
          </button>
        </div>

        {/* Progress bar */}
        <div className="aimy-progress">
          <div style={{ width: step.progress + '%' }}/>
          <div className="aimy-progress-label">{step.progress}%</div>
        </div>

        {/* Messages */}
        <div className="aimy-body" ref={bodyRef}>
          {step.msgs.map((m, i) => {
            let slot = null;
            if (m.kind === 'wsstats')    slot = <WsStats/>;
            if (m.kind === 'wscode-tip') slot = <WsCodeTip/>;
            if (m.kind === 'quiz')       slot = <WaQuiz onDone={(p) => { setQuizPoints(p); setQuizDone(true); }}/>;
            if (m.kind === 'badge')      slot = <WaBadge points={quizPoints}/>;
            return <WaMessage key={step.id + '-' + i} m={m} slot={slot}/>;
          })}

          {step.gateHint && !canContinue && (
            <div style={{textAlign:'center',color:'var(--text-mute)',fontSize:12,padding:'4px 0 10px'}}>
              ⓘ {step.gateHint}
            </div>
          )}

          {step.quickReplies && (
            <div className="aimy-quick">
              {step.quickReplies.map((r, ri) => (
                <button key={ri} className="quick-chip" onClick={() => next()}>{r}</button>
              ))}
            </div>
          )}
        </div>

        {/* Navigation buttons */}
        <div className="aimy-actions">
          <button className="aimy-btn ghost" onClick={back} disabled={stepIdx === 0}>
            {window.t('btn.back')}
          </button>
          {stepIdx < WA_STEPS.length - 1 ? (
            <button className="aimy-btn primary" onClick={next} disabled={!canContinue}>
              {step.id === 'welcome' ? window.t('btn.start') + ' →' : window.t('btn.continue')}
            </button>
          ) : (
            <button className="aimy-btn primary" onClick={() => window.location.reload()}>
              {window.t('btn.repeat')}
            </button>
          )}
        </div>
      </div>
    </>
  );
}

window.AimyWorkspace = AimyWorkspace;
