/* global React, window, document, BlogCover, ContactDots */
const { useState: useStateBlog, useMemo: useMemoBlog } = React;

const CAT_COLORS = {
  'estrategia': '#5a5347',
  'operacao': '#3d5a6b',
  'implementacao': '#4a6b3a',
  'casos-de-uso': '#b8842a',
  'cultura': '#9a5a3d',
  'noticias': '#9a3d3d',
};
/* CAT_ORDER drives the editorial tabs; "noticias" is surfaced in its own section. */
const CAT_ORDER = ['estrategia', 'operacao', 'implementacao', 'casos-de-uso', 'cultura'];

function catLabel(lang, key) { return window.tr(lang, 'cat.' + key); }
function catColor(key) { return CAT_COLORS[key] || '#5a5347'; }
function formatDate(iso, lang) { return window.mooreFormatDate(iso, lang); }
function lp(path, lang) { return window.localePath(path, lang); }

/* Cover: halftone photo when the article has an image, else the generative dot cover.
   Fotos de notícia (landscape) pedem grade mais fina, contraste por percentis,
   nitidez local e quase nenhuma vinheta; tudo sobreponível por post via `image`. */
function Cover({ article, cols }) {
  const img = article.image;
  if (img && img.src) {
    const HT = window.Halftone;
    return (
      <HT
        src={img.src} alt=""
        cols={img.cols || cols || 110}
        zoom={img.zoom || 1}
        focusX={img.fx == null ? 0.5 : img.fx}
        focusY={img.fy == null ? 0.5 : img.fy}
        gamma={img.gamma || 1}
        clip={img.clip == null ? 0.02 : img.clip}
        contrast={img.contrast == null ? 0.3 : img.contrast}
        sharpen={img.sharpen == null ? 0.8 : img.sharpen}
        vignette={img.vignette == null ? 0.25 : img.vignette}
      />
    );
  }
  return <BlogCover slug={article.slug} color={catColor(article.category)} />;
}

function getArticles() {
  const all = (window.MOORE_ARTICLES || []).slice();
  all.sort((a, b) => (a.date < b.date ? 1 : a.date > b.date ? -1 : 0));
  return all;
}
function getArticle(slug) { return window.mooreGetArticle(slug); }
function content(article, lang) { return (article.i18n && (article.i18n[lang] || article.i18n.pt)) || {}; }

/* Renderiza inline: string, link interno {to,text}, externo {href,text} ou negrito {b}. */
function renderInline(value, lang, key) {
  if (value == null) return null;
  if (typeof value === 'string') return value;
  if (Array.isArray(value)) return value.map((part, i) => <React.Fragment key={i}>{renderInline(part, lang, i)}</React.Fragment>);
  if (typeof value === 'object') {
    if (value.b) return <strong key={key}>{renderInline(value.b, lang)}</strong>;
    if (value.to) return <a key={key} className="in" href={lp('/blog/' + value.to, lang)} data-spa="1">{renderInline(value.text, lang)}</a>;
    if (value.href) return <a key={key} className="in" href={value.href} target="_blank" rel="noopener noreferrer">{renderInline(value.text, lang)}</a>;
    if (value.text) return renderInline(value.text, lang, key);
  }
  return null;
}

