// Game shell: progress map, header (timer, stars, attempts), activity host.
// Exposes <MateAventura theme={key} embedded /> as the entry point.

// (Hooks are accessed via React.useState etc. to avoid collision with other Babel files.)

// ---------- 8 Activities metadata ----------
const ACTIVITY_LIBRARY = {
  memoria:     { id: "memoria",    title: "Memoria",      subtitle: "Empareja sumas iguales",             icon: "🧠", kind: "memory",    type: "Memoria",        x: 12, y: 78 },
  asociacion:  { id: "asociacion", title: "Asociación",   subtitle: "Une cada cuenta con su resultado",   icon: "🔗", kind: "match",     type: "Asociación",     x: 28, y: 60 },
  ordenar:     { id: "ordenar",    title: "Ordenar",      subtitle: "Coloca los números en orden",        icon: "📊", kind: "order",     type: "Ordenar",        x: 44, y: 75 },
  completar:   { id: "completar",  title: "Completar",    subtitle: "Rellena los huecos que faltan",      icon: "✏️", kind: "fill",      type: "Completar",      x: 58, y: 50 },
  sopa_letras: { id: "sopa",       title: "Sopa de letras",subtitle: "Encuentra los resultados",           icon: "🔍", kind: "wordsearch",type: "Sopa de letras", x: 72, y: 65 },
  crucigrama:  { id: "crucigrama", title: "Crucigrama",   subtitle: "Resuelve el crucigrama numérico",    icon: "🧩", kind: "crossword", type: "Crucigrama",     x: 36, y: 35 },
  rompecabezas:{ id: "puzzle",     title: "Rompecabezas", subtitle: "Reconstruye la imagen",              icon: "🖼️", kind: "puzzle",    type: "Rompecabezas",   x: 64, y: 25 },
  calculo:     { id: "calculo",    title: "Cálculo",      subtitle: "Escribe el resultado correcto",      icon: "⌨️", kind: "answer",    type: "Cálculo",        x: 86, y: 40 },
};

const ACTIVITY_ORDER = [
  "memoria",
  "asociacion",
  "ordenar",
  "completar",
  "sopa_letras",
  "crucigrama",
  "rompecabezas",
  "calculo",
];

function normalizeTipo(tipo) {
  const aliases = {
    asociacion_simple: "asociacion",
    asociacion_compleja: "asociacion",
    ordenar_elementos: "ordenar",
    completar_textos: "completar",
    rellenar_agujeros: "completar",
    respuesta_escrita: "calculo",
    puzzle_doble: "rompecabezas",
    puzzle_intercambio: "rompecabezas",
    puzzle_agujero: "rompecabezas",
  };
  return aliases[tipo] || tipo;
}

function buildActivities(gameData) {
  const ejercicios = Array.isArray(gameData?.ejercicios) ? gameData.ejercicios : [];
  const byTipo = {};

  ejercicios.forEach((e) => {
    const t = normalizeTipo(e?.tipo);
    if (!ACTIVITY_LIBRARY[t]) return;
    if (!byTipo[t]) byTipo[t] = [];
    byTipo[t].push(e);
  });

  const activeTypes = ejercicios.length > 0
    ? ACTIVITY_ORDER.filter((t) => byTipo[t]?.length)
    : ACTIVITY_ORDER;

  return activeTypes.map((tipo) => {
    const base = ACTIVITY_LIBRARY[tipo];
    const ex = byTipo[tipo]?.[0];
    return {
      ...base,
      title: ex?.titulo || base.title,
      subtitle: ex?.instrucciones || base.subtitle,
      data: ex?.contenido || null,
    };
  });
}

// ---------- Local storage for progress (per theme) ----------
function useProgress(themeKey, progressKey) {
  const scope = progressKey || themeKey;
  const key = `mateaventura:progress:${scope}`;
  const [progress, setProgress] = React.useState(() => {
    try { return JSON.parse(localStorage.getItem(key)) || {}; } catch { return {}; }
  });
  React.useEffect(() => { localStorage.setItem(key, JSON.stringify(progress)); }, [progress, key]);
  const complete = React.useCallback((id, stars) => {
    setProgress(p => ({ ...p, [id]: { stars: Math.max(stars, p[id]?.stars || 0), done: true } }));
  }, []);
  const reset = () => setProgress({});
  return [progress, complete, reset];
}

