/* Shared UI atoms — Spec Compare */

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

/* ---------- Icons (simple strokes only) ---------- */
function Icn({ d, size = 16, sw = 1.8, style }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor"
    strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={style} aria-hidden="true">
      {d}
    </svg>);

}
const Icons = {
  search: (p) => <Icn {...p} d={<><circle cx="11" cy="11" r="7"></circle><path d="M16.5 16.5 21 21"></path></>} />,
  x: (p) => <Icn {...p} d={<><path d="M6 6l12 12"></path><path d="M18 6L6 18"></path></>} />,
  plus: (p) => <Icn {...p} d={<><path d="M12 5v14"></path><path d="M5 12h14"></path></>} />,
  check: (p) => <Icn {...p} d={<path d="M5 13l4 4L19 7"></path>} />,
  chevD: (p) => <Icn {...p} d={<path d="M6 9l6 6 6-6"></path>} />,
  chevR: (p) => <Icn {...p} d={<path d="M9 6l6 6-6 6"></path>} />,
  arrowL: (p) => <Icn {...p} d={<><path d="M19 12H5"></path><path d="M11 6l-6 6 6 6"></path></>} />,
  arrowR: (p) => <Icn {...p} d={<><path d="M5 12h14"></path><path d="M13 6l6 6-6 6"></path></>} />,
  swap: (p) => <Icn {...p} d={<><path d="M7 8h13"></path><path d="M17 4l3 4-3 4"></path><path d="M17 16H4"></path><path d="M7 12l-3 4 3 4"></path></>} />,
  doc: (p) => <Icn {...p} d={<><path d="M7 3h7l4 4v14H7z"></path><path d="M14 3v4h4"></path></>} />,
  link: (p) => <Icn {...p} d={<><path d="M9 15l6-6"></path><path d="M10.5 18.5l-2 2a3.5 3.5 0 0 1-5-5l3-3"></path><path d="M13.5 5.5l2-2a3.5 3.5 0 0 1 5 5l-3 3"></path></>} />,
  mail: (p) => <Icn {...p} d={<><rect x="3" y="5" width="18" height="14" rx="2"></rect><path d="M3 7l9 6 9-6"></path></>} />,
  sparkle: (p) => <Icn {...p} d={<><path d="M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"></path><path d="M19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8z"></path></>} />,
  send: (p) => <Icn {...p} d={<><path d="M21 3L10 14"></path><path d="M21 3l-7 18-4-7-7-4z"></path></>} />,
  clock: (p) => <Icn {...p} d={<><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 3"></path></>} />,
  eye: (p) => <Icn {...p} d={<><path d="M2 12s3.5-7 10-7 10 7 10 7-3.5 7-10 7-10-7-10-7z"></path><circle cx="12" cy="12" r="3"></circle></>} />,
  info: (p) => <Icn {...p} d={<><circle cx="12" cy="12" r="9"></circle><path d="M12 11v6"></path><path d="M12 7.5v.5"></path></>} />,
  bolt: (p) => <Icn {...p} d={<path d="M13 2L4 14h6l-1 8 9-12h-6z"></path>} />
};

/* Category icons — built from simple rects/lines (barcode-flavored) */
function CategoryIcon({ kind, size = 30 }) {
  const bars = (xs, h = 18, y = 3) => xs.map(([x, w], i) => <rect key={i} x={x} y={y} width={w} height={h} rx="0.6" fill="currentColor"></rect>);
  const inner = {
    decoded: <g>{bars([[3, 2], [7, 1.4], [10.5, 2.6], [15, 1.4], [18.5, 2.6]])}<path d="M3 24h18.5" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round"></path></g>,
    undecoded: <g opacity="0.95">{bars([[3, 2], [7, 1.4], [10.5, 2.6], [15, 1.4], [18.5, 2.6]])}<path d="M3 24c2.5-3 4 3 6.5 0s4 3 6.5 0 3.5 2.5 5.5 0" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round"></path></g>,
    compact: <g><rect x="6" y="6" width="12" height="12" rx="1.6" fill="none" stroke="currentColor" strokeWidth="1.8"></rect>{bars([[9, 1.2], [11.5, 0.9], [13.8, 1.6]], 6, 9)}<path d="M3 3h4M17 3h4M3 21h4M17 21h4" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round"></path></g>,
    customer: <g><rect x="4" y="4" width="16" height="11" rx="1.6" fill="none" stroke="currentColor" strokeWidth="1.8"></rect>{bars([[8, 1.4], [10.8, 1], [13.2, 1.8]], 5, 7)}<path d="M9 21h6M12 15v6" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"></path></g>,
    longrange: <g>{bars([[3, 2.2], [6.8, 1.4]], 10, 7)}<path d="M10 12h10" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeDasharray="2.5 2.5"></path><path d="M17 8l4 4-4 4" stroke="currentColor" strokeWidth="1.8" fill="none" strokeLinecap="round" strokeLinejoin="round"></path></g>,
    dpm: <g><circle cx="12" cy="12" r="9" fill="none" stroke="currentColor" strokeWidth="1.8"></circle>{[[9, 9], [12, 9], [15, 9], [9, 12], [15, 12], [9, 15], [12, 15]].map(([cx, cy], i) => <circle key={i} cx={cx} cy={cy} r="1.15" fill="currentColor"></circle>)}</g>
  };
  return <svg width={size} height={size} viewBox="0 0 24 24" aria-hidden="true">{inner[kind]}</svg>;
}

/* ---------- Brand chip ---------- */
function BrandChip({ brandId, size = "md" }) {
  const b = window.SPECDB.brands[brandId];
  return (
    <span className={"brandchip brandchip-" + size}>
      <span className="brandchip-mark" style={{ background: b.color, color: b.text }}>{b.name[0]}</span>
      <span className="brandchip-name">{b.name}</span>
    </span>);

}

/* ---------- Status badge ---------- */
function StatusBadge({ status }) {
  const cls = { New: "new", Active: "active", EOL: "eol" }[status] || "active";
  return <span className={"statusbadge statusbadge-" + cls}>{status}</span>;
}

/* ---------- Device image placeholder ---------- */
function DeviceImage({ product, h = 110 }) {
  /* Prefer the size-normalized local copy (images/products/<id>.png) so every
     engine renders at the same scale; fall back to the original Excel URL. */
  const hasLocal = window.SCANIQ_PRODUCT_IMAGES && window.SCANIQ_PRODUCT_IMAGES[product.id];
  const localSrc = "images/products/" + product.id + ".png";
  if (product.image || hasLocal) {
    return (
      <div className="devimg devimg-photo" style={{ height: h }}>
        <img
          src={hasLocal ? localSrc : product.image}
          alt={product.model}
          loading="lazy"
          onError={(e) => { if (product.image && e.target.src !== product.image) e.target.src = product.image; }}
        />
      </div>);
  }
  return (
    <div className="devimg" style={{ height: h }}>
      <span className="devimg-label">{product.model}</span>
      <span className="devimg-sub">device image</span>
    </div>);

}

/* ---------- Aimer pattern tile ---------- */
function AimerTile({ product, h = 64 }) {
  if (product.aimerView) {
    return (
      <div className="aimerimg" style={{ height: h }} title={product.specs.aimer}>
        <img src={product.aimerView} alt="Aimer pattern" loading="lazy" />
      </div>);
  }
  const ap = product.aimerPattern || { kind: "none", color: null };
  const c = ap.color;
  const glow = { filter: "drop-shadow(0 0 3px " + c + ")" };
  return (
    <div className="aimertile" style={{ height: h, alignItems: "center", justifyContent: "center", textAlign: "center", fontFamily: "\"IBM Plex Mono\"" }} title={product.specs.aimer}>
      <svg width="100%" height="100%" viewBox="0 0 64 44" preserveAspectRatio="xMidYMid meet" aria-hidden="true">
        {ap.kind === "line" ?
        <rect x="10" y="21" width="44" height="2" rx="1" fill={c} style={glow}></rect> :
        ap.kind === "crosshair" ?
        <g style={glow}>
            <rect x="16" y="21" width="32" height="1.8" rx="0.9" fill={c}></rect>
            <rect x="31.1" y="11" width="1.8" height="22" rx="0.9" fill={c}></rect>
          </g> :
        ap.kind === "4dot" ?
        <g style={glow}>
            <circle cx="16" cy="12" r="2.2" fill={c}></circle>
            <circle cx="48" cy="12" r="2.2" fill={c}></circle>
            <circle cx="16" cy="32" r="2.2" fill={c}></circle>
            <circle cx="48" cy="32" r="2.2" fill={c}></circle>
            <circle cx="32" cy="22" r="2.8" fill={c}></circle>
          </g> :
        ap.kind === "dot" ?
        <g style={glow}>
            <circle cx="32" cy="22" r="3.2" fill={c}></circle>
            <circle cx="32" cy="22" r="7" fill="none" stroke={c} strokeWidth="0.8" opacity="0.45"></circle>
          </g> :

        <text x="32" y="25" textAnchor="middle" fill="#7A828D" fontSize="7" fontFamily="IBM Plex Mono, monospace">no aimer</text>
        }
      </svg>
      <span className="aimertile-label">aimer</span>
    </div>);

}

/* ---------- Tooltip ---------- */
function Tip({ text, children }) {
  if (!text) return children;
  return (
    <span className="tipwrap">
      {children}
      <span className="tipbubble" role="tooltip">{text}</span>
    </span>);

}

/* ---------- Toasts ---------- */
window.toast = (msg, icon) => window.dispatchEvent(new CustomEvent("sc-toast", { detail: { msg, icon } }));
function ToastHost() {
  const [toasts, setToasts] = useState([]);
  useEffect(() => {
    const on = (e) => {
      const id = Date.now() + Math.random();
      setToasts((t) => [...t, { id, ...e.detail }]);
      setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 3200);
    };
    window.addEventListener("sc-toast", on);
    return () => window.removeEventListener("sc-toast", on);
  }, []);
  return (
    <div className="toasthost">
      {toasts.map((t) =>
      <div key={t.id} className="toast">
          <span className="toast-ic">{t.icon === "mail" ? <Icons.mail size={15} /> : t.icon === "doc" ? <Icons.doc size={15} /> : t.icon === "link" ? <Icons.link size={15} /> : <Icons.check size={15} />}</span>
          {t.msg}
        </div>
      )}
    </div>);

}

