// Small reusable components for OnlySuomiHaku.

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

/* ---------- Icons ---------- */
const Icon = {
  search: (props) => (
    <svg viewBox="0 0 24 24" width="20" height="20" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <circle cx="11" cy="11" r="7" /><path d="m20 20-3.5-3.5" />
    </svg>
  ),
  arrow: (props) => (
    <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M5 12h14M13 6l6 6-6 6" />
    </svg>
  ),
  spark: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" {...props}>
      <path d="M12 2l1.6 5.4L19 9l-5.4 1.6L12 16l-1.6-5.4L5 9l5.4-1.6L12 2z" />
    </svg>
  ),
  pin: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M12 22s7-7.5 7-13a7 7 0 1 0-14 0c0 5.5 7 13 7 13z" /><circle cx="12" cy="9" r="2.5" />
    </svg>
  ),
  check: (props) => (
    <svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M5 12l5 5L20 7" />
    </svg>
  ),
  tag: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M3 12V4h8l10 10-8 8L3 12z" /><circle cx="7.5" cy="7.5" r="1.2" fill="currentColor" />
    </svg>
  ),
  shield: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M12 3l8 3v6c0 5-3.5 8.5-8 9-4.5-.5-8-4-8-9V6l8-3z" />
    </svg>
  ),
  bolt: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="currentColor" {...props}>
      <path d="M13 2L4 14h6l-1 8 9-12h-6l1-8z" />
    </svg>
  ),
  pulse: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M3 12h4l2-6 4 12 2-6h6" />
    </svg>
  ),
  instagram: (props) => (
    <svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <rect x="3" y="3" width="18" height="18" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none" />
    </svg>
  ),
  external: (props) => (
    <svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>
      <path d="M14 4h6v6M20 4l-9 9M19 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h5" />
    </svg>
  ),
};

/* ---------- Brand mark ---------- */
function BrandMark({ size = 28 }) {
  // Original mark: a stylised compass/north-star — nordic, search-y. Not derivative.
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 10 }}>
      <svg viewBox="0 0 32 32" width={size} height={size} aria-hidden="true">
        <circle cx="16" cy="16" r="14.5" fill="none" stroke="var(--ink)" strokeWidth="1.2" />
        <path d="M16 4 L18.2 14.2 L28 16 L18.2 17.8 L16 28 L13.8 17.8 L4 16 L13.8 14.2 Z"
              fill="var(--accent)" stroke="var(--ink)" strokeWidth="1" strokeLinejoin="round" />
        <circle cx="16" cy="16" r="1.6" fill="var(--surface)" stroke="var(--ink)" strokeWidth="0.8" />
      </svg>
      <span style={{ fontFamily: "'Instrument Serif', serif", fontSize: 22, letterSpacing: "-0.02em", color: "var(--ink)" }}>
        Only<i style={{ fontStyle: "italic" }}>Suomi</i>Haku
      </span>
    </span>
  );
}

