// charte-blocks.jsx — V1.1 LOCKED COMPONENT LIBRARY
// Every page in the collection composes these blocks. Pages MUST NOT
// invent their own header / footer / box / spacing — only insert blocks
// inside <PageShell>'s content area. Blocks have fixed widths (full grid
// row), fixed inner padding, and rely on PageShell's --ae-block-gap for
// vertical rhythm.
//
// Naming follows the brief: PageShell, QRBlock, KettyBubble, ObjectiveBox,
// LessonBox, ExerciseCard, MethodSteps, SelfCheck, ScoreBox, WarningBox,
// ChallengeBox, TableBlock, FigureBlock.

/* ─────────────────────────────────────────────────────────────────────
   PageShell — the ONLY way to start a page. Wraps Header + content + Footer.
   ───────────────────────────────────────────────────────────────────── */
function PageShell({
  matiere, niveau, page,
  density = "std",
  // V1.2 — official QR props (production-ready)
  qrVisible = true,
  scoreVisible = true,
  qrSlug,
  qrUrl,
  qrLabel = "Corriger avec Ketty",
  qrSubLabel,
  scale = 1,
  // V1.2.2 — audit mode (renderer PDF / QA toggle). Surfaces overflow as
  // a blocking error instead of silently clipping the page.
  audit = false,
  // V1.2.2 — split-page indicator (e.g. {n:1, total:2}) for content that
  // legitimately spans two pages. Renders a small badge in the header pill.
  splitOf,
  children,
}) {
  return (
    <AePage
      matiere={matiere} niveau={niveau} page={page}
      density={density} qrVisible={qrVisible} scoreVisible={scoreVisible}
      qrSlug={qrSlug} qrUrl={qrUrl} qrLabel={qrLabel} qrSubLabel={qrSubLabel}
      scale={scale}
      audit={audit}
      splitOf={splitOf}
    >
      <div className="ae-stack">{children}</div>
    </AePage>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   PageTitle — always the first block of any page. Unique typo, no padding.
   ───────────────────────────────────────────────────────────────────── */
function PageTitle({ eyebrow, title, subtitle }) {
  return (
    <div className="bk-pagetitle">
      {eyebrow && <div className="eyebrow">{eyebrow}</div>}
      <div className="title">{title}</div>
      {subtitle && <div className="subtitle">{subtitle}</div>}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   Generic Box — backbone of all framed blocks. Don't use directly in a page.
   ───────────────────────────────────────────────────────────────────── */
function Box({ tone = "neutral", label, iconKey, icon, children, dashed = false, className = "" }) {
  // V1.2 — prefer iconKey (SVG registry). `icon` kept as fallback for legacy strings.
  const cls = [
    "bk-box",
    `tone-${tone}`,
    dashed && "is-dashed",
    label && "has-tab",
    className,
  ].filter(Boolean).join(" ");
  const iconNode = iconKey
    ? <Icon k={iconKey} />
    : (icon ? <span>{icon}</span> : null);
  return (
    <section className={cls}>
      {label && (
        <div className="bk-tab">
          {iconNode && <span className="ic">{iconNode}</span>}
          <span>{label}</span>
        </div>
      )}
      <div className="bk-body">{children}</div>
    </section>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   ObjectiveBox — "Objectifs / Compétences" — primaire & collège
   ───────────────────────────────────────────────────────────────────── */
function ObjectiveBox({ title = "Objectifs", items = [], iconKey = "icon-cible" }) {
  return (
    <Box tone="primary" label={title} iconKey={iconKey}>
      <ul className="bk-bullets">
        {items.map((it, i) => <li key={i}><span className="dot"></span>{it}</li>)}
      </ul>
    </Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   LessonBox — "Je retiens / Cours" — fond jaune
   ───────────────────────────────────────────────────────────────────── */
function LessonBox({ title = "Je retiens", iconKey = "icon-ampoule", children, formula }) {
  return (
    <Box tone="yellow" label={title} iconKey={iconKey}>
      <div className="bk-text">{children}</div>
      {formula && <div className="bk-formula">{formula}</div>}
    </Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   ExerciseCard — exercice structuré : numéro, consigne, contenu
   ───────────────────────────────────────────────────────────────────── */
function ExerciseCard({ number = 1, title = "Exercice", consigne, tone = "primary", iconKey = "icon-crayon", children }) {
  return (
    <Box tone={tone} label={`${title} ${number}`} iconKey={iconKey} className="is-exo">
      {consigne && <div className="bk-consigne">{consigne}</div>}
      <div className="bk-exo-body">{children}</div>
    </Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   MethodSteps — méthode pas à pas (vert)
   ───────────────────────────────────────────────────────────────────── */
function MethodSteps({ title = "Méthode", steps = [], iconKey = "icon-check" }) {
  return (
    <Box tone="green" label={title} iconKey={iconKey}>
      <ol className="bk-steps">
        {steps.map((s, i) => (
          <li key={i}><span className="n">{i + 1}</span><span className="t">{s}</span></li>
        ))}
      </ol>
    </Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   WarningBox — "Erreur à éviter / Attention"
   ───────────────────────────────────────────────────────────────────── */
function WarningBox({ title = "Erreur à éviter", children, iconKey = "icon-attention" }) {
  return (
    <Box tone="red" label={title} iconKey={iconKey}>{children}</Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   ChallengeBox — "Défi Ketty / Pour aller plus loin"
   ───────────────────────────────────────────────────────────────────── */
function ChallengeBox({ title = "Défi Ketty", children, iconKey = "icon-etoile" }) {
  return (
    <Box tone="orange" label={title} iconKey={iconKey} dashed>{children}</Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   SelfCheck — checklist "Je vérifie"
   ───────────────────────────────────────────────────────────────────── */
function SelfCheck({ title = "Je vérifie", items = [], iconKey = "icon-check" }) {
  return (
    <Box tone="cool" label={title} iconKey={iconKey}>
      <ul className="bk-checklist">
        {items.map((it, i) => (
          <li key={i}><span className="bk-check"></span>{it}</li>
        ))}
      </ul>
    </Box>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   ScoreBox — bilan / score d'auto-évaluation
   ───────────────────────────────────────────────────────────────────── */
function ScoreBox({ label = "Mon bilan", message }) {
  return (
    <div className="bk-score">
      <div className="stamp"><Icon k="icon-etoile" /></div>
      <div className="copy">
        <div className="lab">{label}</div>
        <div className="msg">{message}</div>
      </div>
      <div className="value">__ <span className="den">/ 10</span></div>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   TableBlock — tableau standardisé
   ───────────────────────────────────────────────────────────────────── */
function TableBlock({ title, columns, rows }) {
  return (
    <div className={"bk-table-wrap" + (title ? " has-title" : "")}>
      {title && <div className="bk-table-title">{title}</div>}
      <table className="bk-table">
        <thead>
          <tr>{columns.map((c, i) => <th key={i}>{c}</th>)}</tr>
        </thead>
        <tbody>
          {rows.map((r, i) => (
            <tr key={i}>{r.map((c, j) => <td key={j}>{c}</td>)}</tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   FigureBlock — illustration / schéma encadré + légende
   ───────────────────────────────────────────────────────────────────── */
function FigureBlock({ caption, label = "Document", children, height = "1.2in" }) {
  return (
    <figure className="bk-figure">
      <div className="bk-figure-frame" style={{ height }}>
        {children || <div className="bk-figure-placeholder">illustration / schéma</div>}
      </div>
      {caption && <figcaption><b>{label}</b> · {caption}</figcaption>}
    </figure>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   QRBlock — bloc QR sur la page (différent du QR du footer)
   ───────────────────────────────────────────────────────────────────── */
function QRBlock({
  title = "Scanne pour la correction",
  // V1.2 — production props
  qrSlug,
  qrUrl = "alloeducation.fr/maths/4e/p28",
  qrLabel,                 // alias for title (production-naming consistency)
  qrSubLabel,
  url,                     // legacy alias for qrUrl
  seed = 42,
  size = "0.95in",
}) {
  const finalUrl = qrSlug ? `alloeducation.fr/qr/${qrSlug}` : (url || qrUrl);
  const finalTitle = qrLabel || title;
  return (
    <div className="bk-qrblock">
      <div className="bk-qr" data-prod-replace="qr" data-qr-slug={qrSlug || ""}>
        <QRPlaceholder size={size} seed={seed} />
      </div>
      <div className="bk-qr-copy">
        <div className="t">{finalTitle}</div>
        {qrSubLabel && <div className="sub">{qrSubLabel}</div>}
        <div className="u">{finalUrl}</div>
      </div>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   KettyBubble — composant Ketty unique (slot mascotte + bulle)
   ───────────────────────────────────────────────────────────────────── */
function KettyBubble({
  pose = "pointing",
  // V1.2 — production props
  kettyPose,
  kettyImageSrc,
  kettyAlt,
  label = "Astuce Ketty",
  tone = "primary",
  children,
}) {
  return (
    <div className="bk-ketty">
      <div className="bk-ketty-slot">
        <KettySlot
          pose={pose}
          kettyPose={kettyPose}
          kettyImageSrc={kettyImageSrc}
          kettyAlt={kettyAlt}
        />
      </div>
      <div className={`bk-ketty-bubble tone-${tone}`}>
        <div className="bk-ketty-lab">{label}</div>
        <div className="bk-ketty-text">{children}</div>
      </div>
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   Helpers used inside ExerciseCard
   ───────────────────────────────────────────────────────────────────── */
function QInput({ n, children }) {
  return (
    <div className="bk-q">
      <span className="ae-q-num">{n}</span>
      <span className="bk-q-content">{children}</span>
    </div>
  );
}
function AnswerLine({ width = "1.4in" }) {
  return <span className="ae-answer-line" style={{ width }}></span>;
}
function AnswerBox({ height = "0.6in", ruled = false }) {
  return <div className={"ae-answer-box" + (ruled ? " ruled" : "")} style={{ height }}></div>;
}
function QCMRow({ options = [] }) {
  return (
    <div className="bk-qcm-row">
      {options.map(([letter, text], i) => (
        <span key={i} className="bk-qcm-opt">
          <span className="ae-qcm-letter">{letter}</span>{text}
        </span>
      ))}
    </div>
  );
}

/* ─────────────────────────────────────────────────────────────────────
   Two-column layout helper for putting blocks side-by-side
   ───────────────────────────────────────────────────────────────────── */
function Cols({ ratio = "1fr 1fr", gap, className = "", children }) {
  return (
    <div className={"bk-cols " + className} style={{ gridTemplateColumns: ratio, gap: gap || "var(--ae-block-gap)" }}>
      {children}
    </div>
  );
}

Object.assign(window, {
  PageShell, PageTitle, Box, ObjectiveBox, LessonBox, ExerciseCard,
  MethodSteps, WarningBox, ChallengeBox, SelfCheck, ScoreBox,
  TableBlock, FigureBlock, QRBlock, KettyBubble,
  QInput, AnswerLine, AnswerBox, QCMRow, Cols,
});
