// page-shell.jsx
// Shared building blocks for every Allo Education book page (8.5×11).
// Header / Footer / Page wrapper / Ketty slot / decorative doodles / QR placeholder.

const { useState, useMemo, useEffect, useRef } = React;

/* ---------- Logo (vector — "Allo Education / Éditions") ---------- */
const AlloLogoMark = ({ size = "0.42in" }) => (
  <svg viewBox="0 0 64 64" style={{ width: size, height: size }}>
    {/* Mortar board */}
    <path d="M32 10 L58 22 L32 34 L6 22 Z" fill="white" />
    <path d="M14 26 L14 38 Q14 46 32 46 Q50 46 50 38 L50 26" fill="none" stroke="white" strokeWidth="3" strokeLinecap="round"/>
    <circle cx="56" cy="26" r="2.2" fill="var(--ae-yellow)" />
    <path d="M56 28 L56 36" stroke="var(--ae-yellow)" strokeWidth="2" strokeLinecap="round"/>
  </svg>
);

const AlloHeaderLogo = () => (
  <div className="ae-header-logo">
    <div className="lg-mark"><AlloLogoMark /></div>
    <div className="lg-text">
      <span className="lg1">Allo</span>
      <span className="lg2">Education</span>
      <span className="lg3">Éditions</span>
    </div>
  </div>
);

/* ---------- Header doodles (subtle, white-on-blue) ---------- */
const HeaderDoodles = () => (
  <>
    <svg className="ae-header-doodle" style={{ left: "3.4in", top: "0.18in", width: "0.5in" }} viewBox="0 0 50 30" fill="none">
      <path d="M2 22 C 12 8, 24 8, 38 18" stroke="white" strokeWidth="1.4" strokeDasharray="2 3" strokeLinecap="round" />
      <circle cx="40" cy="20" r="2" fill="var(--ae-yellow)" />
    </svg>
    <svg className="ae-header-doodle" style={{ right: "1.6in", top: "0.16in", width: "0.4in" }} viewBox="0 0 40 30" fill="none">
      <path d="M4 20 L 18 6 L 36 14 L 22 20 L 20 28 Z" stroke="white" strokeWidth="1.5" fill="none" strokeLinejoin="round"/>
    </svg>
    <svg className="ae-header-doodle" style={{ left: "2.5in", top: "0.05in", width: "0.18in" }} viewBox="0 0 24 24">
      <path d="M12 2 L14 9 L21 10 L15 15 L17 22 L12 18 L7 22 L9 15 L3 10 L10 9 Z" fill="var(--ae-yellow)" />
    </svg>
  </>
);

/* ---------- Header ---------- */
function PageHeader({ matiere = "Mode d'emploi", niveau = "Primaire", page = 3, showDoodles = true, variant = "default", splitOf }) {
  return (
    <header className="ae-header">
      {showDoodles && <HeaderDoodles />}
      <AlloHeaderLogo />
      <div className="ae-header-pill">
        <span>{matiere}</span>
        <span className="dot"></span>
        <span>{niveau}</span>
        {splitOf && <span className="ae-split-badge">{splitOf.n} / {splitOf.total}</span>}
      </div>
      <div className={"ae-header-page" + (variant === "muted" ? " muted" : "")}>
        {typeof page === "number" ? `Page ${page}` : page}
      </div>
    </header>
  );
}