/* ---------- Count-up number ---------- */
function CountUp({ value, duration = 1400, format = (n) => n.toLocaleString("fi-FI") }) {
  const [n, setN] = useState(0);
  const startRef = useRef(null);
  const rafRef = useRef(0);
  useEffect(() => {
    cancelAnimationFrame(rafRef.current);
    startRef.current = null;
    const step = (t) => {
      if (startRef.current === null) startRef.current = t;
      const p = Math.min(1, (t - startRef.current) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setN(Math.round(value * eased));
      if (p < 1) rafRef.current = requestAnimationFrame(step);
    };
    rafRef.current = requestAnimationFrame(step);
    return () => cancelAnimationFrame(rafRef.current);
  }, [value, duration]);
  return <span>{format(n)}</span>;
}

/* ---------- Live ticker dot ---------- */
function LiveDot() {
  return (
    <span style={{ position: "relative", display: "inline-flex", width: 8, height: 8 }}>
      <span style={{
        position: "absolute", inset: 0, borderRadius: 999, background: "var(--accent)", opacity: 0.4,
        animation: "oshPing 1.6s ease-out infinite",
      }} />
      <span style={{ position: "absolute", inset: 0, borderRadius: 999, background: "var(--accent)" }} />
      <style>{`@keyframes oshPing { 0%{transform:scale(1);opacity:.5} 100%{transform:scale(3);opacity:0} }`}</style>
    </span>
  );
}

/* ---------- Stylised silhouette avatar (placeholder, original) ---------- */
function SilhouetteAvatar({ seed = 0, size = 28, style }) {
  // Generate a small abstract geometric "person" silhouette from seed — no real imagery.
  const palettes = [
    ["#cfdcef", "#3a6ea8"],
    ["#e3d7f0", "#6b5aa0"],
    ["#f0d7d7", "#a85a5a"],
    ["#d7eee2", "#3f8a72"],
    ["#efe2cf", "#a8763a"],
    ["#d7e6f0", "#4a7d99"],
  ];
  const [bg, fg] = palettes[Math.abs(seed) % palettes.length];
  return (
    <svg viewBox="0 0 40 40" width={size} height={size} aria-hidden="true" style={style}>
      <rect width="40" height="40" rx="20" fill={bg} />
      <circle cx="20" cy="16" r="6" fill={fg} />
      <path d="M6 36 C6 26 14 22 20 22 C26 22 34 26 34 36 Z" fill={fg} />
    </svg>
  );
}

/* ---------- Portrait (full-body) silhouette placeholder ---------- */
function PortraitFigure({ seed = 0, w = 120, h = 200, fg, bg, style }) {
  return (
    <svg viewBox="0 0 60 100" width={w} height={h} aria-hidden="true"
         preserveAspectRatio="xMidYMax meet" style={style}>
      {/* head */}
      <circle cx="30" cy="22" r="10" fill={fg} />
      {/* neck + shoulders */}
      <path d="M24 32 L24 38 Q24 40 22 40 L12 44 Q8 46 8 52 L8 100 L52 100 L52 52 Q52 46 48 44 L38 40 Q36 40 36 38 L36 32 Z"
            fill={fg} />
      {/* subtle hair tuft (vary by seed) */}
      <ellipse cx={30 + ((seed % 5) - 2)} cy="14" rx={10 + (seed % 3)} ry="6" fill={fg} opacity="0.85" />
    </svg>
  );
}

/* ---------- Chip / pill ---------- */
function Chip({ children, onClick, count, trend, hot }) {
  const [hover, setHover] = useState(false);
  return (
    <button
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => setHover(false)}
      style={{
        display: "inline-flex", alignItems: "center", gap: 8,
        padding: "8px 14px",
        background: hover ? "var(--tag-bg-hover)" : "var(--tag-bg)",
        border: "1px solid var(--line)",
        borderRadius: 999,
        fontSize: 13.5, fontWeight: 500, color: "var(--ink-soft)",
        cursor: "pointer",
        transition: "all 160ms ease",
        boxShadow: hover ? "var(--shadow-sm)" : "none",
        transform: hover ? "translateY(-1px)" : "translateY(0)",
      }}
    >
      {hot ? <span style={{ color: "var(--accent)", display: "inline-flex" }}><Icon.bolt /></span> : null}
      <span>{children}</span>
      {count != null ? (
        <span style={{ color: "var(--muted)", fontVariantNumeric: "tabular-nums", fontSize: 12 }}>
          {formatCount(count)}
        </span>
      ) : null}
      {trend != null && trend > 5 ? (
        <span style={{
          fontSize: 10.5, color: "var(--accent)", background: "var(--accent-soft)",
          padding: "2px 6px", borderRadius: 6, fontWeight: 600, fontVariantNumeric: "tabular-nums",
        }}>+{trend}%</span>
      ) : null}
    </button>
  );
}

function formatCount(n) {
  if (n >= 1000) {
    const k = n / 1000;
    return (k >= 10 ? Math.round(k) : k.toFixed(1).replace(/\.0$/, "")) + "k";
  }
  return String(n);
}

Object.assign(window, {
  Icon, BrandMark, CountUp, LiveDot, SilhouetteAvatar, PortraitFigure, Chip, formatCount,
});
