// Shared atoms: Tilt card, reveal on scroll, animated counter, section header.
// framer-motion UMD exposes as window.Motion (v11)
const FM = window.Motion || {};

/* ----------------------- Reveal ----------------------- */
function Reveal({ children, y = 24, delay = 0, className = "", once = true }) {
  const ref = React.useRef(null);
  const inView = FM.useInView ? FM.useInView(ref, { once, margin: "-10% 0px -10% 0px" }) : true;
  const MotionDiv = FM.motion ? FM.motion.div : "div";
  return (
    <MotionDiv
      ref={ref}
      initial={{ opacity: 0, y }}
      animate={inView ? { opacity: 1, y: 0 } : undefined}
      transition={{ duration: 0.7, delay, ease: [0.22, 1, 0.36, 1] }}
      className={className}
    >
      {children}
    </MotionDiv>
  );
}

/* ----------------------- Tilt Card ----------------------- */
function Tilt({ children, className = "", max = 6, scale = 1.01, glare = true, style = {} }) {
  // Tilt disabled — caused sub-pixel paint artefacts on large serif text with 3D context.
  return (
    <div className={`tilt-wrap ${className}`} style={style}>
      <div className="tilt relative h-full w-full rounded-[inherit]">
        {children}
        {glare && <div className="tilt-shine rounded-[inherit]" />}
      </div>
    </div>
  );
}

/* ----------------------- Counter ----------------------- */
function Counter({ to = 0, duration = 1.4, prefix = "", suffix = "", className = "" }) {
  // Animation removed to prevent paint artefacts on large serif numerals.
  // The number still feels dynamic thanks to Reveal's opacity/y transition on the parent.
  const display = Math.abs(to) >= 1000 ? to.toLocaleString("es-CL") : to.toString();
  return <span className={className}>{prefix}{display}{suffix}</span>;
}

/* ----------------------- Section Header ----------------------- */
function SectionHeader({ num, label, title, kicker, className = "" }) {
  return (
    <div className={`flex flex-col gap-4 ${className}`}>
      <div className="sec-label">
        <span className="sec-dash" aria-hidden="true" />
        <span>{label}</span>
      </div>
      <div className="grid grid-cols-12 gap-6 md:gap-8 items-start">
        <h2 className="col-span-12 md:col-span-8 serif text-[44px] md:text-[56px] leading-[1.05] tracking-[-0.01em] text-[color:var(--text)] pb-1" style={{textWrap:"balance"}}>
          {title}
        </h2>
        {kicker && <p className="col-span-12 md:col-span-4 t-mute text-[15px] leading-relaxed md:pt-3">{kicker}</p>}
      </div>
      <div className="accent-rule w-full" />
    </div>
  );
}

/* ----------------------- Lucide icon helper ----------------------- */
function Icon({ name, size = 16, className = "", strokeWidth = 1.6 }) {
  const L = window.lucide || {};
  // Convert kebab-case to PascalCase
  const pascal = name.replace(/(^|-)(\w)/g, (_, __, c) => c.toUpperCase());
  const node = L[pascal] || L.Square;
  if (!node || !Array.isArray(node)) return <span style={{ display:"inline-block", width:size, height:size }} />;
  const [, attrs, children] = node;
  const kebabToCamel = (k) => k.replace(/-([a-z])/g, (_, c) => c.toUpperCase());
  const svgAttrs = {};
  for (const k in attrs) svgAttrs[kebabToCamel(k)] = attrs[k];
  return (
    <svg
      {...svgAttrs}
      width={size}
      height={size}
      strokeWidth={strokeWidth}
      className={className}
      aria-hidden="true"
    >
      {(children || []).map((c, i) => {
        if (!Array.isArray(c)) return null;
        const [tag, cattrs] = c;
        const props = { key: i };
        for (const k in cattrs) props[kebabToCamel(k)] = cattrs[k];
        return React.createElement(tag, props);
      })}
    </svg>
  );
}

Object.assign(window, { Reveal, Tilt, Counter, SectionHeader, Icon, FM });
