/* ============================================================
   Media SOP — Shared UI primitives
   ============================================================ */
const { useState, useEffect, useRef, useMemo } = React;

// ---- Icon set (curated line icons) ----
const ICON_PATHS = {
  dashboard: "M3 3h7v8H3zM14 3h7v5h-7zM14 12h7v9h-7zM3 14h7v7H3z",
  kanban: "M4 4h4v16H4zM10 4h4v10h-4zM16 4h4v13h-4z",
  order: "M9 5H7a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2h-2M9 5a2 2 0 0 0 2 2h2a2 2 0 0 0 2-2M9 5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2M9 12h6M9 16h4",
  inbox: "M22 12h-6l-2 3h-4l-2-3H2M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",
  star: "M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z",
  check: "M20 6L9 17l-5-5",
  checkCircle: "M22 11.08V12a10 10 0 1 1-5.93-9.14M22 4L12 14.01l-3-3",
  clock: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 6v6l4 2",
  users: "M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2M9 11a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75",
  trophy: "M6 9H4.5a2.5 2.5 0 0 1 0-5H6M18 9h1.5a2.5 2.5 0 0 0 0-5H18M4 22h16M10 14.66V17c0 .55-.47.98-.97 1.21C7.85 18.75 7 20.24 7 22M14 14.66V17c0 .55.47.98.97 1.21C16.15 18.75 17 20.24 17 22M18 2H6v7a6 6 0 0 0 12 0V2z",
  bell: "M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0",
  send: "M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z",
  film: "M2 2h20v20H2zM7 2v20M17 2v20M2 12h20M2 7h5M2 17h5M17 17h5M17 7h5",
  video: "M23 7l-7 5 7 5V7zM14 5H3a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V7a2 2 0 0 0-2-2z",
  sparkles: "M12 3l1.9 5.8L20 10l-6.1 1.2L12 17l-1.9-5.8L4 10l6.1-1.2L12 3z",
  trendUp: "M23 6l-9.5 9.5-5-5L1 18M17 6h6v6",
  calendar: "M8 2v4M16 2v4M3 10h18M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z",
  plus: "M12 5v14M5 12h14",
  x: "M18 6L6 18M6 6l12 12",
  edit: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7M18.5 2.5a2.12 2.12 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z",
  search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.35-4.35",
  filter: "M22 3H2l8 9.46V19l4 2v-8.54L22 3z",
  arrowRight: "M5 12h14M12 5l7 7-7 7",
  chevronRight: "M9 18l6-6-6-6",
  chevronDown: "M6 9l6 6 6-6",
  menu: "M3 12h18M3 6h18M3 18h18",
  link: "M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71",
  upload: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12",
  alert: "M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0zM12 9v4M12 17h.01",
  flame: "M8.5 14.5A2.5 2.5 0 0 0 11 12c0-1.38-.5-2-1-3-1.072-2.143-.224-4.054 2-6 .5 2.5 2 4.9 4 6.5 2 1.6 3 3.5 3 5.5a7 7 0 1 1-14 0c0-1.153.433-2.294 1-3a2.5 2.5 0 0 0 2.5 2.5z",
  target: "M12 22a10 10 0 1 0 0-20 10 10 0 0 0 0 20zM12 18a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM12 14a2 2 0 1 0 0-4 2 2 0 0 0 0 4z",
  briefcase: "M20 7h-4V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v2H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2zM8 7V5h8v2",
  message: "M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",
  zap: "M13 2L3 14h9l-1 8 10-12h-9l1-8z",
  layers: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5",
  logout: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9",
  scissors: "M6 9a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM6 21a3 3 0 1 0 0-6 3 3 0 0 0 0 6zM20 4L8.12 15.88M14.47 14.48L20 20M8.12 8.12L12 12",
};

function Icon({ name, size = 20, color = "currentColor", strokeWidth = 2, fill = "none", style }) {
  const p = ICON_PATHS[name];
  if (!p) return null;
  const solid = fill !== "none";
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={solid ? color : "none"}
         stroke={solid ? "none" : color} strokeWidth={strokeWidth} strokeLinecap="round"
         strokeLinejoin="round" style={style}>
      {p.split("M").filter(Boolean).map((seg, i) => <path key={i} d={"M" + seg} />)}
    </svg>
  );
}

function Avatar({ name, color, size = 36, fontSize }) {
  return (
    <div className="avatar" style={{ width: size, height: size, background: color || "var(--violet-500)", fontSize: fontSize || size * 0.38 }}>
      {initials(name)}
    </div>
  );
}

function Badge({ children, cls = "badge-gray", dot }) {
  return <span className={"badge " + cls}>{dot && <span className="dot" />}{children}</span>;
}

function VChip({ vtype }) {
  const v = VIDEO_TYPES[vtype];
  return <span className={"vchip " + v.cls}>{v.code === "QUAY" ? "QUAY" : v.code === "LIVE" ? "LIVE" : v.code}</span>;
}

function PriorityBadge({ p }) {
  const pr = PRIORITIES[p];
  return <Badge cls={pr.cls} dot>{pr.label}</Badge>;
}

