// Shared icons + primitives. All icons are stroke-based, currentColor.

// Viewport hook — returns true when below `bp` px wide. Used to switch inline
// grid/padding values that would otherwise win against any CSS media query.
const useIsMobile = (bp = 768) => {
  const get = () => typeof window !== "undefined" && window.innerWidth < bp;
  const [m, setM] = React.useState(get);
  React.useEffect(() => {
    const onR = () => setM(get());
    window.addEventListener("resize", onR);
    return () => window.removeEventListener("resize", onR);
  }, [bp]);
  return m;
};

const Icon = ({ name, size = 18, ...rest }) => {
  const s = size;
  const props = { width: s, height: s, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.6, strokeLinecap: "round", strokeLinejoin: "round", ...rest };
  switch (name) {
    case "home": return <svg {...props}><path d="M3 11l9-7 9 7"/><path d="M5 10v10h14V10"/></svg>;
    case "library": return <svg {...props}><path d="M4 4h6v16H4z"/><path d="M14 4h6v16h-6z"/><path d="M7 8h0M17 8h0"/></svg>;
    case "audit": return <svg {...props}><path d="M9 3h7l4 4v14H4V3h5z"/><path d="M9 3v5h7"/><path d="M8 14l2 2 5-5"/></svg>;
    case "api": return <svg {...props}><path d="M8 9l-5 3 5 3"/><path d="M16 9l5 3-5 3"/><path d="M14 5l-4 14"/></svg>;
    case "settings": return <svg {...props}><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1A1.7 1.7 0 0 0 9 19.4a1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1A1.7 1.7 0 0 0 4.6 9a1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3H9a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8V9a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>;
    case "search": return <svg {...props}><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.3-4.3"/></svg>;
    case "download": return <svg {...props}><path d="M12 4v12"/><path d="M7 11l5 5 5-5"/><path d="M5 20h14"/></svg>;
    case "upload": return <svg {...props}><path d="M12 20V8"/><path d="M7 13l5-5 5 5"/><path d="M5 4h14"/></svg>;
    case "copy": return <svg {...props}><rect x="9" y="9" width="11" height="11" rx="2"/><path d="M5 15V5a2 2 0 0 1 2-2h10"/></svg>;
    case "check": return <svg {...props}><path d="M5 12l5 5L20 7"/></svg>;
    case "x": return <svg {...props}><path d="M6 6l12 12M18 6L6 18"/></svg>;
    case "alert": return <svg {...props}><path d="M12 3l10 18H2L12 3z"/><path d="M12 10v5"/><circle cx="12" cy="18" r=".5" fill="currentColor"/></svg>;
    case "info": return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M12 8v.01"/><path d="M11 12h1v5h1"/></svg>;
    case "shield": return <svg {...props}><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3z"/></svg>;
    case "wcag": return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M8 9l4 1 4-1"/><path d="M12 10v4M9 18l3-4 3 4"/></svg>;
    case "brand": return <svg {...props}><path d="M12 3l3 5 6 .9-4.5 4.2 1 6L12 16l-5.5 3 1-6L3 8.9 9 8z"/></svg>;
    case "globe": return <svg {...props}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></svg>;
    case "lock": return <svg {...props}><rect x="4" y="11" width="16" height="10" rx="2"/><path d="M8 11V8a4 4 0 0 1 8 0v3"/></svg>;
    case "key": return <svg {...props}><circle cx="8" cy="14" r="4"/><path d="M11 13l9-9 2 2-3 3 2 2-3 3-2-2"/></svg>;
    case "mail": return <svg {...props}><rect x="3" y="5" width="18" height="14" rx="2"/><path d="M3 7l9 6 9-6"/></svg>;
    case "eye": return <svg {...props}><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></svg>;
    case "arrow-right": return <svg {...props}><path d="M5 12h14M13 6l6 6-6 6"/></svg>;
    case "arrow-up-right": return <svg {...props}><path d="M7 17L17 7M9 7h8v8"/></svg>;
    case "play": return <svg {...props}><path d="M6 4l14 8-14 8z" fill="currentColor"/></svg>;
    case "filter": return <svg {...props}><path d="M3 5h18M7 12h10M10 19h4"/></svg>;
    case "menu": return <svg {...props}><path d="M4 6h16M4 12h16M4 18h16"/></svg>;
    case "doc": return <svg {...props}><path d="M14 3H6v18h12V7z"/><path d="M14 3v4h4"/><path d="M9 13h6M9 17h4"/></svg>;
    case "fig": return <svg {...props}><circle cx="12" cy="12" r="3"/><path d="M9 3h6v6H9zM9 9h6v6H9zM9 15h3v6h-3z"/></svg>;
    case "code": return <svg {...props}><path d="M8 8l-4 4 4 4M16 8l4 4-4 4"/><path d="M14 4l-4 16"/></svg>;
    case "package": return <svg {...props}><path d="M12 3l9 5v8l-9 5-9-5V8l9-5z"/><path d="M3 8l9 5 9-5M12 13v10"/></svg>;
    case "image": return <svg {...props}><rect x="3" y="4" width="18" height="16" rx="2"/><circle cx="9" cy="10" r="2"/><path d="M21 16l-5-5-9 9"/></svg>;
    case "sparkles": return <svg {...props}><path d="M12 3l1.5 4.5L18 9l-4.5 1.5L12 15l-1.5-4.5L6 9l4.5-1.5z"/><path d="M19 15l.7 2L22 18l-2.3.7L19 21l-.7-2.3L16 18l2.3-1z"/></svg>;
    case "logout": return <svg {...props}><path d="M9 4H5v16h4"/><path d="M16 8l4 4-4 4M20 12H10"/></svg>;
    case "bell": return <svg {...props}><path d="M6 9a6 6 0 1 1 12 0c0 5 2 6 2 6H4s2-1 2-6z"/><path d="M10 19a2 2 0 0 0 4 0"/></svg>;
    case "external": return <svg {...props}><path d="M14 4h6v6"/><path d="M20 4l-9 9"/><path d="M19 14v5a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1h5"/></svg>;
    case "more": return <svg {...props}><circle cx="5" cy="12" r="1.4" fill="currentColor"/><circle cx="12" cy="12" r="1.4" fill="currentColor"/><circle cx="19" cy="12" r="1.4" fill="currentColor"/></svg>;
    case "star": return <svg {...props}><path d="M12 3l3 5 6 .9-4.5 4.2 1 6L12 16l-5.5 3 1-6L3 8.9 9 8z"/></svg>;
    case "git": return <svg {...props}><circle cx="6" cy="6" r="2.5"/><circle cx="6" cy="18" r="2.5"/><circle cx="18" cy="12" r="2.5"/><path d="M6 8.5v7M8.5 6h4a3 3 0 0 1 3 3v1.5"/></svg>;
    case "spinner": return <svg {...props} style={{animation: "spin 0.9s linear infinite"}}><path d="M12 3a9 9 0 1 0 9 9" /></svg>;
    case "chevron-down": return <svg {...props}><path d="M6 9l6 6 6-6"/></svg>;
    case "chevron-right": return <svg {...props}><path d="M9 6l6 6-6 6"/></svg>;
    case "trend-up": return <svg {...props}><path d="M3 17l6-6 4 4 8-8"/><path d="M14 7h7v7"/></svg>;
    default: return null;
  }
};

