// shared.jsx — icons, logo, primitives
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ── Inline SVG icon set (line-based, 1.5 stroke) ─────────────────
const Icon = ({ d, size = 16, stroke = 1.5, ...rest }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
       stroke="currentColor" strokeWidth={stroke}
       strokeLinecap="round" strokeLinejoin="round"
       aria-hidden="true" {...rest}>
    {typeof d === "string" ? <path d={d} /> : d}
  </svg>
);

const I = {
  Search:   (p) => <Icon size={p?.size} d="M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16Zm6-2 4 4" {...p} />,
  Plus:     (p) => <Icon size={p?.size} d="M12 5v14M5 12h14" {...p} />,
  Close:    (p) => <Icon size={p?.size} d="M6 6l12 12M6 18 18 6" {...p} />,
  Folder:   (p) => <Icon size={p?.size} d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Z" {...p} />,
  FolderOpen: (p) => <Icon size={p?.size} d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2H5l-2 9V7Zm0 0 2 11h14a2 2 0 0 0 2-2V9" {...p} />,
  Tag:      (p) => <Icon size={p?.size} d="M3 12V5a2 2 0 0 1 2-2h7l9 9-9 9-9-9Zm5-4a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z" {...p} />,
  Chevron:  (p) => <Icon size={p?.size} d="m9 6 6 6-6 6" {...p} />,
  Trash:    (p) => <Icon size={p?.size} d="M4 7h16M9 7V5a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2m1 0v12a2 2 0 0 1-2 2h-6a2 2 0 0 1-2-2V7h10Z" {...p} />,
  Move:     (p) => <Icon size={p?.size} d="M5 9 2 12l3 3M9 5l3-3 3 3M15 19l-3 3-3-3M19 9l3 3-3 3M2 12h20M12 2v20" {...p} />,
  Sun:      (p) => <Icon size={p?.size} d="M12 4v2m0 12v2M4 12H2m20 0h-2M5.6 5.6 4.2 4.2m15.6 15.6-1.4-1.4M5.6 18.4 4.2 19.8M19.8 4.2l-1.4 1.4M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8Z" {...p} />,
  Moon:     (p) => <Icon size={p?.size} d="M20 14.5A8 8 0 0 1 9.5 4a8 8 0 1 0 10.5 10.5Z" {...p} />,
  Menu:     (p) => <Icon size={p?.size} d="M4 6h16M4 12h16M4 18h16" {...p} />,
  List:     (p) => <Icon size={p?.size} d="M4 6h16M4 12h16M4 18h16" stroke={2.5} {...p} />,
  Grid:     (p) => <Icon size={p?.size} d="M4 5h6v6H4zM14 5h6v6h-6zM4 15h6v6H4zM14 15h6v6h-6z" {...p} />,
  ArrowR:   (p) => <Icon size={p?.size} d="M5 12h14m-5-5 5 5-5 5" {...p} />,
  ArrowL:   (p) => <Icon size={p?.size} d="M19 12H5m5 5-5-5 5-5" {...p} />,
  External: (p) => <Icon size={p?.size} d="M14 5h5v5M19 5l-9 9M11 5H6a2 2 0 0 0-2 2v11a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2v-5" {...p} />,
  Star:     (p) => <Icon size={p?.size} d="m12 3 2.7 5.7 6.3.9-4.6 4.4 1.2 6.3L12 17l-5.6 3.3 1.2-6.3L3 9.6l6.3-.9L12 3Z" {...p} />,
  Check:    (p) => <Icon size={p?.size} d="m5 13 4 4L19 7" {...p} />,
  Clock:    (p) => <Icon size={p?.size} d="M12 8v4l3 2m6-2a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" {...p} />,
  Bolt:     (p) => <Icon size={p?.size} d="m13 3-9 11h7l-1 7 9-11h-7l1-7Z" {...p} />,
  Lock:     (p) => <Icon size={p?.size} d="M6 11V8a6 6 0 1 1 12 0v3M5 11h14a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1Z" {...p} />,
  Globe:    (p) => <Icon size={p?.size} d="M12 3v18M3 12h18M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Zm-4 0c0 5-2 9-5 9s-5-4-5-9 2-9 5-9 5 4 5 9Z" {...p} />,
  Cloud:    (p) => <Icon size={p?.size} d="M7 18a5 5 0 1 1 0-10 6 6 0 0 1 11.7 1A4 4 0 0 1 18 18H7Z" {...p} />,
  Import:   (p) => <Icon size={p?.size} d="M12 3v12m0 0-4-4m4 4 4-4M4 17v2a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-2" {...p} />,
  Export:   (p) => <Icon size={p?.size} d="M12 21V9m0 0-4 4m4-4 4 4M4 7V5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2" {...p} />,
  Logout:   (p) => <Icon size={p?.size} d="M15 3h3a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-3M10 17l-5-5 5-5M5 12h12" {...p} />,
  Settings: (p) => <Icon size={p?.size} 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-1.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.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1.1 1.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.3h.1a1.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.8v.1a1.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 M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" {...p} />,
  Pin:      (p) => <Icon size={p?.size} d="M12 17v5M5 11l7-8 7 8-3 1v5l-4 1-4-1v-5l-3-1Z" {...p} />,
  Sparkle:  (p) => <Icon size={p?.size} d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.1 2.1M16.3 16.3l2.1 2.1M5.6 18.4l2.1-2.1M16.3 7.7l2.1-2.1" {...p} />,
  Eye:      (p) => <Icon size={p?.size} d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7Z M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z" {...p} />,
  Mail:     (p) => <Icon size={p?.size} d="M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7Zm0 0 9 7 9-7" {...p} />,
};

