// accessories.jsx - Refurb Ping recommended accessories
// Reuses Logo / ProductIcon from art.jsx (loaded first).

const { useState, useEffect, useRef } = React;

// Placeholder thumbnail icons
// Monoline fallback icons for items without photos.

const stroke = { fill: "none", stroke: "var(--ink-3)", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round" };

const IconDock = () => (
  <svg viewBox="0 0 64 64" width="56" height="56" aria-hidden="true">
    {/* mini sitting on dock */}
    <rect x="20" y="14" width="24" height="15" rx="3.5" {...stroke} />
    <circle cx="32" cy="21.5" r="1.6" fill="var(--ink-4)" stroke="none" />
    {/* dock base */}
    <rect x="12" y="34" width="40" height="16" rx="4" {...stroke} />
    <line x1="20" y1="42" x2="26" y2="42" {...stroke} />
    <line x1="31" y1="42" x2="37" y2="42" {...stroke} />
    <circle cx="44" cy="42" r="1.8" fill="var(--ink-4)" stroke="none" />
  </svg>
);

const IconHubStand = () => (
  <svg viewBox="0 0 64 64" width="56" height="56" aria-hidden="true">
    {/* M.2 stick */}
    <rect x="20" y="16" width="24" height="9" rx="2" {...stroke} />
    <line x1="22" y1="25" x2="22" y2="22" {...stroke} />
    <line x1="26" y1="25" x2="26" y2="22" {...stroke} />
    {/* stand bar */}
    <rect x="10" y="34" width="44" height="9" rx="3.5" {...stroke} />
    <line x1="16" y1="38.5" x2="22" y2="38.5" {...stroke} />
    <circle cx="46" cy="38.5" r="1.8" fill="var(--ink-4)" stroke="none" />
    {/* feet */}
    <line x1="18" y1="43" x2="18" y2="49" {...stroke} />
    <line x1="46" y1="43" x2="46" y2="49" {...stroke} />
  </svg>
);

const IconAdapter = () => (
  <svg viewBox="0 0 64 64" width="56" height="56" aria-hidden="true">
    {/* hub body */}
    <rect x="8" y="26" width="34" height="15" rx="4" {...stroke} />
    <line x1="14" y1="33.5" x2="20" y2="33.5" {...stroke} />
    <line x1="24" y1="33.5" x2="30" y2="33.5" {...stroke} />
    <circle cx="36" cy="33.5" r="1.6" fill="var(--ink-4)" stroke="none" />
    {/* cable + plug */}
    <path d="M42 30 C 52 28, 53 19, 48 16" {...stroke} />
    <rect x="44" y="11" width="9" height="6" rx="1.5" {...stroke} />
  </svg>
);

const IconKeyboard = () => (
  <svg viewBox="0 0 64 64" width="56" height="56" aria-hidden="true">
    <rect x="8" y="21" width="48" height="22" rx="4" {...stroke} />
    <g fill="var(--ink-4)" stroke="none">
      {[15, 22, 29, 36, 43, 50].map((x) => <circle key={"a" + x} cx={x} cy="28" r="1.3" />)}
      {[15, 22, 29, 36, 43, 50].map((x) => <circle key={"b" + x} cx={x} cy="34" r="1.3" />)}
    </g>
    <rect x="22" y="37.5" width="20" height="2.6" rx="1.3" fill="var(--ink-4)" stroke="none" />
  </svg>
);

const IconTrackpad = () => (
  <svg viewBox="0 0 64 64" width="56" height="56" aria-hidden="true">
    <rect x="12" y="16" width="40" height="32" rx="6" {...stroke} />
    <line x1="20" y1="40" x2="44" y2="40" stroke="var(--ink-4)" strokeWidth="1.6" strokeLinecap="round" />
  </svg>
);

const ICONS = {
  dock: IconDock,
  hub: IconHubStand,
  adapter: IconAdapter,
  keyboard: IconKeyboard,
  trackpad: IconTrackpad,
};

// Data is injected by the server-rendered accessories.html template.

const ACCESSORIES_DATA = window.REFURBPING_ACCESSORIES || { items: {}, products: [] };
const ITEMS = ACCESSORIES_DATA.items || {};
const PRODUCTS = ACCESSORIES_DATA.products || [];

const DEVICE_NAME = { "mac-mini": "Mac mini", "mac-studio": "Mac Studio" };
const FILTERS = [
  { id: "all", label: "All accessories" },
  { id: "mac-mini", label: "Mac mini" },
  { id: "mac-studio", label: "Mac Studio" },
];
const FEATURED_ORDER = [
  "anker-7in1-usb-adapter",
  "nuphy-air75-v3-keyboard",
  "apple-magic-trackpad",
  "mac-mini-satechi-m4-dock",
  "satechi-hub-stand-ssd-enclosure",
];

function buildAccessoryRows() {
  const fitByKey = {};

  PRODUCTS.forEach((product) => {
    (product.keys || []).forEach((key) => {
      if (!fitByKey[key]) fitByKey[key] = [];
      if (!fitByKey[key].includes(product.id)) fitByKey[key].push(product.id);
    });
  });

  return Object.keys(fitByKey)
    .filter((key) => ITEMS[key])
    .map((key) => ({ key, item: ITEMS[key], fit: fitByKey[key] }))
    .sort((a, b) => {
      const aIndex = FEATURED_ORDER.includes(a.key) ? FEATURED_ORDER.indexOf(a.key) : FEATURED_ORDER.length;
      const bIndex = FEATURED_ORDER.includes(b.key) ? FEATURED_ORDER.indexOf(b.key) : FEATURED_ORDER.length;
      return aIndex - bIndex || a.item.title.localeCompare(b.item.title);
    });
}

const LIST = buildAccessoryRows();

// Components

function Nav() {
  return (
    <header className="nav">
      <div className="nav-inner">
        <a className="brand" href="/" aria-label="RefurbPing home">
          <Logo size={26} gap={8} />
        </a>
        <nav className="nav-links" aria-label="Primary">
          <a href="/#products">Products</a>
          <a href="/#alerts">Alerts</a>
          <a href="/#how">How it works</a>
          <a href="/accessories.html" aria-current="page" style={{ color: "var(--ink)" }}>Accessories</a>
        </nav>
        <div className="nav-cta" aria-hidden="true" style={{visibility:"hidden"}}>Sign in</div>
      </div>
    </header>
  );
}

function AccHero() {
  return (
    <section className="acc-hero">
      <div className="wrap">
        <div className="eyebrow">After the ping - gear we'd actually buy</div>
        <h1 className="h-display">Now make it yours.</h1>
        <p className="sub">
          You scored the refurb - here's the short list of accessories worth adding.
          Most work with both machines; the tag on each tells you what it fits. Every pick links straight to the buy page.
        </p>
      </div>
    </section>
  );
}

function FitTag({ fit }) {
  const both = fit.length > 1;
  return (
    <span className={`acc-tag ${both ? "both" : ""}`}>
      <span className="acc-tag-ic">
        {fit.map((kind) => <ProductIcon key={kind} kind={kind} size={15} />)}
      </span>
      {both ? "Works with both" : `${DEVICE_NAME[fit[0]] || fit[0]} only`}
    </span>
  );
}

function AccessoryCard({ item, fit }) {
  const Icon = ICONS[item.icon];
  return (
    <a className="acc-card" href={item.url} target="_blank" rel="noopener noreferrer">
      <div className="acc-thumb">
        {item.image ? (
          <img src={item.image} alt="" loading="lazy" decoding="async" />
        ) : (
          <Icon />
        )}
      </div>
      <div className="acc-info">
        <FitTag fit={fit} />
        <div className="acc-title">{item.title}</div>
        <div className="acc-reason">{item.reason}</div>
        <span className="acc-buy">
          View on Amazon
          <svg className="arrow" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
            <path d="M7 17 L17 7" />
            <path d="M9 7 h8 v8" />
          </svg>
        </span>
      </div>
    </a>
  );
}

function AccessoryList() {
  const [filter, setFilter] = useState("all");
  const rows = filter === "all" ? LIST : LIST.filter((row) => row.fit.includes(filter));

  return (
    <section className="acc-section" id="list">
      <div className="wrap-wide">
        <div className="filter-bar" role="tablist" aria-label="Filter accessories by machine">
          {FILTERS.map((option) => (
            <button
              key={option.id}
              role="tab"
              aria-selected={filter === option.id}
              className={`filter-chip ${filter === option.id ? "active" : ""}`}
              onClick={() => setFilter(option.id)}
              type="button"
            >
              {option.id !== "all" && <ProductIcon kind={option.id} size={17} />}
              {option.label}
            </button>
          ))}
          <span className="filter-count num">{rows.length} {rows.length === 1 ? "pick" : "picks"}</span>
        </div>
        <div className="acc-grid">
          {rows.map((row) => (
            <AccessoryCard key={row.key} item={row.item} fit={row.fit} />
          ))}
        </div>
      </div>
    </section>
  );
}

function Footer() {
  return (
    <footer>
      <div className="wrap-wide" style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, flexWrap: "wrap" }}>
        <a href="/" className="brand" style={{ fontSize: 13, textDecoration: "none" }}>
          <Logo size={18} gap={7} />
        </a>
        <div style={{ fontSize: 11.5, color: "var(--ink-4)" }}>
          Accessory picks are independent - we update them as configs change.
        </div>
        <div style={{ display: "inline-flex", alignItems: "center", gap: 8, fontSize: 12, color: "var(--ink-3)", background: "var(--surface)", border: "1px solid var(--hairline)", padding: "6px 12px", borderRadius: 999 }}>
          <span className="live-dot" aria-hidden="true"></span>
          <span>2026 Refurb Ping</span>
        </div>
      </div>
    </footer>
  );
}

function App() {
  return (
    <React.Fragment>
      <Nav />
      <AccHero />
      <AccessoryList />
      <Footer />
    </React.Fragment>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