function ProseBlocks({ body, lang }) {
  return (
    <div className="prose">
      {(body || []).map((block, i) => {
        switch (block.type) {
          case 'lead': return <p key={i} className="lead">{renderInline(block.text, lang)}</p>;
          case 'h2': return <h2 key={i}>{renderInline(block.text, lang)}</h2>;
          case 'h3': return <h3 key={i}>{renderInline(block.text, lang)}</h3>;
          case 'ul': return <ul key={i}>{block.items.map((it, j) => <li key={j}>{renderInline(it, lang)}</li>)}</ul>;
          case 'ol': return <ol key={i}>{block.items.map((it, j) => <li key={j}>{renderInline(it, lang)}</li>)}</ol>;
          case 'quote':
            return (
              <blockquote key={i}>
                <p>{renderInline(block.text, lang)}</p>
                {block.cite ? <cite>{renderInline(block.cite, lang)}</cite> : null}
              </blockquote>
            );
          case 'callout':
            return (
              <div key={i} className="callout">
                {block.title ? <p className="callout-title">{renderInline(block.title, lang)}</p> : null}
                <p>{renderInline(block.text, lang)}</p>
              </div>
            );
          case 'table':
            return (
              <div key={i} className="table-wrap">
                <table>
                  {block.headers ? (
                    <thead>
                      <tr>{block.headers.map((h, j) => <th key={j}>{renderInline(h, lang)}</th>)}</tr>
                    </thead>
                  ) : null}
                  <tbody>
                    {(block.rows || []).map((row, j) => (
                      <tr key={j}>{row.map((cell, k) => <td key={k}>{renderInline(cell, lang)}</td>)}</tr>
                    ))}
                  </tbody>
                </table>
              </div>
            );
          default: return <p key={i}>{renderInline(block.text, lang)}</p>;
        }
      })}
    </div>
  );
}

function CatTag({ catKey, lang }) {
  const color = catColor(catKey);
  return (
    <span className="cat-tag" style={{ color: color }}>
      <span className="swatch" style={{ background: color }} />
      {catLabel(lang, catKey)}
    </span>
  );
}

/* ---------- Index ---------- */

function BlogIndex({ lang }) {
  const [filter, setFilter] = useStateBlog('todos');
  const articles = useMemoBlog(getArticles, []);
  const news = useMemoBlog(() => articles.filter((a) => a.category === 'noticias'), [articles]);
  const editorial = useMemoBlog(() => articles.filter((a) => a.category !== 'noticias'), [articles]);
  const usedCats = useMemoBlog(() => {
    const set = [];
    CAT_ORDER.forEach((c) => { if (editorial.some((a) => a.category === c)) set.push(c); });
    return set;
  }, [editorial]);

  const shownEditorial = filter === 'todos' ? editorial : editorial.filter((a) => a.category === filter);

  const wrap = { paddingTop: '80px', paddingBottom: '120px' };
  const header = { display: 'grid', gridTemplateColumns: '1.15fr 0.85fr', gap: '56px', alignItems: 'center', paddingBottom: '40px', borderBottom: '1px solid var(--ink)' };
  const h1 = { fontSize: 'clamp(40px, 5.4vw, 72px)', fontWeight: 500, letterSpacing: '-0.03em', lineHeight: 1.02, color: 'var(--ink)', margin: '16px 0 0', maxWidth: '15ch' };
  const lead = { fontSize: '19px', lineHeight: 1.55, color: 'var(--warm-700)', margin: 0, maxWidth: '46ch' };
  const meta = { fontFamily: 'var(--font-mono)', fontSize: '11px', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--warm-600)', display: 'flex', gap: '14px', flexWrap: 'wrap' };
  const cardTitle = { fontSize: 'clamp(24px, 2.6vw, 32px)', fontWeight: 500, letterSpacing: '-0.022em', lineHeight: 1.12, color: 'var(--ink)', margin: '14px 0 0', maxWidth: '20ch' };
  const dek = { fontSize: '16px', lineHeight: 1.55, color: 'var(--warm-700)', margin: '12px 0 0', maxWidth: '42ch' };
  const more = { fontFamily: 'var(--font-mono)', fontSize: '12px', letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--graphite)', marginTop: '18px', display: 'inline-flex', gap: '8px', alignItems: 'center' };
  const sectionEyebrow = { marginBottom: '20px' };

  const card = (a) => {
    const c = content(a, lang);
    return (
      <a key={a.slug} className="post-card" href={lp('/blog/' + a.slug, lang)} data-spa="1">
        <div className="cover"><Cover article={a} cols={110} /></div>
        <div>
          <div style={meta}>
            <CatTag catKey={a.category} lang={lang} />
            <span>{formatDate(a.date, lang)}</span>
            <span>{a.readingMinutes[lang] + ' ' + window.tr(lang, 'blog.reading_suffix')}</span>
          </div>
          <h2 className="post-title" style={cardTitle}>{c.title}</h2>
          <p style={dek}>{c.dek}</p>
          <span style={more}>{window.tr(lang, 'blog.read_article')} <span>→</span></span>
        </div>
      </a>
    );
  };

  return (
    <section style={wrap}>
      <div className="container">
        <header style={header} className="sec-header">
          <div>
            <h1 style={h1}>{window.tr(lang, 'blog.index_heading')}</h1>
            <p style={{ ...lead, marginTop: '20px' }}>{window.tr(lang, 'blog.index_lead')}</p>
          </div>
          <div className="contact-dots-wrap"><ContactDots tone="ink" /></div>
        </header>

        {news.length > 0 ? (
          <div id="noticias" style={{ paddingTop: '48px', scrollMarginTop: '100px' }}>
            <div className="eyebrow" style={sectionEyebrow}><span className="dot"></span> {window.tr(lang, 'blog.news_eyebrow')}</div>
            <div className="post-list">{news.map(card)}</div>
          </div>
        ) : null}

        <div id="artigos" style={{ paddingTop: news.length > 0 ? '72px' : '40px', scrollMarginTop: '100px' }}>
          <div className="eyebrow" style={sectionEyebrow}><span className="dot"></span> {window.tr(lang, 'blog.articles_eyebrow')}</div>
          <div className="cat-tabs" style={{ marginBottom: '8px' }}>
            <button className={'cat-tab' + (filter === 'todos' ? ' active' : '')} onClick={() => setFilter('todos')}>{window.tr(lang, 'blog.filter_all')}</button>
            {usedCats.map((c) => (
              <button key={c} className={'cat-tab' + (filter === c ? ' active' : '')} onClick={() => setFilter(c)}>{catLabel(lang, c)}</button>
            ))}
          </div>
          <div className="post-list">{shownEditorial.map(card)}</div>
        </div>
      </div>
    </section>
  );
}