// ---------- Star display ----------
function Stars({ count, total = 3, size = 20, color }) {
  return (
    <span style={{ display: "inline-flex", gap: 2, alignItems: "center" }}>
      {Array.from({ length: total }).map((_, i) => (
        <Star key={i} filled={i < count} size={size} color={color} />
      ))}
    </span>
  );
}
function Star({ filled, size, color }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" style={{ filter: filled ? `drop-shadow(0 0 4px ${color}aa)` : "none" }}>
      <path d="M12 2l2.9 6.9 7.1.6-5.4 4.7 1.7 7L12 17.8 5.7 21.2l1.7-7L2 9.5l7.1-.6L12 2z"
        fill={filled ? color : "transparent"}
        stroke={filled ? "rgba(0,0,0,0.3)" : color}
        strokeWidth="1.5"
        strokeLinejoin="round" />
    </svg>
  );
}

// ---------- Header ----------
function Header({ theme, title, subtitle, totalCompleted, totalExercises, scorePercentage, onBack, onReset, attempts, timer, onToggleSound, soundOn }) {
  return (
    <div className="ma-header">
      <div className="ma-header-left">
        {onBack && (
          <button className="ma-btn ma-btn-ghost" onClick={onBack}>← Mapa</button>
        )}
        <div>
          <div className="ma-title">{title}</div>
          {subtitle && <div className="ma-subtitle">{subtitle}</div>}
        </div>
      </div>
      <div className="ma-header-right">
        {timer != null && (
          <div className="ma-pill" title="Tiempo">⏱ {formatTime(timer)}</div>
        )}
        {attempts != null && (
          <div className="ma-pill" title="Intentos restantes">❤ {attempts}</div>
        )}
        <div className="ma-pill ma-pill-stars" title="Progreso">
          <Stars count={totalCompleted} total={totalExercises} size={16} color={theme.star} />
          <span style={{ marginLeft: 6, fontWeight: 700 }}>{totalCompleted}/{totalExercises}</span>
        </div>
        <div className="ma-pill ma-pill-score" title="Calificación Total">
          <span style={{ marginRight: 6 }}>📊</span>
          <span style={{ fontWeight: 800, color: theme.star }}>{scorePercentage}%</span>
        </div>
        <button className="ma-btn ma-btn-ghost ma-btn-icon" onClick={onToggleSound} title={soundOn ? "Silenciar" : "Activar sonido"}>
          {soundOn ? "🔊" : "🔈"}
        </button>
        {onReset && (
          <button className="ma-btn ma-btn-ghost ma-btn-icon" onClick={onReset} title="Reiniciar progreso">↻</button>
        )}
      </div>
    </div>
  );
}
function formatTime(s) {
  const m = Math.floor(s / 60), r = s % 60;
  return `${m}:${String(r).padStart(2,"0")}`;
}

// ---------- Adventure Map ----------
function AdventureMap({ theme, progress, onPick, themeKey, activities }) {
  const path = React.useMemo(() => {
    // Build a smooth curve through activity points
    return activities.map(a => `${a.x},${a.y}`).join(" L ");
  }, [activities]);
  const isUnlocked = (i) => i === 0 || progress[activities[i-1].id]?.done;

  return (
    <div className="ma-map">
      <MapBackground themeKey={themeKey} />
      <svg className="ma-map-svg" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path d={`M ${path}`} fill="none"
          stroke={theme.flourish === "stars" ? "rgba(255,255,255,0.7)" : theme.inkSoft}
          strokeWidth="0.6" strokeDasharray="1.2 1.2" strokeLinecap="round" />
      </svg>
      {activities.map((a, i) => {
        const unlocked = isUnlocked(i);
        const stars = progress[a.id]?.stars || 0;
        const done = progress[a.id]?.done;
        return (
          <button
            key={a.id}
            className={`ma-node ${unlocked ? "" : "ma-node-locked"} ${done ? "ma-node-done" : ""}`}
            style={{ left: `${a.x}%`, top: `${a.y}%`, animationDelay: `${i * 60}ms` }}
            onClick={() => unlocked && onPick(a)}
            disabled={!unlocked}
          >
            <div className="ma-node-bubble">
              <div className="ma-node-icon">{unlocked ? a.icon : "🔒"}</div>
              <div className="ma-node-num">{i + 1}</div>
            </div>
            <div className="ma-node-label">
              <div className="ma-node-title">{a.title}</div>
              <div className="ma-node-type">{a.type}</div>
              {done && <Stars count={stars} total={3} size={12} color={theme.star} />}
            </div>
          </button>
        );
      })}
    </div>
  );
}

