// Interludio — «Atendé la agencia vos solo».
// Mini-juego arcade de 30 segundos: leads que se enfrían, reuniones que
// interrumpen, y un final que hace la cuenta. El dolor del ICP, jugable.

const GAME_MS = 30000;       // round length
const SLOTS = 6;             // board positions
const MEETINGS = [           // [start, duration] in ms from round start
  [7000, 2200],
  [16500, 2400],
  [24500, 2000],
];
const CHANNELS = ['wa', 'mail', 'ig', 'web'];

function fmtUSD(n, lang) {
  return 'USD ' + n.toLocaleString(lang === 'es' ? 'es-AR' : 'en-US');
}

function GameModal({ onClose }) {
  const [lang] = useLang();
  const C = window.FUSE_CONTENT.juego;

  const [phase, setPhase] = React.useState('ready'); // ready | playing | over
  const [leads, setLeads] = React.useState([]);      // {id, slot, born, life, name, brief, channel, ticket}
  const [ghosts, setGhosts] = React.useState([]);    // {id, slot, kind: 'hit'|'cold', label, until}
  const [billed, setBilled] = React.useState(0);
  const [lost, setLost] = React.useState(0);
  const [answered, setAnswered] = React.useState(0);
  const [cooled, setCooled] = React.useState(0);
  const [elapsed, setElapsed] = React.useState(0);
  const [meeting, setMeeting] = React.useState(-1);  // index into MEETINGS or -1
  const [isBest, setIsBest] = React.useState(false);

  const stateRef = React.useRef(null);

  const start = () => {
    stateRef.current = {
      t0: performance.now(),
      nextSpawn: 0,
      nextId: 1,
      leadIdx: Math.floor(Math.random() * C.leads[lang].length),
    };
    setLeads([]); setGhosts([]);
    setBilled(0); setLost(0); setAnswered(0); setCooled(0);
    setElapsed(0); setMeeting(-1); setIsBest(false);
    setPhase('playing');
  };

  // Main loop — spawn, expire, meetings, clock.
  React.useEffect(() => {
    if (phase !== 'playing') return;
    const iv = setInterval(() => {
      const S = stateRef.current;
      const now = performance.now();
      const t = now - S.t0;
      setElapsed(t);

      // meetings window
      let m = -1;
      MEETINGS.forEach(([at, dur], i) => { if (t >= at && t < at + dur) m = i; });
      setMeeting(m);

      // expire + spawn in one pass over leads state
      setLeads(prev => {
        let next = prev;

        // expirations
        const dead = prev.filter(l => now - l.born > l.life);
        if (dead.length) {
          next = prev.filter(l => now - l.born <= l.life);
          setLost(v => v + dead.reduce((a, l) => a + l.ticket, 0));
          setCooled(v => v + dead.length);
          setGhosts(g => [
            ...g,
            ...dead.map(l => ({ id: 'c' + l.id, slot: l.slot, kind: 'cold', label: '❄ ' + C.cold[lang], until: now + 900 })),
          ]);
        }

        // spawn — pace ramps up as the round advances
        if (t >= S.nextSpawn) {
          const taken = new Set(next.map(l => l.slot));
          const free = [];
          for (let i = 0; i < SLOTS; i++) if (!taken.has(i)) free.push(i);
          if (free.length) {
            const pool = C.leads[lang];
            const [name, brief] = pool[S.leadIdx % pool.length];
            S.leadIdx += 1;
            const lead = {
              id: S.nextId++,
              slot: free[Math.floor(Math.random() * free.length)],
              born: now,
              life: Math.max(2400, 4000 - t * 0.05),
              name, brief,
              channel: CHANNELS[Math.floor(Math.random() * CHANNELS.length)],
              ticket: (Math.floor(Math.random() * 18) + 8) * 100, // USD 800–2,500
            };
            next = next === prev ? [...prev, lead] : [...next, lead];
          }
          S.nextSpawn = t + Math.max(850, 1700 - t * 0.028);
        }
        return next;
      });

      // sweep ghosts
      setGhosts(g => (g.length ? g.filter(x => x.until > now) : g));

      if (t >= GAME_MS) setPhase('over');
    }, 90);
    return () => clearInterval(iv);
  }, [phase, lang]);

  // Round over — clear board, persist best score.
  React.useEffect(() => {
    if (phase !== 'over') return;
    setLeads([]); setMeeting(-1);
    try {
      const prev = parseInt(localStorage.getItem('fuse-game-best') || '0', 10);
      if (billed > prev) { localStorage.setItem('fuse-game-best', String(billed)); setIsBest(true); }
    } catch (e) { /* storage unavailable — score just isn't kept */ }
  }, [phase, billed]);

  // Esc closes, and the page behind doesn't scroll while playing.
  React.useEffect(() => {
    const onKey = (e) => { if (e.key === 'Escape') onClose(); };
    window.addEventListener('keydown', onKey);
    const prevOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    return () => { window.removeEventListener('keydown', onKey); document.body.style.overflow = prevOverflow; };
  }, [onClose]);

  const hit = (lead) => {
    if (meeting >= 0 || phase !== 'playing') return;
    setLeads(prev => prev.filter(l => l.id !== lead.id));
    setBilled(v => v + lead.ticket);
    setAnswered(v => v + 1);
    setGhosts(g => [...g, { id: 'h' + lead.id, slot: lead.slot, kind: 'hit', label: '✓ +' + fmtUSD(lead.ticket, lang), until: performance.now() + 800 }]);
  };

  const now = performance.now();
  const timeLeft = Math.max(0, Math.ceil((GAME_MS - elapsed) / 1000));
  const won = cooled === 0;

  return (
    <div className="game-overlay" role="dialog" aria-modal="true" aria-label={C.h2[lang].join('')} onClick={(e) => { if (e.target === e.currentTarget) onClose(); }}>
      <div className="game-card">
        <div className="game-top">
          <span className="kicker kicker-accent">{C.kicker[lang]}</span>
          <button className="game-close" onClick={onClose} aria-label={C.close[lang]}>✕</button>
        </div>

        {phase === 'ready' && (
          <div className="game-ready">
            <h3 className="g-title">{C.h2[lang][0]} <em>{C.h2[lang][1]}</em>{C.h2[lang][2]}</h3>
            <div className="g-rules">
              <span className="kicker">§ {C.howto_title[lang]}</span>
              <ol>
                {C.howto[lang].map((r, i) => <li key={i}>{r}</li>)}
              </ol>
            </div>
            <button className="btn btn-accent" onClick={start}>{C.start[lang]} <span style={{ fontFamily: 'var(--font-display)' }}>→</span></button>
          </div>
        )}

        {phase === 'playing' && (
          <>
            <div className="game-hud">
              <div className="hud-cell">
                <span className="hud-k">{C.hud_time[lang]}</span>
                <span className="hud-v mono-num">0:{String(timeLeft).padStart(2, '0')}</span>
              </div>
              <div className="hud-bar"><i style={{ width: `${Math.max(0, 100 - (elapsed / GAME_MS) * 100)}%` }} /></div>
              <div className="hud-cell">
                <span className="hud-k">{C.hud_billed[lang]}</span>
                <span className="hud-v good mono-num">{fmtUSD(billed, lang)}</span>
              </div>
              <div className="hud-cell">
                <span className="hud-k">{C.hud_lost[lang]}</span>
                <span className="hud-v bad mono-num">{fmtUSD(lost, lang)}</span>
              </div>
            </div>

            <div className="game-grid">
              {Array.from({ length: SLOTS }, (_, slot) => {
                const lead = leads.find(l => l.slot === slot);
                const ghost = ghosts.find(g => g.slot === slot);
                const fresh = lead ? Math.max(0, 1 - (now - lead.born) / lead.life) : 0;
                return (
                  <div key={slot} className="g-slot">
                    {lead && (
                      <button className="g-lead" data-ch={lead.channel} onClick={() => hit(lead)}>
                        <span className="gl-ch">{C.channels[lang][lead.channel]}</span>
                        <span className="gl-name">{lead.name} · <em>{lead.brief}</em></span>
                        <span className="gl-ticket">{fmtUSD(lead.ticket, lang)}</span>
                        <span className="gl-bar" data-heat={fresh > 0.55 ? 'hot' : fresh > 0.25 ? 'warm' : 'cold'}>
                          <i style={{ width: `${fresh * 100}%` }} />
                        </span>
                      </button>
                    )}
                    {ghost && <span className={`g-ghost ${ghost.kind}`}>{ghost.label}</span>}
                  </div>
                );
              })}

              {meeting >= 0 && (
                <div className="g-meeting">
                  <span className="gm-txt">{C.meeting_lines[lang][meeting % C.meeting_lines[lang].length]}</span>
                  <span className="gm-sub">↳ {C.meeting_sub[lang]}</span>
                </div>
              )}
            </div>
          </>
        )}

        {phase === 'over' && (
          <div className="game-over">
            <h3 className="g-title">{won ? C.over_title_won[lang] : C.over_title_lost[lang]}</h3>
            <div className="go-stats">
              <div className="go-cell">
                <span className="go-v good">{fmtUSD(billed, lang)}</span>
                <span className="go-k">{C.hud_billed[lang]} · {answered} {C.over_stats[lang][0]}</span>
              </div>
              <div className="go-cell">
                <span className="go-v bad">{fmtUSD(lost, lang)}</span>
                <span className="go-k">{C.hud_lost[lang]} · {cooled} {C.over_stats[lang][1]}</span>
              </div>
            </div>
            {isBest && <div className="go-best">★ {C.new_best[lang]}</div>}
            <p className="go-note">{won ? C.over_note_won[lang] : C.over_note_lost[lang]}</p>
            <div className="go-actions">
              <a href="#cta" className="btn btn-accent" onClick={onClose}>{C.over_cta[lang]} <span style={{ fontFamily: 'var(--font-display)' }}>→</span></a>
              <button className="btn btn-ghost" onClick={start}>{C.over_retry[lang]}</button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}

function Juego() {
  const [lang] = useLang();
  const C = window.FUSE_CONTENT.juego;
  const [open, setOpen] = React.useState(false);
  const [best, setBest] = React.useState(0);
  const [pre, emph, post] = C.h2[lang];

  React.useEffect(() => {
    if (open) return;
    try { setBest(parseInt(localStorage.getItem('fuse-game-best') || '0', 10)); } catch (e) { /* no storage */ }
  }, [open]);

  return (
    <section id="juego" className="section-tight divider-top" style={{ background: 'var(--paper-2)', overflow: 'hidden' }} data-screen-label="juego">
      <div className="container juego-band">
        <div className="reveal">
          <div className="kicker kicker-accent">{C.kicker[lang]}</div>
          <h2 className="h-section" style={{ marginTop: 14, maxWidth: '16ch' }}>
            {pre} <span className="mk-emph">{emph}</span>{post}
          </h2>
          <p style={{ marginTop: 16, fontSize: 15.5, lineHeight: 1.6, color: 'var(--ink-2)', maxWidth: '52ch' }}>{C.body[lang]}</p>
        </div>
        <div className="reveal juego-side" data-delay="2">
          <button className="juego-btn" onClick={() => setOpen(true)}>
            <span className="jb-icon" aria-hidden>▸</span>
            <span>{C.play[lang]}</span>
          </button>
          {best > 0 && <span className="kicker">↳ {C.best[lang]}: {fmtUSD(best, lang)}</span>}
        </div>
      </div>

      {open && <GameModal onClose={() => setOpen(false)} />}
    </section>
  );
}

window.Juego = Juego;
