/* UPOLT site — shared marketing primitives (icon, container, overline, buttons, sectioning). */

function Ico({ n, s = 20, c = "currentColor", style = {} }) {
  return <i data-lucide={n} style={{ width: s, height: s, color: c, display: "inline-flex", flex: "none", ...style }}></i>;
}

function Container({ children, style = {}, className = "" }) {
  return <div className={("upolt-content " + className).trim()} style={{ maxWidth: "var(--content-max)", margin: "0 auto", padding: "0 40px", ...style }}>{children}</div>;
}

function Overline({ children, onDark = false, style = {} }) {
  return (
    <div style={{ fontSize: 13, fontWeight: 700, letterSpacing: "0.1em", textTransform: "uppercase", color: onDark ? "var(--teal-400)" : "var(--text-accent)", ...style }}>
      {children}
    </div>
  );
}

/* Marketing button — anchor based, supports cross-page hrefs. Mirrors the DS button palette. */
function Btn({ children, variant = "primary", size = "lg", iconLeft, iconRight, href = "#", onClick, style = {} }) {
  const [h, setH] = React.useState(false);
  const [a, setA] = React.useState(false);
  const sizes = { sm: { height: 40, pad: "0 16px", fs: 14 }, md: { height: 46, pad: "0 20px", fs: 15 }, lg: { height: 52, pad: "0 24px", fs: 16 } };
  const s = sizes[size] || sizes.lg;
  const pal = {
    primary: { background: a ? "var(--accent-press)" : h ? "var(--accent-hover)" : "var(--accent)", color: "#fff", border: "1px solid transparent" },
    secondary: { background: a ? "var(--surface-active)" : h ? "var(--surface-hover)" : "transparent", color: "var(--text-primary)", border: "1px solid var(--graphite-900)" },
    ghost: { background: h ? "var(--surface-hover)" : "transparent", color: "var(--text-primary)", border: "1px solid transparent" },
    inverse: { background: a ? "var(--graphite-200)" : h ? "var(--graphite-100)" : "#fff", color: "var(--graphite-900)", border: "1px solid transparent" },
    ghostInverse: { background: h ? "rgba(255,255,255,0.10)" : "transparent", color: "#fff", border: "1px solid rgba(255,255,255,0.28)" },
  }[variant];
  const handle = (e) => { if (href === "#" || !href) e.preventDefault(); if (onClick) onClick(e); };
  return (
    <a href={href} onClick={handle}
      onMouseEnter={() => setH(true)} onMouseLeave={() => { setH(false); setA(false); }}
      onMouseDown={() => setA(true)} onMouseUp={() => setA(false)}
      style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8, height: s.height, padding: s.pad, fontFamily: "var(--font-sans)", fontSize: s.fs, fontWeight: 600, letterSpacing: "-0.01em", borderRadius: "var(--radius-button)", textDecoration: "none", cursor: "pointer", whiteSpace: "nowrap", transition: "background var(--motion-fast) var(--ease-standard), border-color var(--motion-fast) var(--ease-standard)", ...pal, ...style }}>
      {iconLeft}{children}{iconRight}
    </a>
  );
}

/* Inline text link with the teal "Learn more →" treatment. */
function TextLink({ children, href = "#", onDark = false, style = {} }) {
  const [h, setH] = React.useState(false);
  return (
    <a href={href} onClick={e => { if (href === "#") e.preventDefault(); }}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{ display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "var(--font-sans)", fontSize: 15, fontWeight: 600, color: onDark ? "var(--teal-400)" : "var(--text-accent)", textDecoration: "none", whiteSpace: "nowrap", ...style }}>
      {children}
      <span style={{ display: "inline-flex", transition: "transform var(--motion-fast) var(--ease-standard)", transform: h ? "translateX(3px)" : "none" }}><Ico n="arrow-right" s={16} /></span>
    </a>
  );
}

/* Scroll/entrance reveal — content is visible by default; the fade-up is a pure CSS
   animation layered on top, so content never stays hidden if animations are throttled. */
function Reveal({ children, delay = 0, y = 16, style = {} }) {
  return (
    <div className="upolt-reveal" style={{ "--reveal-y": `${y}px`, animationDelay: delay ? `${delay}ms` : undefined, ...style }}>
      {children}
    </div>
  );
}

/* Fires true once the element scrolls into view. */
function useInView(ref, { threshold = 0.3 } = {}) {
  const [inView, setInView] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    if (typeof IntersectionObserver === "undefined") { setInView(true); return; }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setInView(true); io.disconnect(); }
    }, { threshold });
    io.observe(ref.current);
    return () => io.disconnect();
  }, [ref, threshold]);
  return inView;
}

/* Counts up from 0 to target when `active` becomes true. */
function useCountUp(target, active, { duration = 1200 } = {}) {
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    if (!active) return;
    let raf, start;
    const tick = (ts) => {
      if (start == null) start = ts;
      const p = Math.min(1, (ts - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(target * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
      else setVal(target);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [target, active, duration]);
  return val;
}

Object.assign(window, { Ico, Container, Overline, Btn, TextLink, Reveal, useInView, useCountUp });