// ── Brand mark ────────────────────────────────────────────────────
function BrandMark({ size = 22, accent }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
      <path d="M6 3h12v18l-6-4.5L6 21V3Z"
            fill={accent || "var(--accent)"}
            stroke="var(--ink)"
            strokeWidth="1.5"
            strokeLinejoin="round"
            strokeLinecap="round"/>
      <path d="M10 8h4M10 11h4" stroke="var(--accent-ink, white)" strokeWidth="1.5" strokeLinecap="round" opacity="0.85"/>
    </svg>
  );
}

function Brand({ size = 22 }) {
  return (
    <span className="brand">
      <span className="brand-mark"><BrandMark size={size} /></span>
      <span className="brand-name">B<span className="dot"></span>UKMAK</span>
    </span>
  );
}

// ── Browser logos ────────────────────────────────────────────────
const BrowserLogo = {
  Chrome: ({ size = 22 }) => (
    <svg width={size} height={size} viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
      <circle cx="24" cy="24" r="22" fill="#fff"/>
      <path d="M24 6a18 18 0 0 1 15.6 9H24a9 9 0 0 0-8.5 12.1L8 13.5A18 18 0 0 1 24 6Z" fill="#EA4335"/>
      <path d="M24 42a18 18 0 0 1-15.6-9l7.6-13.1A9 9 0 0 0 24 33h.1l-7.7 8.7c2.4.8 5 1.3 7.6 1.3Z" fill="#34A853"/>
      <path d="M39.6 15H24l-7.6 13.1A9 9 0 0 1 24.1 15h15.5Z" fill="#FBBC05"/>
      <path d="M42 24a18 18 0 0 1-25.6 17.7L24 33a9 9 0 0 0 8.4-6 9 9 0 0 0-.8-6.9L39.6 15A17.9 17.9 0 0 1 42 24Z" fill="#4285F4"/>
      <circle cx="24" cy="24" r="6.5" fill="#fff"/>
      <circle cx="24" cy="24" r="5" fill="#4285F4"/>
    </svg>
  ),
  Firefox: ({ size = 22 }) => (
    <svg width={size} height={size} viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <radialGradient id="ffa" cx="60%" cy="60%" r="80%">
          <stop offset="0%" stopColor="#FFCD3F"/>
          <stop offset="40%" stopColor="#FF7139"/>
          <stop offset="80%" stopColor="#E5252C"/>
        </radialGradient>
      </defs>
      <path d="M40 18c1 4 1 8-1 13a17 17 0 1 1-30-12C12 25 16 27 21 26c-4-2-7-7-3-13 2 5 7 6 11 4 4-3 8 0 11 1Z" fill="url(#ffa)"/>
    </svg>
  ),
  Edge: ({ size = 22 }) => (
    <svg width={size} height={size} viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <linearGradient id="ed1" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#0FA7DF"/>
          <stop offset="100%" stopColor="#0078D4"/>
        </linearGradient>
        <linearGradient id="ed2" x1="0" y1="0" x2="1" y2="1">
          <stop offset="0%" stopColor="#33D462"/>
          <stop offset="100%" stopColor="#1B7A3F"/>
        </linearGradient>
      </defs>
      <path d="M40 30c-2 7-9 12-17 12-5 0-9-2-12-5 4 3 11 1 13-5-3-1-8-3-9-9 0-6 6-10 11-10 11 0 17 8 14 17Z" fill="url(#ed1)"/>
      <path d="M24 6a18 18 0 0 1 17 13c-5-4-15-7-23-2-5 3-7 7-7 11-1-3-1-6 0-9C13 11 18 6 24 6Z" fill="url(#ed2)"/>
    </svg>
  ),
};