function Stars({ value = 0, size = 16, onChange }) {
  const [hover, setHover] = useState(0);
  return (
    <span className="stars">
      {[1,2,3,4,5].map(i => {
        const on = (hover || value) >= i;
        return (
          <span key={i} className={"star" + (on ? " on" : "") + (onChange ? " click" : "")}
            onMouseEnter={() => onChange && setHover(i)}
            onMouseLeave={() => onChange && setHover(0)}
            onClick={() => onChange && onChange(i)}>
            <Icon name="star" size={size} fill={on ? "var(--amber)" : "none"} color={on ? "var(--amber)" : "var(--line-2)"} />
          </span>
        );
      })}
    </span>
  );
}

function Btn({ children, variant = "primary", sm, block, icon, iconRight, onClick, disabled, type = "button", style }) {
  return (
    <button type={type} disabled={disabled} onClick={onClick} style={style}
      className={`btn btn-${variant}${sm ? " btn-sm" : ""}${block ? " btn-block" : ""}`}>
      {icon && <Icon name={icon} size={sm ? 15 : 17} />}
      {children}
      {iconRight && <Icon name={iconRight} size={sm ? 15 : 17} />}
    </button>
  );
}

function Modal({ title, sub, icon, onClose, children, footer, wide }) {
  useEffect(() => {
    const h = (e) => e.key === "Escape" && onClose();
    window.addEventListener("keydown", h);
    return () => window.removeEventListener("keydown", h);
  }, []);
  return (
    <div className="modal-scrim" onMouseDown={(e) => e.target === e.currentTarget && onClose()}>
      <div className={"modal" + (wide ? " modal-wide" : "")}>
        <div className="modal-h">
          {icon && <div className="brand-mark" style={{ width: 36, height: 36, borderRadius: 10 }}><Icon name={icon} size={19} /></div>}
          <div style={{ flex: 1 }}>
            <h3 style={{ fontSize: 17, fontWeight: 700 }}>{title}</h3>
            {sub && <div className="page-sub" style={{ display: "block" }}>{sub}</div>}
          </div>
          <button className="icon-btn" onClick={onClose}><Icon name="x" size={19} /></button>
        </div>
        <div className="modal-b">{children}</div>
        {footer && <div className="modal-f">{footer}</div>}
      </div>
    </div>
  );
}

// progress ring (circle only — allowed)
function Ring({ value, size = 64, stroke = 8, color = "var(--violet-500)", track = "var(--violet-100)", label }) {
  const r = (size - stroke) / 2;
  const c = 2 * Math.PI * r;
  const off = c * (1 - Math.max(0, Math.min(1, value)));
  return (
    <div className="ring-wrap" style={{ width: size, height: size }}>
      <svg width={size} height={size} style={{ transform: "rotate(-90deg)" }}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={track} strokeWidth={stroke} />
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke}
          strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round" style={{ transition: "stroke-dashoffset .6s ease" }} />
      </svg>
      {label && <div className="ring-val" style={{ fontSize: size * 0.24 }}>{label}</div>}
    </div>
  );
}

// sparkline / bar chart using rects (allowed)
function BarChart({ data, height = 90, color = "var(--violet-500)", baseline }) {
  const max = Math.max(...data, baseline || 0) * 1.05;
  const min = Math.min(...data, baseline || Infinity) * 0.92;
  return (
    <svg width="100%" height={height} viewBox={`0 0 ${data.length * 40} ${height}`} preserveAspectRatio="none">
      {baseline != null && (() => {
        const y = height - ((baseline - min) / (max - min)) * height;
        return <line x1="0" y1={y} x2={data.length*40} y2={y} stroke="var(--line-2)" strokeWidth="1.5" strokeDasharray="5 4" />;
      })()}
      {data.map((v, i) => {
        const h = ((v - min) / (max - min)) * (height - 12);
        return <rect key={i} x={i*40 + 9} y={height - h} width={22} height={h} rx={5}
          fill={color} opacity={i === data.length-1 ? 1 : 0.45} />;
      })}
    </svg>
  );
}

// horizontal stacked-ish meter
function Meter({ value, color = "var(--violet-500)", height = 8 }) {
  return <div className="bar" style={{ height }}><span style={{ width: Math.min(100, value*100) + "%", background: color }} /></div>;
}

function Empty({ icon, title, desc, action }) {
  return (
    <div className="empty">
      <div className="empty-ic"><Icon name={icon} size={28} /></div>
      <div style={{ fontWeight: 700, fontSize: 16, color: "var(--ink)" }}>{title}</div>
      {desc && <div style={{ fontSize: 13.5, marginTop: 6, maxWidth: 360, margin: "6px auto 0" }}>{desc}</div>}
      {action && <div style={{ marginTop: 18 }}>{action}</div>}
    </div>
  );
}

function StageBadge({ stage }) {
  const s = STAGE_MAP[stage];
  return <Badge cls="badge-gray" dot><span style={{ color: s.color }}>●</span>&nbsp;{s.label}</Badge>;
}

Object.assign(window, { Icon, Avatar, Badge, VChip, PriorityBadge, Stars, Btn, Modal, Ring, BarChart, Meter, Empty, StageBadge });