function MapBackground({ themeKey }) {
  // Decorative scenery per theme — abstract hills/clouds, no copyrighted shapes
  if (themeKey === "retro2000") {
    return (
      <svg className="ma-map-bg" viewBox="0 0 100 100" preserveAspectRatio="none">
        <ellipse cx="20" cy="95" rx="40" ry="18" fill="#7FB800" opacity="0.45"/>
        <ellipse cx="75" cy="92" rx="45" ry="15" fill="#7FB800" opacity="0.55"/>
        <ellipse cx="50" cy="100" rx="80" ry="12" fill="#5a8a00" opacity="0.6"/>
        <circle cx="15" cy="15" r="8" fill="#fff" opacity="0.6"/>
        <circle cx="22" cy="13" r="6" fill="#fff" opacity="0.6"/>
        <circle cx="80" cy="10" r="5" fill="#fff" opacity="0.5"/>
      </svg>
    );
  }
  if (themeKey === "retroClean") {
    return (
      <svg className="ma-map-bg" viewBox="0 0 100 100" preserveAspectRatio="none">
        <path d="M0,85 Q25,72 50,82 T100,80 L100,100 L0,100 Z" fill="#C8B89A" opacity="0.5"/>
        <path d="M0,92 Q30,85 60,90 T100,88 L100,100 L0,100 Z" fill="#9B8C70" opacity="0.4"/>
        {Array.from({length: 20}).map((_,i)=>(
          <circle key={i} cx={(i*53)%100} cy={(i*37)%70+5} r="0.4" fill="#7c6e57" opacity="0.3"/>
        ))}
      </svg>
    );
  }
  // modernPlay
  return (
    <svg className="ma-map-bg" viewBox="0 0 100 100" preserveAspectRatio="none">
      {Array.from({length: 30}).map((_,i)=>{
        const x=(i*17)%100, y=(i*23)%100, r=(i%4)*0.3+0.2;
        return <circle key={i} cx={x} cy={y} r={r} fill="#fff" opacity={0.3+(i%3)*0.2}/>;
      })}
      <ellipse cx="20" cy="95" rx="35" ry="10" fill="#FF4B8B" opacity="0.2"/>
      <ellipse cx="80" cy="95" rx="40" ry="12" fill="#5BE0E8" opacity="0.2"/>
    </svg>
  );
}

// ---------- Celebration overlay ----------
function Celebration({ stars, theme, onClose, message }) {
  React.useEffect(() => { window.SFX && window.SFX.win(); }, []);
  return (
    <div className="ma-overlay" onClick={onClose}>
      <div className="ma-celebrate" onClick={e=>e.stopPropagation()}>
        <div className="ma-celebrate-burst" aria-hidden>
          {Array.from({length:18}).map((_,i)=>(
            <span key={i} className="ma-confetti" style={{
              left: `${(i*53)%100}%`,
              animationDelay: `${i*40}ms`,
              background: [theme.primary, theme.secondary, theme.accent, theme.star][i%4],
            }}/>
          ))}
        </div>
        <div className="ma-celebrate-title">¡Genial!</div>
        <div className="ma-celebrate-stars">
          <Stars count={stars} total={3} size={56} color={theme.star} />
        </div>
        <div className="ma-celebrate-msg">{message}</div>
        <button className="ma-btn ma-btn-primary ma-btn-lg" onClick={onClose}>Continuar →</button>
      </div>
    </div>
  );
}

// ---------- Failure overlay ----------
function FailScreen({ theme, onRetry, onBack, message }) {
  React.useEffect(() => { window.SFX && window.SFX.lose(); }, []);
  return (
    <div className="ma-overlay">
      <div className="ma-celebrate">
        <div style={{fontSize: 80}}>💔</div>
        <div className="ma-celebrate-title" style={{color: theme.danger}}>¡Inténtalo otra vez!</div>
        <div className="ma-celebrate-msg">{message}</div>
        <div style={{display:"flex", gap:12, marginTop:16}}>
          <button className="ma-btn ma-btn-ghost" onClick={onBack}>Mapa</button>
          <button className="ma-btn ma-btn-primary" onClick={onRetry}>Reintentar</button>
        </div>
      </div>
    </div>
  );
}