const Logo = ({ light = false, size = 16 }) => (
  <span className="wordmark" style={{ color: light ? "var(--bone)" : "var(--ink)", fontSize: size }}>
    <span className="wordmark-mark" style={{ width: size * 0.95, height: size * 0.95 }} />
    Graphite
  </span>
);

// Tiny SVG sparkline
const Sparkline = ({ data, color = "var(--accent)" }) => {
  const w = 100, h = 38, pad = 2;
  const max = Math.max(...data), min = Math.min(...data);
  const range = max - min || 1;
  const pts = data.map((v, i) => {
    const x = pad + (i / (data.length - 1)) * (w - pad * 2);
    const y = h - pad - ((v - min) / range) * (h - pad * 2);
    return `${x},${y}`;
  }).join(" ");
  const area = `M ${pad},${h} L ${pts.split(" ").join(" L ")} L ${w - pad},${h} Z`;
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${h}`} preserveAspectRatio="none">
      <path d={area} fill={color} fillOpacity="0.08" />
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" />
    </svg>
  );
};

// Donut score
const ScoreDonut = ({ score, size = 120, label = "Score" }) => {
  const r = size / 2 - 8;
  const c = 2 * Math.PI * r;
  const off = c - (score / 100) * c;
  const color = score >= 85 ? "var(--ok)" : score >= 65 ? "var(--warn)" : "var(--crit)";
  return (
    <div style={{ position: "relative", width: size, height: size, flexShrink: 0 }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} stroke="var(--line)" strokeWidth="6" fill="none" />
        <circle cx={size/2} cy={size/2} r={r} stroke={color} strokeWidth="6" fill="none"
          strokeDasharray={c} strokeDashoffset={off} strokeLinecap="round"
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: "stroke-dashoffset 1.2s ease" }} />
      </svg>
      <div style={{ position: "absolute", inset: 0, display: "grid", placeItems: "center", textAlign: "center" }}>
        <div>
          <div style={{ fontSize: size * 0.32, fontWeight: 500, letterSpacing: "-0.02em", lineHeight: 1 }}>{score}</div>
          <div className="eyebrow" style={{ marginTop: 4, fontSize: 10 }}>{label}</div>
        </div>
      </div>
    </div>
  );
};

// Toast/notification minimal
const Toast = ({ msg, onDone }) => {
  React.useEffect(() => {
    const t = setTimeout(onDone, 2200);
    return () => clearTimeout(t);
  }, []);
  return (
    <div style={{
      position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)",
      background: "var(--ink)", color: "var(--bone)", padding: "12px 20px",
      borderRadius: 999, fontSize: 13, zIndex: 9999, display: "flex", alignItems: "center", gap: 10,
      boxShadow: "0 8px 32px rgba(0,0,0,0.18)", animation: "fade-up 0.25s ease"
    }}>
      <Icon name="check" size={14} />
      {msg}
    </div>
  );
};

Object.assign(window, { Icon, Logo, Sparkline, ScoreDonut, Toast, useIsMobile });