/* ---------- Artigo ---------- */

function RelatedCard({ slug, lang }) {
  const a = getArticle(slug);
  if (!a) return null;
  const c = content(a, lang);
  const title = { fontSize: '18px', fontWeight: 500, letterSpacing: '-0.015em', lineHeight: 1.2, color: 'var(--ink)', margin: 0, maxWidth: '28ch' };
  const meta = { fontFamily: 'var(--font-mono)', fontSize: '10px', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--warm-600)', marginBottom: '6px' };
  return (
    <a className="related-card" href={lp('/blog/' + a.slug, lang)} data-spa="1">
      <div className="cover"><Cover article={a} cols={80} /></div>
      <div>
        <div style={meta}>{catLabel(lang, a.category)}</div>
        <h4 className="rel-title" style={title}>{c.title}</h4>
      </div>
    </a>
  );
}

function BlogArticle({ slug, lang, onOpenContact }) {
  const article = getArticle(slug);

  if (!article) {
    return (
      <section style={{ padding: '120px 0' }}>
        <div className="container-narrow">
          <div className="eyebrow"><span className="dot"></span> {window.tr(lang, 'blog.eyebrow')}</div>
          <h1 style={{ fontSize: '48px', fontWeight: 500, letterSpacing: '-0.03em', margin: '16px 0 24px' }}>{window.tr(lang, 'blog.not_found_heading')}</h1>
          <p style={{ fontSize: '19px', color: 'var(--warm-700)', maxWidth: '46ch', marginBottom: '32px' }}>{window.tr(lang, 'blog.not_found_p')}</p>
          <a className="btn secondary" href={lp('/blog', lang)} data-spa="1">{window.tr(lang, 'blog.not_found_button')}</a>
        </div>
      </section>
    );
  }

  const c = content(article, lang);
  const related = (article.related || []).filter((s) => getArticle(s));

  const head = { paddingTop: '64px', paddingBottom: '48px' };
  const back = { fontFamily: 'var(--font-mono)', fontSize: '12px', letterSpacing: '0.14em', textTransform: 'uppercase', color: 'var(--warm-600)', display: 'inline-flex', gap: '8px', alignItems: 'center' };
  const title = { fontSize: 'clamp(38px, 5.6vw, 68px)', fontWeight: 500, letterSpacing: '-0.035em', lineHeight: 1.04, color: 'var(--ink)', margin: '20px 0 0', maxWidth: '20ch' };
  const dek = { fontSize: '22px', lineHeight: 1.45, color: 'var(--warm-700)', margin: '24px 0 0', maxWidth: '46ch', letterSpacing: '-0.01em' };
  const metaRow = { display: 'flex', gap: '20px', flexWrap: 'wrap', marginTop: '32px', paddingTop: '24px', borderTop: '1px solid var(--border)', fontFamily: 'var(--font-mono)', fontSize: '11px', letterSpacing: '0.12em', textTransform: 'uppercase', color: 'var(--warm-600)' };

  return (
    <article>
      <div className="container-narrow" style={head}>
        <div style={{ marginBottom: '40px' }}>
          <a href={lp('/blog', lang)} data-spa="1" style={back}><span>←</span> {window.tr(lang, 'blog.back')}</a>
        </div>
        <CatTag catKey={article.category} lang={lang} />
        <h1 style={title}>{c.title}</h1>
        <p style={dek}>{c.dek}</p>
        <div style={metaRow}>
          <span><time dateTime={article.date}>{formatDate(article.date, lang)}</time></span>
          <span>{article.readingMinutes[lang] + ' ' + window.tr(lang, 'blog.reading_suffix')}</span>
          <span>{window.tr(lang, 'blog.byline')}</span>
        </div>
      </div>

      <div className="container-narrow">
        <div className="cover cover-tall"><Cover article={article} cols={150} /></div>
        {article.image && article.image.credit ? <p className="cover-credit">{article.image.credit}</p> : null}
      </div>

      <div className="container-narrow" style={{ paddingTop: '56px', paddingBottom: '24px' }}>
        <ProseBlocks body={c.body} lang={lang} />
      </div>

      <div className="container-narrow" style={{ paddingTop: '40px', paddingBottom: '80px' }}>
        <div className="on-ink" style={{ borderRadius: '2px', padding: 'clamp(32px, 5vw, 56px)' }}>
          <span className="eyebrow" style={{ color: 'var(--warm-400)' }}>{window.tr(lang, 'blog.cta_eyebrow')}</span>
          <h3 style={{ fontSize: 'clamp(28px, 3.4vw, 40px)', fontWeight: 500, letterSpacing: '-0.025em', lineHeight: 1.1, color: 'var(--cream)', margin: '14px 0 0', maxWidth: '20ch' }}>{window.tr(lang, 'blog.cta_heading')}</h3>
          <p style={{ fontSize: '17px', lineHeight: 1.6, color: 'var(--warm-300)', margin: '16px 0 28px', maxWidth: '46ch' }}>{window.tr(lang, 'blog.cta_p')}</p>
          <button className="btn ink-inverse" onClick={onOpenContact}>{window.tr(lang, 'blog.cta_button')} <span>→</span></button>
        </div>
      </div>

      {related.length > 0 ? (
        <div className="container-narrow" style={{ paddingBottom: '100px' }}>
          <div className="eyebrow" style={{ marginBottom: '8px' }}><span className="dot"></span> {window.tr(lang, 'blog.continue_reading')}</div>
          {related.map((s) => <RelatedCard key={s} slug={s} lang={lang} />)}
        </div>
      ) : null}
    </article>
  );
}

window.BlogIndex = BlogIndex;
window.BlogArticle = BlogArticle;