// ---------- Main ----------
function MateAventura({ themeKey: initialKey = "retro2000", embedded = false, tweaks: extTweaks, gameData = null, progressKey = null }) {
  const tweaks = extTweaks || {
    theme: initialKey,
    difficulty: "media",
    speed: 1,
    sound: true,
    fontScale: 1,
  };
  const themeKey = tweaks.theme || initialKey;
  const theme = window.THEMES[themeKey];
  const activities = React.useMemo(() => buildActivities(gameData), [gameData]);
  const [progress, complete, reset] = useProgress(themeKey, progressKey);
  const [active, setActive] = React.useState(null);
  const [result, setResult] = React.useState(null); // {stars, message} | "fail"
  const [soundOn, setSoundOn] = React.useState(true);
  React.useEffect(() => { window.SOUND_ENABLED = soundOn && (tweaks.sound !== false); }, [soundOn, tweaks.sound]);

  const totalCompleted = activities.filter(a => progress[a.id]?.done).length;
  const totalExercises = activities.length;
  const totalStars = activities.reduce((s, a) => s + (progress[a.id]?.stars || 0), 0);
  const maxPossibleStars = activities.length * 3;
  const scorePercentage = maxPossibleStars > 0 ? Math.round((totalStars / maxPossibleStars) * 100) : 0;

  const cssVars = {
    "--bg": theme.bg, "--surface": theme.surface, "--panel": theme.panel,
    "--ink": theme.ink, "--ink-soft": theme.inkSoft,
    "--primary": theme.primary, "--primary-ink": theme.primaryInk,
    "--secondary": theme.secondary, "--accent": theme.accent,
    "--danger": theme.danger, "--success": theme.success, "--star": theme.star,
    "--font-display": theme.fontDisplay, "--font-body": theme.fontBody,
    "--radius": theme.radius, "--radius-sm": theme.radiusSm,
    "--card-shadow": theme.cardShadow, "--node-shadow": theme.nodeShadow,
    "--font-scale": tweaks.fontScale || 1,
    "--speed": tweaks.speed || 1,
    "--btn-bevel-bg": theme.btnBevel,
    background: theme.bgPattern,
  };

  return (
    <div className={`ma-root ma-theme-${themeKey} ${embedded ? "ma-embedded" : ""}`} style={cssVars}>
      <Header
        theme={theme}
        title={active ? active.title : "MateAventura"}
        subtitle={active ? active.subtitle : "Mapa del aventurero"}
        totalCompleted={totalCompleted}
        totalExercises={totalExercises}
        scorePercentage={scorePercentage}
        onBack={active ? () => setActive(null) : null}
        onReset={!active ? () => { if(confirm("¿Reiniciar progreso?")) reset(); } : null}
        onToggleSound={() => setSoundOn(s => !s)}
        soundOn={soundOn}
      />
      <div className="ma-stage">
        {!active && (
          <AdventureMap theme={theme} themeKey={themeKey} progress={progress} activities={activities} onPick={(a) => { window.SFX && window.SFX.click(); setActive(a); }} />
        )}
        {active && (
          <ActivityHost
            key={active.id + "-" + (result === null ? "play" : "x")}
            activity={active}
            theme={theme}
            tweaks={tweaks}
            onWin={(stars, message) => {
              complete(active.id, stars);
              setResult({ stars, message });
            }}
            onFail={(message) => setResult({ fail: true, message })}
          />
        )}
      </div>
      {result && !result.fail && (
        <Celebration stars={result.stars} theme={theme} message={result.message}
          onClose={() => { setResult(null); setActive(null); }}/>
      )}
      {result && result.fail && (
        <FailScreen theme={theme} message={result.message}
          onBack={() => { setResult(null); setActive(null); }}
          onRetry={() => { setResult(null); /* remount via key */ }}/>
      )}
    </div>
  );
}

window.MateAventura = MateAventura;
window.ACTIVITIES = ACTIVITY_ORDER.map((t) => ACTIVITY_LIBRARY[t]);
window.Stars = Stars;