// ── useToast ──────────────────────────────────────────────────────
function useToast() {
  const [toasts, setToasts] = useState([]);
  const push = useCallback((msg, kind) => {
    const id = Math.random().toString(36).slice(2);
    setToasts((t) => [...t, { id, msg, kind }]);
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2400);
  }, []);
  const node = (
    <div className="toast-wrap" role="status" aria-live="polite">
      {toasts.map((t) => (
        <div key={t.id} className={`toast ${t.kind || ""}`}>{t.msg}</div>
      ))}
    </div>
  );
  return [node, push];
}

// ── Modal primitive ───────────────────────────────────────────────
function Modal({ open, onClose, title, subtitle, children, footer, width }) {
  useEffect(() => {
    if (!open) return;
    const onKey = (e) => { if (e.key === "Escape") onClose?.(); };
    document.addEventListener("keydown", onKey);
    return () => document.removeEventListener("keydown", onKey);
  }, [open, onClose]);
  if (!open) return null;
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={width ? { maxWidth: width } : null} onClick={(e) => e.stopPropagation()}>
        {(title || subtitle) && (
          <div className="modal-hd">
            {title && <h2 className="modal-title">{title}</h2>}
            {subtitle && <p className="modal-sub">{subtitle}</p>}
          </div>
        )}
        <div className="modal-body">{children}</div>
        {footer && <div className="modal-ft">{footer}</div>}
      </div>
    </div>
  );
}

// ── Favicon helper ────────────────────────────────────────────────
function faviconFor(url) {
  try {
    const host = new URL(url).hostname;
    return `https://www.google.com/s2/favicons?domain=${host}&sz=64`;
  } catch { return null; }
}
function hostOf(url) {
  try { return new URL(url).hostname.replace(/^www\./, ""); } catch { return url; }
}
function relTime(iso) {
  const d = new Date(iso);
  const diff = Math.round((Date.now() - d.getTime()) / 86400000);
  if (diff <= 0) return "Today";
  if (diff === 1) return "Yesterday";
  if (diff < 7) return `${diff}d ago`;
  if (diff < 30) return `${Math.round(diff/7)}w ago`;
  if (diff < 365) return `${Math.round(diff/30)}mo ago`;
  return `${Math.round(diff/365)}y ago`;
}

// Export to window
Object.assign(window, {
  Icon, I, BrandMark, Brand, BrowserLogo,
  useToast, Modal, faviconFor, hostOf, relTime,
});
