// Shared utility components for the SPA

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

function CopyButton({ text, label = "Copy" }) {
  const [copied, setCopied] = useState(false);
  const onCopy = (e) => {
    e.stopPropagation();
    navigator.clipboard.writeText(text);
    setCopied(true);
    setTimeout(() => setCopied(false), 1200);
  };
  return (
    <button className={"copy-btn " + (copied ? "copied" : "")} onClick={onCopy}>
      {copied ? "Copied" : label}
    </button>
  );
}

function CodeBlock({ children, language = "css", copy = true }) {
  const text = typeof children === "string" ? children : "";
  return (
    <div className="code-block">
      {copy && <CopyButton text={text} />}
      <pre style={{ margin: 0 }}><code>{children}</code></pre>
    </div>
  );
}

function Eyebrow({ children }) {
  return <div className="eyebrow">{children}</div>;
}

function SectionHeader({ eyebrow, title, lede, provenance }) {
  return (
    <header style={{ marginBottom: 40 }}>
      {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
      <h1 className="page-title">{title}</h1>
      {lede && <p className="page-lede">{lede}</p>}
      {provenance && <Provenance level={provenance.level} note={provenance.note} />}
    </header>
  );
}

function Provenance({ level = "verified", note }) {
  const conf = {
    verified:    { tag: "✓ Verified",    desc: "Sourced directly from the 2025 RegScale Design & Brand Guide.", cls: "prov-verified" },
    mixed:       { tag: "◐ Mixed",       desc: "Core values verified against the 2025 guide; structure or naming is authored.", cls: "prov-mixed" },
    recommended: { tag: "⚙ Recommended", desc: "Authored standard — the 2025 guide is silent here. Needs brand-team sign-off.", cls: "prov-recommended" },
  }[level] || {};
  return (
    <div className={"provenance " + conf.cls}>
      <span className="prov-tag">{conf.tag}</span>
      <span className="prov-desc">{note || conf.desc}</span>
    </div>
  );
}

function H2({ children, sub }) {
  return (
    <>
      <h2 className="section-title">{children}</h2>
      {sub && <p className="section-sub">{sub}</p>}
    </>
  );
}

function DownloadButton({ label = "Download", note }) {
  const [pulse, setPulse] = useState(false);
  return (
    <button
      className="dl-btn"
      onClick={() => { setPulse(true); setTimeout(() => setPulse(false), 800); }}
      title="Placeholder — wire this to your asset CDN"
    >
      <svg className="ico" viewBox="0 0 12 12" fill="none">
        <path d="M6 1v7M3 5l3 3 3-3M2 10h8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
      {pulse ? "Queued ✓" : label}
      {note && <span style={{ opacity: 0.6, marginLeft: 4, fontSize: 11 }}>{note}</span>}
    </button>
  );
}

// Easing curve renderer — points = cubic-bezier control points
function EasingCurve({ p1x, p1y, p2x, p2y, animate, runKey }) {
  const w = 220, h = 80, padX = 14, padY = 14;
  const x = (t) => padX + (w - padX*2) * t;
  const y = (t) => h - padY - (h - padY*2) * t;
  const path = `M${x(0)},${y(0)} C${x(p1x)},${y(p1y)} ${x(p2x)},${y(p2y)} ${x(1)},${y(1)}`;
  const puckRef = useRef(null);

  useEffect(() => {
    const el = puckRef.current; if (!el) return;
    el.style.animation = "none";
    el.offsetWidth;
    el.style.animation = `puckRun 1400ms cubic-bezier(${p1x},${p1y},${p2x},${p2y}) forwards`;
  }, [runKey, p1x, p1y, p2x, p2y]);

  return (
    <div className="curve-viz">
      <svg viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
        <path d={`M${x(0)},${y(0)} L${x(1)},${y(0)}`} stroke="rgba(255,255,255,0.06)" strokeDasharray="2 4" />
        <path d={path} stroke="#00DBEE" strokeWidth="2" fill="none" />
        <circle cx={x(0)} cy={y(0)} r="3" fill="#fff" />
        <circle cx={x(1)} cy={y(1)} r="3" fill="#fff" />
      </svg>
      <div className="puck" ref={puckRef} />
      <style>{`
        @keyframes puckRun {
          0%   { left: 14px; }
          100% { left: calc(100% - 28px); }
        }
      `}</style>
    </div>
  );
}

// Logo lockup component — supports six variants per the 2025 Brand Guide
function RegScaleLogo({ inverse, size = "md", variant }) {
  const sizes = { sm: { w: 32, t: 20 }, md: { w: 48, t: 28 }, lg: { w: 72, t: 42 } };
  const s = sizes[size] || sizes.md;

  // Variant-specific styling for the wordmark + symbol
  let wordStyle = {};
  let scaleStyle = {};
  let symbolFilter = null;
  if (variant === "all-black") {
    wordStyle = { color: "#000" }; scaleStyle = { color: "#000" };
    symbolFilter = "grayscale(1) brightness(0)";
  } else if (variant === "all-white") {
    wordStyle = { color: "#fff" }; scaleStyle = { color: "#fff" };
    symbolFilter = "brightness(0) invert(1)";
  } else if (variant === "solid-blue") {
    wordStyle = { color: "var(--rs-compliance-blue)" }; scaleStyle = { color: "var(--rs-compliance-blue)" };
    symbolFilter = "grayscale(1) brightness(0.4) sepia(1) hue-rotate(200deg) saturate(8)";
  }
  // "color" and "color-on-dark" use default class styling

  return (
    <div className={"logo-mark " + (inverse ? "inverse" : "")}>
      <div className="logo-symbol" style={{ width: s.w, height: s.w, filter: symbolFilter || undefined }} />
      <div className="logo-wordmark" style={{ fontSize: s.t, ...wordStyle }}>
        Reg<span className="scale" style={scaleStyle}>Scale</span>
      </div>
    </div>
  );
}

Object.assign(window, { CopyButton, CodeBlock, Eyebrow, SectionHeader, H2, DownloadButton, EasingCurve, RegScaleLogo, Provenance });
