// ------------------------------------------------------------------
// Blog post App — shared by /blog/<slug>.html (Faz 3 static pages) and
// the legacy /blog-post.html?slug= entry point.
//
// Slug source: window.__POST_SLUG__ (baked into the static /blog/<slug>.html
// wrapper) takes precedence; falls back to the ?slug= query param.
//
// When __POST_SLUG__ is set, the page's <head> already carries the correct
// title / description / canonical / OG / JSON-LD (written by gen-blog.mjs),
// so the dynamic head-mutation effect is skipped to avoid duplicates. The
// legacy ?slug= path still injects them at runtime.
// ------------------------------------------------------------------

const GLOSSARY = {
  blueprint: {
    title: 'Blueprint — neden "mavi baskı"?',
    body: [
      '1842 — İngiliz bilim insanı Sir John Herschel’in keşfettiği siyanotip yöntemi: ışığa duyarlı kimyasalla kaplı kağıt, üzerine konan şeffaf orijinal planla birlikte güneşe tutuluyordu.',
      'Işık görmeyen çizgiler beyaz, gören yüzeyler Prusya mavisi kalıyordu — fotokopi öncesi mimari planı çoğaltmanın tek hızlı yolu.',
      'Bugün kağıt mavi değil. Ama kelime, herhangi bir sistemin mimari planı için yaşamaya devam ediyor: yazılımda, stratejide, hatta DNA için.',
    ],
  },
  ciso: {
    title: 'CISO — Chief Information Security Officer',
    body: [
      'Bir kurumun bilgi güvenliği, siber güvenlik ve veri koruma stratejilerinden sorumlu en üst düzey yönetici. Türkçesi: Bilgi Güvenliği Baş Sorumlusu.',
      'Teknik ekipler ile yönetim kurulu (C-Level) arasında köprüdür. Görevi sadece yangın söndürmek değil — şirketin iş hedeflerini siber riskleri yöneterek korumaktır.',
      'Sorumluluk alanı: BGYS (Bilgi Güvenliği Yönetim Sistemi) kurulumu, KVKK/GDPR uyumluluğu, siber olaylara müdahale.',
    ],
  },
};

// Find glossary terms in plain text → return array of strings & JSX buttons
function highlight(text, openTerm) {
  if (typeof text !== 'string') return text;
  const terms = Object.keys(GLOSSARY);
  if (terms.length === 0) return text;
  const re = new RegExp(`(${terms.join('|')})`, 'gi');
  const parts = text.split(re);
  return parts.map((p, i) => {
    const key = p && p.toLowerCase();
    if (GLOSSARY[key]) {
      return (
        <button
          key={i}
          type="button"
          className="rar-gloss"
          onClick={(e) => { e.stopPropagation(); openTerm(key, e.currentTarget); }}
        >{p}</button>
      );
    }
    return p;
  });
}

function Postit({ term, anchor, onClose }) {
  const ref = React.useRef(null);
  const [pos, setPos] = React.useState(null);

  React.useLayoutEffect(() => {
    if (!anchor) return;
    const isMobile = window.matchMedia('(max-width: 640px)').matches;
    if (isMobile) { setPos({ mobile: true }); return; }
    const rect = anchor.getBoundingClientRect();
    const popW = 320;
    let left = rect.left + rect.width / 2 - popW / 2;
    left = Math.max(12, Math.min(left, window.innerWidth - popW - 12));
    const spaceBelow = window.innerHeight - rect.bottom;
    const placeAbove = spaceBelow < 260 && rect.top > 260;
    const top = placeAbove
      ? rect.top + window.scrollY - 16
      : rect.bottom + window.scrollY + 10;
    setPos({ top, left, placeAbove });
  }, [anchor]);

  React.useEffect(() => {
    const handle = (e) => {
      if (!ref.current) return;
      if (ref.current.contains(e.target)) return;
      if (anchor && anchor.contains(e.target)) return;
      onClose();
    };
    const esc = (e) => { if (e.key === 'Escape') onClose(); };
    document.addEventListener('mousedown', handle);
    document.addEventListener('touchstart', handle, { passive: true });
    document.addEventListener('keydown', esc);
    return () => {
      document.removeEventListener('mousedown', handle);
      document.removeEventListener('touchstart', handle);
      document.removeEventListener('keydown', esc);
    };
  }, [anchor, onClose]);

  if (!pos) return null;
  const style = pos.mobile
    ? {}
    : { top: pos.top, left: pos.left, transform: pos.placeAbove ? 'translateY(-100%) rotate(-1.4deg)' : 'rotate(-1.4deg)' };
  const cls = `rar-postit ${pos.mobile ? 'rar-postit--mobile' : ''}`;
  return (
    <div ref={ref} className={cls} style={style} role="dialog" aria-label={term.title}>
      <span className="rar-postit__tape" aria-hidden="true" />
      <button className="rar-postit__close" onClick={onClose} aria-label="Kapat">×</button>
      <div className="rar-postit__title">{term.title}</div>
      {term.body.map((p, i) => <p key={i} className="rar-postit__p">{p}</p>)}
    </div>
  );
}