/* ---------- Product card ---------- */
function ProductCard({ product, selected, disabled, onToggle }) {
  const brand = window.SPECDB.brands[product.brand];
  return (
    <div className={"pcard" + (selected ? " pcard-selected" : "")}>
      <span className="pcard-brandbar" style={{ background: brand.color }}></span>
      <div className="pcard-imgwrap">
        <DeviceImage product={product} h={180} />
        {selected ? <span className="pcard-checkpop"><Icons.check size={16} /></span> : null}
        <div className="pcard-badges">
          {product.status !== "Active" ? <StatusBadge status={product.status} /> : null}
        </div>
      </div>
      <div className="pcard-body">
        <BrandChip brandId={product.brand} size="sm" />
        <div className="pcard-model">{product.model}</div>
        <ul className="pcard-specs">
          {product.preview.map((s, i) => <li key={i}>{s}</li>)}
        </ul>
        <button
          className={"btn " + (selected ? "btn-selected" : "btn-outline")}
          disabled={disabled && !selected}
          onClick={() => onToggle(product.id)}>
          
          {selected ? <><Icons.check size={14} /> Added</> : <><Icons.plus size={14} /> Add to compare</>}
        </button>
      </div>
    </div>);

}

/* ---------- Skeleton card (loading realism) ---------- */
function SkeletonCard() {
  return (
    <div className="pcard pcard-skeleton">
      <div className="sk sk-img"></div>
      <div className="pcard-body">
        <div className="sk sk-line" style={{ width: "40%" }}></div>
        <div className="sk sk-line" style={{ width: "65%", height: 16 }}></div>
        <div className="sk sk-line" style={{ width: "85%" }}></div>
        <div className="sk sk-line" style={{ width: "75%" }}></div>
        <div className="sk sk-btn"></div>
      </div>
    </div>);

}

Object.assign(window, { Icons, CategoryIcon, BrandChip, StatusBadge, DeviceImage, AimerTile, Tip, ToastHost, ProductCard, SkeletonCard });