/* =========================================================
   UI 공용 컴포넌트 — Icon / Reveal / Counter
   ========================================================= */
const { useState, useEffect, useRef, useCallback } = React;

/* ---------- Icon set (stroke-based, 24x24) ---------- */
const ICONS = {
  leaf: <path d="M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z M2 21c0-3 1.85-5.36 5.08-6" />,
  snow: <g><path d="M12 2v20M4.93 4.93l14.14 14.14M19.07 4.93 4.93 19.07M2 12h20" /><path d="M12 5 9.5 7.5M12 5l2.5 2.5M12 19l-2.5-2.5M12 19l2.5-2.5M5 12 7.5 9.5M5 12l2.5 2.5M19 12l-2.5-2.5M19 12l-2.5 2.5" /></g>,
  ruler: <g><path d="M21.3 15.3 8.7 2.7a1 1 0 0 0-1.4 0L2.7 7.3a1 1 0 0 0 0 1.4l12.6 12.6a1 1 0 0 0 1.4 0l4.6-4.6a1 1 0 0 0 0-1.4Z" /><path d="m14.5 12.5-2 2M11.5 9.5l-2 2M8.5 6.5l-2 2M17.5 15.5l-2 2" /></g>,
  doc: <g><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" /><path d="M14 2v6h6M9 13h6M9 17h6M9 9h1" /></g>,
  shield: <g><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z" /><path d="m9 12 2 2 4-4" /></g>,
  hand: <g><path d="M11 14V5.5a1.5 1.5 0 0 1 3 0V12" /><path d="M14 10.5a1.5 1.5 0 0 1 3 0V13" /><path d="M17 11.5a1.5 1.5 0 0 1 3 0V16a6 6 0 0 1-6 6h-2a6 6 0 0 1-5.4-3.4L4 13.5a1.5 1.5 0 0 1 2.6-1.5l1.4 2" /><path d="M8 13V4.5a1.5 1.5 0 0 1 3 0V12" /></g>,
  phone: <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.8 19.8 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.8 19.8 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.9.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92Z" />,
  check: <path d="M20 6 9 17l-5-5" />,
  plus: <path d="M12 5v14M5 12h14" />,
  arrowRight: <path d="M5 12h14M12 5l7 7-7 7" />,
  chevronRight: <path d="m9 18 6-6-6-6" />,
  chevronLeft: <path d="m15 18-6-6 6-6" />,
  zoom: <g><circle cx="11" cy="11" r="8" /><path d="m21 21-4.3-4.3M11 8v6M8 11h6" /></g>,
  x: <path d="M18 6 6 18M6 6l12 12" />,
  menu: <path d="M3 6h18M3 12h18M3 18h18" />,
  star: <path d="M11.5 2.5 14 8l6 .5-4.5 4 1.4 6L11.5 15 6 18.5 7.5 12.5 3 8.5 9 8z" />,
  mail: <g><rect x="2" y="4" width="20" height="16" rx="2" /><path d="m22 7-10 6L2 7" /></g>,
  pin: <g><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" /><circle cx="12" cy="10" r="3" /></g>,
  user: <g><circle cx="12" cy="8" r="4" /><path d="M4 21a8 8 0 0 1 16 0" /></g>,
  spark: <path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M18.4 5.6l-2.1 2.1M7.7 16.3l-2.1 2.1" />,
  clock: <g><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></g>,
  bolt: <path d="M13 2 4 14h7l-1 8 9-12h-7l1-8z" />,
};

function Icon({ name, size, strokeWidth = 1.8, className, style }) {
  const fillIcons = ["star"];
  const isFill = fillIcons.includes(name);
  return (
    <svg viewBox="0 0 24 24" width={size} height={size}
      fill={isFill ? "currentColor" : "none"} stroke={isFill ? "none" : "currentColor"}
      strokeWidth={strokeWidth} strokeLinecap="round" strokeLinejoin="round"
      className={className} style={style} aria-hidden="true">
      {ICONS[name] || null}
    </svg>
  );
}

/* ---------- Reveal on scroll ---------- */
function Reveal({ children, className = "", delay = 0, as = "div", style, ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === "undefined") { setShown(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.unobserve(e.target); } });
    }, { threshold: 0.12, rootMargin: "0px 0px -8% 0px" });
    io.observe(el);
    const fb = setTimeout(() => setShown(true), 900);
    return () => { io.disconnect(); clearTimeout(fb); };
  }, []);
  const Tag = as;
  const delayCls = delay ? ` reveal-${delay}` : "";
  return (
    <Tag ref={ref} className={`reveal${shown ? " in" : ""}${delayCls} ${className}`} style={style} {...rest}>
      {children}
    </Tag>
  );
}

/* ---------- Count-up number ---------- */
function Counter({ to, suffix = "", duration = 1500 }) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  const started = useRef(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const run = () => {
      if (started.current) return;
      started.current = true;
      const t0 = performance.now();
      const tick = (t) => {
        const p = Math.min((t - t0) / duration, 1);
        const eased = 1 - Math.pow(1 - p, 3);
        setVal(Math.round(eased * to));
        if (p < 1) requestAnimationFrame(tick);
      };
      requestAnimationFrame(tick);
    };
    if (typeof IntersectionObserver === "undefined") { run(); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { run(); io.unobserve(e.target); } });
    }, { threshold: 0.5 });
    io.observe(el);
    const fb = setTimeout(run, 1100);
    return () => { io.disconnect(); clearTimeout(fb); };
  }, [to, duration]);
  return <span ref={ref}>{val}<span className="u">{suffix}</span></span>;
}

Object.assign(window, { Icon, Reveal, Counter, useState, useEffect, useRef, useCallback });