function ArticleBody({ body, openTerm }) {
  return (
    <div className="rar-article__body">
      {body.map((block, i) => {
        if (block.type === 'h2')   return <h2 key={i} className="rar-article__h2">{highlight(block.text, openTerm)}</h2>;
        if (block.type === 'p')    return <p  key={i} className="rar-article__p">{highlight(block.text, openTerm)}</p>;
        if (block.type === 'pull') return (
          <figure key={i} className="rar-article__pull">
            <span className="rar-article__pull-mark" aria-hidden="true">"</span>
            <blockquote className="rar-editorial"><em>{highlight(block.text, openTerm)}</em></blockquote>
          </figure>
        );
        if (block.type === 'list') return (
          <ul key={i} className="rar-article__list">
            {block.items.map((it, j) => <li key={j}>{highlight(it, openTerm)}</li>)}
          </ul>
        );
        if (block.type === 'callout') return (
          <aside key={i} className="rar-article__callout">
            <div className="rar-eyebrow rar-article__callout-eyebrow">{block.title}</div>
            <p>{highlight(block.text, openTerm)}</p>
          </aside>
        );
        return null;
      })}
    </div>
  );
}

function NotFound() {
  return (
    <section className="rar-subhero">
      <div className="rar-container">
        <div className="rar-subhero__inner">
          <div className="rar-eyebrow">404 · BULUNAMADI</div>
          <h1 className="rar-subhero__title">Bu yazı henüz <em>elementlenmedi.</em></h1>
          <p className="rar-subhero__lede">Aradığınız blog yazısı kaldırılmış ya da adresi değişmiş olabilir.</p>
          <div style={{ marginTop: 24 }}>
            <Button as="a" href="/blog.html" variant="primary" size="lg" rightIcon={<Arrow/>}>Tüm yazılara dön</Button>
          </div>
        </div>
      </div>
    </section>
  );
}

