// Primitives — Icon, Button, Badges, etc.
// Light remake of the design system primitives for our prototype.

const cn = (...c) => c.filter(Boolean).join(" ");

function Icon({ name, size = 16, className = "", strokeWidth = 1.75, style }) {
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!ref.current || !window.lucide) return;
    ref.current.innerHTML = "";
    const pascal = name.split("-").map(s => s[0].toUpperCase() + s.slice(1)).join("");
    const ic = (window.lucide.icons[pascal] || window.lucide.icons.Package);
    if (!ic) return;
    const el = window.lucide.createElement(ic);
    el.setAttribute("width", size);
    el.setAttribute("height", size);
    el.setAttribute("stroke-width", strokeWidth);
    ref.current.appendChild(el);
  }, [name, size, strokeWidth]);
  return <span ref={ref} className={cn("inline-flex items-center justify-center shrink-0", className)} style={{ width: size, height: size, ...style }} />;
}

function Button({ variant = "primary", size = "md", className = "", children, dataId, ...rest }) {
  const base = "inline-flex items-center justify-center gap-2 font-medium whitespace-nowrap transition-all disabled:opacity-50 disabled:pointer-events-none cursor-pointer select-none";
  const variants = {
    // v5: primary = ink-on-paper (black). Indigo only on accent variant.
    primary: "bg-[var(--ink)] text-[var(--paper)] hover:bg-[oklch(0.10_0.008_260)] active:scale-[0.985] shadow-[var(--elev-1)]",
    accent:  "bg-[var(--accent-1)] text-[var(--accent-1-fg)] hover:bg-[var(--accent-1-hover)] active:bg-[var(--accent-1-press)] active:scale-[0.985] shadow-[var(--elev-1)]",
    outline: "bg-[var(--surface)] text-[var(--ink)] border border-[var(--hairline-2)] hover:bg-[var(--surface-2)] hover:border-[var(--hairline-3)]",
    ghost:   "bg-transparent text-[var(--ink-2)] hover:bg-[var(--sunken)] hover:text-[var(--ink)]",
    success: "bg-[var(--positive)] text-white hover:opacity-90 active:scale-[0.985] shadow-[var(--elev-1)]",
    danger:  "bg-[var(--critical)] text-white hover:opacity-90 active:scale-[0.985]",
    subtle:  "bg-[var(--accent-1-tint)] text-[var(--accent-1-text)] hover:bg-[color-mix(in_oklch,var(--primary)_16%,transparent)]",
  };
  const sizes = {
    xs: "h-7 px-2.5 text-[12px] rounded-md",
    sm: "h-8 px-3 text-[13px] rounded-md",
    md: "h-9 px-3.5 text-[13.5px] rounded-md",
    lg: "h-10 px-5 text-[14px] rounded-md",
    icon: "h-9 w-9 rounded-md",
    "icon-sm": "h-8 w-8 rounded-md",
  };
  return <button data-id={dataId} className={cn(base, variants[variant], sizes[size], className)} {...rest}>{children}</button>;
}

function Card({ className = "", children, style, dataId }) {
  return (
    <div data-id={dataId} style={style}
      className={cn("bg-[var(--card)] border border-[var(--border)] rounded-[14px] shadow-[var(--elev-1)]", className)}>
      {children}
    </div>
  );
}

const STATUS_DOT_COLOR = {
  open:           { bg: "var(--positive)",  text: "var(--positive-text)", label: "Open" },
  approved:       { bg: "var(--positive)",  text: "var(--positive-text)", label: "Approved" },
  pending_review: { bg: "var(--caution)",   text: "var(--caution-text)",  label: "Pending Review" },
  pending:        { bg: "var(--caution)",   text: "var(--caution-text)",  label: "Pending" },
  cancelled:      { bg: "var(--critical)",  text: "var(--critical-text)", label: "Cancelled" },
  draft:          { bg: "var(--ink-4)",      text: "var(--ink-3)",         label: "Draft" },
  low:            { bg: "var(--caution)",   text: "var(--caution-text)",  label: "Low" },
};
function StatusBadge({ status, label }) {
  const v = STATUS_DOT_COLOR[status] || STATUS_DOT_COLOR.draft;
  return (
    <span className="inline-flex items-center gap-1.5 text-[12.5px] font-medium" style={{ color: v.text }}>
      <span style={{ width: 6, height: 6, borderRadius: 99, background: v.bg }} />
      {label || v.label}
    </span>
  );
}

