// Chapter scroller — sticky TOC sidebar with goal titles; verbatim body text per goal.

// Render lede with bolded keywords (1-3 phrases per theme).
function boldLede(text, keywords) {
  if (!keywords || !keywords.length) return text;
  // Build a regex that matches any of the keywords; case-insensitive.
  const escape = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
  const re = new RegExp('(' + keywords.map(escape).join('|') + ')', 'i');
  // Split by sequential matches.
  const parts = [];
  let rest = text;
  let key = 0;
  while (rest.length) {
    const m = rest.match(re);
    if (!m) { parts.push(rest); break; }
    if (m.index > 0) parts.push(rest.slice(0, m.index));
    parts.push(<strong key={key++}>{m[0]}</strong>);
    rest = rest.slice(m.index + m[0].length);
  }
  return parts;
}

const ChapterScroller = () => {
  const data = window.TUTKE_DATA;
  const [openGoals, setOpenGoals] = React.useState({});

  const goalsByTheme = React.useMemo(() => {
    const m = {};
    data.goals.forEach(g => { (m[g.theme] = m[g.theme] || []).push(g); });
    return m;
  }, [data.goals]);

  React.useEffect(() => {
    if (!window.gsap || !window.ScrollTrigger) return;
    gsap.registerPlugin(ScrollTrigger);
    const ctx = gsap.context(() => {
      gsap.utils.toArray('.chapter').forEach((el) => {
        // Sequence per chapter: eyebrow+title → tagline → lede → goals (stagger)
        const tl = gsap.timeline({
          scrollTrigger: {
            trigger: el,
            start: 'top 85%',
            once: true,
            // refresh after layout settles so triggers compute correctly
          }
        });
        const eyebrow = el.querySelector('.chapter-eyebrow');
        const title   = el.querySelector('.chapter-title');
        const tag     = el.querySelector('.chapter-tag');
        const lede    = el.querySelector('.chapter-lede');
        const goals   = el.querySelectorAll('.goals-list > .goal');
        const back    = el.querySelector('.chapter-back');

        const fromOpts = { y: 18, opacity: 0, ease: 'power2.out' };
        if (eyebrow || title) {
          tl.from([eyebrow, title].filter(Boolean), { ...fromOpts, duration: 0.36, stagger: 0.05 });
        }
        if (tag)  tl.from(tag,  { ...fromOpts, duration: 0.3 }, '+=0.03');
        if (lede) tl.from(lede, { ...fromOpts, duration: 0.36 }, '+=0.06');
        if (goals.length) {
          tl.from(goals, { ...fromOpts, duration: 0.3, stagger: 0.11 }, '+=0.09');
        }
        if (back) tl.from(back, { ...fromOpts, duration: 0.24 }, '+=0.06');
      });
      // Recalculate after fonts/layout settle
      setTimeout(() => ScrollTrigger.refresh(), 200);
    });
    return () => ctx.revert();
  }, []);

  const toggleGoal = (id) => {
    setOpenGoals(prev => ({ ...prev, [id]: !prev[id] }));
  };

  const handleShare = (id) => {
    const url = window.location.origin + window.location.pathname + '#suositus-' + id;
    if (navigator.clipboard) {
      navigator.clipboard.writeText(url).then(() => {
        alert('Linkki kopioitu: ' + url);
      });
    }
  };

  const scrollToSuositus = (id) => {
    const el = document.getElementById('suositus-' + id);
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
    setOpenGoals(prev => ({ ...prev, [id]: true }));
  };

  const backToMap = () => {
    const el = document.querySelector('.map');
    if (el) el.scrollIntoView({ behavior: 'smooth', block: 'start' });
  };

  return (
    <section className="chapters">
      {data.themes.map((t, ti) => {
        const accent = window.themeAccentRGB[t.id];
        const goals = goalsByTheme[t.id] || [];
        return (
          <article
            key={t.id}
            id={'chapter-' + t.id}
            className="chapter"
            data-screen-label={`05.${ti+1} ${t.title}`}
            style={{ '--accent': accent }}
          >
            <div className="chapter-grid">
              <aside className="chapter-side">
                <div className="chapter-side-id">§ {t.n}</div>
                <div className="chapter-side-name">{t.title}</div>
                <div className="chapter-side-rule"></div>
                <div className="chapter-side-toc-label">Suositukset</div>
                <ol className="chapter-side-toc">
                  {goals.map(g => (
                    <li key={g.id}>
                      <button onClick={() => scrollToSuositus(g.id)}>
                        <span className="toc-num">№ {g.id}</span>
                        <span className="toc-title">{g.title}</span>
                      </button>
                    </li>
                  ))}
                </ol>
              </aside>

              <div className="chapter-body">
                <div className="chapter-eyebrow">Aihepiiri {t.n} / 06</div>
                <h2 className="chapter-title">{t.title}</h2>
                <div className="chapter-tag">{t.tagline}</div>
                <p className="chapter-lede">{boldLede(t.lede, t.ledeBold)}</p>

                <div className="goals-list">
                  {goals.map(g => {
                    const isOpen = !!openGoals[g.id];
                    return (
                      <div key={g.id} id={'suositus-' + g.id} className={"goal" + (isOpen ? " is-open" : "")}>
                        <button
                          className="goal-head goal-head-toggle"
                          onClick={() => toggleGoal(g.id)}
                          aria-expanded={isOpen}
                        >
                          <div className="goal-num">№ {g.id}</div>
                          <h3 className="goal-title">{g.title}</h3>
                        </button>

                        <div className="goal-meta">
                          <div className="ministry-chips">
                            {g.ministries.map(m => (
                              <span key={m} className="ministry-chip">{m}</span>
                            ))}
                          </div>
                          {!isOpen && (
                            <button className="goal-readmore" onClick={() => toggleGoal(g.id)}>
                              Lue lisää ↓
                            </button>
                          )}
                        </div>

                        {isOpen && (
                          <div className="goal-expand">
                            <div className="goal-body-single">
                              <p>{g.body}</p>
                            </div>
                            {g.cta && (
                              <div className="goal-cta">
                                <div className="goal-cta-card">
                                  <div>
                                    <div className="lbl">Allekirjoita kansainvälinen adressi</div>
                                    <div className="ttl">{g.cta.label}</div>
                                  </div>
                                  <a href={g.cta.url} target="_blank" rel="noopener">Allekirjoita →</a>
                                </div>
                              </div>
                            )}
                            <div className="goal-foot">
                              <button className="goal-readmore goal-readmore-close" onClick={() => toggleGoal(g.id)}>
                                ↑ Sulje
                              </button>
                            </div>
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>

                <div className="chapter-back">
                  <button className="chapter-back-btn" onClick={backToMap}>
                    ↑ Takaisin yleiskuvaan
                  </button>
                </div>
              </div>
            </div>
          </article>
        );
      })}
    </section>
  );
};

window.ChapterScroller = ChapterScroller;