function App() {
  const params = new URLSearchParams(window.location.search);
  const slug = window.__POST_SLUG__ || params.get('slug');
  const post = POSTS.find(p => p.slug === slug);

  const [active, setActive] = React.useState(null); // { key, anchor }
  const openTerm = React.useCallback((key, anchor) => setActive({ key, anchor }), []);
  const closeTerm = React.useCallback(() => setActive(null), []);

  if (!post) {
    return (
      <>
        <Nav activeKey="blog" overHero={false} />
        <NotFound />
        <Footer />
      </>
    );
  }

  const related = POSTS.filter(p => p.slug !== post.slug).slice(0, 3);

  React.useEffect(() => {
    // /blog/<slug>.html pages already carry a static <head> (title, meta,
    // canonical, OG, JSON-LD) from gen-blog.mjs — don't duplicate it.
    if (window.__POST_SLUG__) return;

    document.title = `${post.title} — Raryum`;

    const url = `https://raryum.com/blog/${post.slug}.html`;
    const setMeta = (selector, attr, value) => {
      let el = document.head.querySelector(selector);
      if (!el) {
        el = document.createElement('meta');
        const [key, val] = selector.replace('meta[', '').replace(']', '').split('=');
        el.setAttribute(key, val.replace(/"/g, ''));
        document.head.appendChild(el);
      }
      el.setAttribute(attr, value);
    };
    const setLink = (rel, href) => {
      let el = document.head.querySelector(`link[rel="${rel}"]`);
      if (!el) {
        el = document.createElement('link');
        el.setAttribute('rel', rel);
        document.head.appendChild(el);
      }
      el.setAttribute('href', href);
    };

    setMeta('meta[name="description"]', 'content', post.lede);
    setLink('canonical', url);
    setMeta('meta[property="og:title"]', 'content', `${post.title} — Raryum`);
    setMeta('meta[property="og:description"]', 'content', post.lede);
    setMeta('meta[property="og:url"]', 'content', url);
    setMeta('meta[name="twitter:title"]', 'content', `${post.title} — Raryum`);
    setMeta('meta[name="twitter:description"]', 'content', post.lede);

    // JSON-LD: BlogPosting
    const old = document.getElementById('rar-jsonld-post');
    if (old) old.remove();
    const ld = document.createElement('script');
    ld.type = 'application/ld+json';
    ld.id = 'rar-jsonld-post';
    ld.textContent = JSON.stringify({
      '@context': 'https://schema.org',
      '@type': 'BlogPosting',
      'headline': post.title,
      'description': post.lede,
      'datePublished': post.date,
      'inLanguage': 'tr-TR',
      'url': url,
      'mainEntityOfPage': { '@type': 'WebPage', '@id': url },
      'author': { '@type': 'Organization', 'name': 'Raryum', 'url': 'https://raryum.com/' },
      'publisher': {
        '@type': 'Organization',
        'name': 'Raryum',
        'logo': { '@type': 'ImageObject', 'url': 'https://raryum.com/assets/logo/raryum-tile.svg' }
      },
      'articleSection': post.category,
      'timeRequired': `PT${post.minutes}M`,
    });
    document.head.appendChild(ld);
  }, [post.title, post.slug, post.lede, post.date, post.category, post.minutes]);

  return (
    <>
      <Nav activeKey="blog" overHero={false} />

      <article className="rar-article">
        <div className="rar-article__hero">
          <div className="rar-article__hero-art" aria-hidden="true">
            <BlogCover slug={post.slug} accent={post.accent} accent2={post.accent2} />
          </div>
          <div className="rar-container rar-article__hero-inner">
            <div className="rar-eyebrow">{post.category}</div>
            <h1 className="rar-article__title">{highlight(post.title, openTerm)}</h1>
            <p className="rar-article__lede">{highlight(post.lede, openTerm)}</p>
            <div className="rar-meta rar-article__meta">
              {post.date} · {post.minutes} dk okuma · RARYUM EDİTÖRYAL
            </div>
          </div>
        </div>

        <div className="rar-container rar-article__container">
          <Reveal>
            <ArticleBody body={post.body} openTerm={openTerm} />
          </Reveal>

          <hr className="rar-rule" style={{ margin: '64px 0 32px' }} />

          <div className="rar-article__footer">
            <div className="rar-eyebrow">YAZARIN ALTI</div>
            <p className="rar-editorial rar-article__sign"><em>Bütünün tek elementi.</em></p>
            <div className="rar-article__cta">
              <Button as="a" href="/iletisim.html" variant="spark" size="lg" rightIcon={<Arrow/>}>Bu konuyu konuşalım</Button>
              <Button as="a" href="/blog.html" variant="ghost" size="lg">Tüm yazılar</Button>
            </div>
          </div>
        </div>
      </article>

      <section className="rar-section rar-related">
        <div className="rar-container">
          <SectionHeader eyebrow="DAHA FAZLA · İLGİLİ YAZILAR" title="Aynı çizgide, başka açılar." />
          <div className="rar-grid-3">
            {related.map((p, i) => (
              <Reveal key={p.slug} delay={i * 60}>
                <BlogCard post={p} />
              </Reveal>
            ))}
          </div>
        </div>
      </section>

      <Footer />

      {active && (
        <Postit term={GLOSSARY[active.key]} anchor={active.anchor} onClose={closeTerm} />
      )}
    </>
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