/* ---------- QR placeholder (visually realistic — V1.1) ---------- */
function QRPlaceholder({ size = "0.9in", seed = 42, fg = "#0F1A3D", bg = "white", quiet = true }) {
  // 33×33 grid (Version 4 QR). Three finder patterns, one alignment pattern,
  // timing rows, and a deterministic dense data field. Looks real, isn't scannable.
  const grid = 33;
  const cells = React.useMemo(() => {
    let s = seed * 1103515245 + 12345;
    const rand = () => { s = (s * 1103515245 + 12345) & 0x7fffffff; return (s >>> 0) / 0x7fffffff; };
    const inFinder = (x, y) =>
      (x < 7 && y < 7) || (x > grid - 8 && y < 7) || (x < 7 && y > grid - 8);
    const finderRing = (x, y) => {
      const fx = x > grid - 8 ? grid - 1 - x : x;
      const fy = y > grid - 8 ? grid - 1 - y : y;
      if (fx === 0 || fx === 6 || fy === 0 || fy === 6) return 1;
      if (fx >= 2 && fx <= 4 && fy >= 2 && fy <= 4) return 1;
      return 0;
    };
    // Alignment pattern (5×5) at bottom-right interior
    const ax = grid - 9, ay = grid - 9;
    const inAlign = (x, y) => x >= ax && x < ax + 5 && y >= ay && y < ay + 5;
    const alignCell = (x, y) => {
      const dx = x - ax, dy = y - ay;
      if (dx === 0 || dx === 4 || dy === 0 || dy === 4) return 1;
      if (dx === 2 && dy === 2) return 1;
      return 0;
    };
    const out = [];
    for (let y = 0; y < grid; y++) {
      for (let x = 0; x < grid; x++) {
        let v;
        if (inFinder(x, y)) v = finderRing(x, y);
        else if (inAlign(x, y)) v = alignCell(x, y);
        else if (x === 6) v = y % 2 === 0 ? 1 : 0;          // timing column
        else if (y === 6) v = x % 2 === 0 ? 1 : 0;          // timing row
        else v = rand() > 0.48 ? 1 : 0;                     // data field
        if (v) out.push([x, y]);
      }
    }
    return out;
  }, [seed]);
  // Quiet zone is part of the visual block (1 module padding embedded in viewBox)
  const q = quiet ? 1 : 0;
  return (
    <svg
      viewBox={`${-q} ${-q} ${grid + q * 2} ${grid + q * 2}`}
      style={{ width: size, height: size, background: bg, display: "block", borderRadius: "1px" }}
      shapeRendering="crispEdges"
    >
      {cells.map(([x, y], i) => <rect key={i} x={x} y={y} width="1" height="1" fill={fg} />)}
    </svg>
  );
}

/* ---------- Footer (V1.2 — square white-bg QR for KDP print fidelity) ---------- */
function PageFooter({
  score = "/ 10",
  scoreVisible = true,
  qrVisible = true,
  qrSlug,                  // production: builds the URL via factoryUrl
  qrUrl = "alloeducation.fr",
  qrLabel = "Corriger avec Ketty",
  qrSubLabel,              // optional second line shown above the URL
  page = 3,
}) {
  // qrSlug overrides qrUrl when present (production wiring)
  const url = qrSlug ? `alloeducation.fr/qr/${qrSlug}` : qrUrl;
  return (
    <footer className="ae-footer">
      <div>
        {scoreVisible && (
          <div className="ft-score">
            <span>Score :</span>
            <span className="blank"></span>
            <span>{score}</span>
          </div>
        )}
      </div>
      <div className="ft-qr" style={{ visibility: qrVisible ? "visible" : "hidden" }}>
        <div className="qr-square" data-prod-replace="qr" data-qr-slug={qrSlug || ""}>
          <QRPlaceholder size="0.55in" fg="#0F1A3D" bg="white" seed={page * 7 + 13} quiet={true} />
        </div>
        <div className="qr-text">
          {qrSubLabel && <div className="sub">{qrSubLabel}</div>}
          <div>{qrLabel}</div>
          <div>sur <span className="url">{url}</span></div>
        </div>
      </div>
      <div className="ft-page">{typeof page === "number" ? page : "—"}</div>
    </footer>
  );
}

/* ---------- Ketty slot (placeholder for 3D PNG) ---------- */
const KETTY_SVG = `data:image/svg+xml;utf8,${encodeURIComponent(`
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 120'>
<g fill='black'>
<ellipse cx='50' cy='30' rx='17' ry='19'/>
<path d='M30 28 Q22 18 30 10 Q38 6 44 16 Z'/>
<path d='M70 28 Q78 18 70 10 Q62 6 56 16 Z'/>
<rect x='32' y='52' width='36' height='38' rx='10'/>
<path d='M22 55 Q14 65 18 80 L30 85 L34 65 Z'/>
<path d='M78 55 Q86 65 82 80 L70 85 L66 65 Z'/>
<rect x='34' y='86' width='14' height='28' rx='5'/>
<rect x='52' y='86' width='14' height='28' rx='5'/>
</g>
</svg>`)}`;