function Pill({ kind = "neutral", children, className = "" }) {
  const tones = {
    neutral:    "bg-[var(--sunken)] text-[var(--ink-2)] border border-[var(--hairline)]",
    accent:     "bg-[var(--accent-1-tint)] text-[var(--accent-1-text)]",
    positive:   "bg-[var(--positive-tint)] text-[var(--positive-text)]",
    caution:    "bg-[var(--caution-tint)] text-[var(--caution-text)]",
    critical:   "bg-[var(--critical-tint)] text-[var(--critical-text)]",
    info:       "bg-[var(--info-tint)] text-[var(--info-text)]",
  };
  return (
    <span className={cn("inline-flex items-center gap-1.5 rounded-full px-2.5 h-[22px] text-[11.5px] font-medium tabular-nums", tones[kind], className)}>
      {children}
    </span>
  );
}

function Kbd({ children }) {
  return <span className="type-kbd inline-flex items-center justify-center min-w-[18px] h-[18px] px-1">{children}</span>;
}

function Avatar({ initials, size = 28, tint = "var(--accent-1-tint)", color = "var(--accent-1-text)" }) {
  return (
    <span style={{ width: size, height: size, background: tint, color, fontSize: size * 0.42, fontWeight: 600 }}
      className="inline-flex items-center justify-center rounded-full">
      {initials}
    </span>
  );
}

// CountUp - animates a number when value changes
function CountUp({ value, format = (n) => n.toLocaleString("en-IN"), duration = 600, prefix = "", suffix = "" }) {
  const [display, setDisplay] = React.useState(value);
  const prev = React.useRef(value);
  React.useEffect(() => {
    if (prev.current === value) { setDisplay(value); return; }
    const from = prev.current;
    const to = value;
    const start = performance.now();
    let raf;
    const tick = (t) => {
      const k = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - k, 3);
      const v = Math.round(from + (to - from) * eased);
      setDisplay(v);
      if (k < 1) raf = requestAnimationFrame(tick);
      else prev.current = to;
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [value, duration]);
  return <span className="tabular-nums">{prefix}{format(display)}{suffix}</span>;
}

// Spotlight — overlays a translucent dim on the WHOLE app, with a cutout around target rect
function Spotlight({ rect, padding = 8 }) {
  if (!rect) return null;
  const r = 10;
  const x = rect.x - padding, y = rect.y - padding;
  const w = rect.width + padding*2, h = rect.height + padding*2;
  return (
    <svg className="absolute inset-0 pointer-events-none" width="1920" height="1080" style={{ zIndex: 60 }}>
      <defs>
        <mask id="spot-mask">
          <rect width="1920" height="1080" fill="white"/>
          <rect x={x} y={y} width={w} height={h} rx={r} ry={r} fill="black"/>
        </mask>
      </defs>
      <rect width="1920" height="1080" fill="oklch(0.16 0.012 260 / 0.32)" mask="url(#spot-mask)"/>
      <rect x={x} y={y} width={w} height={h} rx={r} ry={r}
        fill="none" stroke="var(--accent-1)" strokeWidth="2"
        style={{ filter: "drop-shadow(0 0 16px oklch(0.54 0.21 268 / 0.55))" }}/>
    </svg>
  );
}

Object.assign(window, {
  cn, Icon, Button, Card, StatusBadge, Pill, Kbd, Avatar, CountUp, Spotlight, STATUS_DOT_COLOR,
});