function KettySlot({
  pose = "hello",          // alias accepted: kettyPose -> pose
  kettyPose,
  kettyImageSrc,           // production: real PNG path (e.g. "img/ketty/pointing.png")
  kettyAlt,                // production: alt text for accessibility
  className = "",
  style = {},
}) {
  const finalPose = kettyPose || pose;
  if (kettyImageSrc) {
    return (
      <div className={"ketty-slot is-prod " + className} style={style}>
        <img src={kettyImageSrc} alt={kettyAlt || `Ketty — ${finalPose}`}
             style={{ width: "100%", height: "100%", objectFit: "contain" }} />
      </div>
    );
  }
  return (
    <div className={"ketty-slot " + className}
         style={{ "--ketty-mask": `url("${KETTY_SVG}")`, ...style }}
         data-prod-replace="ketty" data-ketty-pose={finalPose}>
      <div className="silhouette"></div>
      <div className="ks-cap">Ketty PNG transparent</div>
      <div className="ks-pose">pose : {finalPose}</div>
    </div>
  );
}

/* ---------- Full page wrapper ---------- */
// V1.2.2 — density is now LOCKED per template (not driven by a global tweak).
// The optional `splitOf` prop renders a "1 / 2" badge in the header and is
// the only safe way to declare a content-too-long page split.
function AePage({
  matiere = "Mode d'emploi",
  niveau = "Primaire",
  page = 3,
  scale = 0.7,
  density = "std",         // LOCKED per template — air | std | dense
  qrVisible = true,
  scoreVisible = true,
  showGrid = false,
  showMargins = false,
  // V1.2 official QR props
  qrSlug,
  qrUrl,
  qrLabel = "Corriger avec Ketty",
  qrSubLabel,
  // V1.2.2 split-page support
  splitOf,                 // e.g. {n: 1, total: 2}
  // V1.2.2 auditor mode — when true (set by sidebar toggle), flags violations
  audit = false,
  children,
}) {
  const contentRef = React.useRef(null);
  const [overflow, setOverflow] = React.useState(false);

  // Overflow detection — runs after layout in auditor mode
  React.useEffect(() => {
    if (!audit || !contentRef.current) return;
    const el = contentRef.current;
    setOverflow(el.scrollHeight - el.clientHeight > 2);
  }, [audit, children]);

  const cls = [
    "ae-page",
    "scaled",
    `density-${density}`,
    showGrid && "show-grid",
    showMargins && "show-margins",
  ].filter(Boolean).join(" ");

  return (
    <div className={cls}
         style={{ "--ae-page-scale": scale }}
         data-overflow={audit && overflow ? "true" : undefined}>
      <PageHeader matiere={matiere} niveau={niveau} page={page} splitOf={splitOf} />
      <div className="ae-content" ref={contentRef}>{children}</div>
      <PageFooter
        page={page}
        qrVisible={qrVisible}
        scoreVisible={scoreVisible}
        qrSlug={qrSlug}
        qrUrl={qrUrl}
        qrLabel={qrLabel}
        qrSubLabel={qrSubLabel}
      />
    </div>
  );
}

/* ---------- Page-frame wrapper for previews in mini-site ---------- */
function PageFrame({ label = "8.5 × 11 in", scale = 0.62, children }) {
  // children is an AePage; we render it scaled and reserve actual scaled space.
  // Width/height of scaled content = page * scale.
  const w = `calc(${8.5} * ${scale} * 96px)`;
  const h = `calc(${11} * ${scale} * 96px)`;
  return (
    <div className="page-frame">
      <div className="frame-meta">
        <span>{label}</span>
        <span className="meta-pill">300 dpi · KDP ready</span>
      </div>
      <div style={{ width: w, height: h, position: "relative", overflow: "hidden" }}>
        {React.cloneElement(children, { scale })}
      </div>
    </div>
  );
}

/* Export */
Object.assign(window, {
  AlloHeaderLogo, AlloLogoMark, PageHeader, PageFooter, AePage, PageFrame,
  KettySlot, QRPlaceholder, HeaderDoodles,
});
