// sections.jsx — store domain shared UI (Nav, Footer, cards, finder/guide,
// filters, trust + disclosure atoms, error/empty states).
// Loaded after data.jsx, before app.jsx and the page file.

// ── icon helper (Lucide via unpkg, see index.html) ─────────────────────────
function Icon({ name, size = 18, className = "" }) {
  return <i data-lucide={name} className={`ic ${className}`} style={{ width: size, height: size }} />;
}

// ── star rating (Lucide icons, never a literal glyph) ──────────────────────
function Stars({ score, size = 13 }) {
  const rounded = Math.round(score);
  return (
    <span className="stars" aria-label={`${score.toFixed(1)} out of 5`}>
      {Array.from({ length: 5 }, (_, i) => (
        <Icon
          key={i}
          name="star"
          size={size}
          className={i < rounded ? "fg-gold star-filled" : "fg-muted star-empty"}
        />
      ))}
    </span>
  );
}

// ── layout atoms ────────────────────────────────────────────────────────
function Section({ id, className = "", children }) {
  return <section id={id} className={`section ${className}`}><div className="page">{children}</div></section>;
}

function Crumb({ trail }) {
  return (
    <nav className="crumb label-nav" aria-label="Breadcrumb">
      {trail.map((t, i) => (
        <span key={i}>
          {t.href ? <a href={t.href}>{t.label}</a> : <span className="crumb-cur">{t.label}</span>}
          {i < trail.length - 1 && <span className="crumb-sep">/</span>}
        </span>
      ))}
    </nav>
  );
}

// ── Nav ─────────────────────────────────────────────────────────────────
function Nav({ active, onOpenGuide }) {
  const links = [
    { href: "index.html", label: "Discover", key: "index" },
    { href: "plp.html", label: "Shop", key: "plp" },
    { href: "compare.html", label: "Compare", key: "compare" },
    { href: "cart.html", label: "Cart", key: "cart" },
  ];
  return (
    <header className="nav-root">
      <div className="nav-inner">
        <a className="brand-rule" href="index.html">
          <img className="ds-logo white" src="../../../tenants/aaas/brand/AaaS_Logo_White.png" alt="AaaS" />
          <img className="ds-logo black" src="../../../tenants/aaas/brand/AaaS_Logo_Black.png" alt="AaaS" />
          <span className="ds-seg">store</span>
        </a>
        <nav className="nav-links">
          {links.map((l) => (
            <a key={l.key} className={"nav-link" + (active === l.key ? " nav-link-on" : "")} href={l.href}>{l.label}</a>
          ))}
        </nav>
        <div style={{ display: "flex", gap: 10, alignItems: "center" }}>
          <button type="button" className="btn btn-outline btn-sm guide-trigger" onClick={onOpenGuide}>
            <Icon name="sparkles" size={14} /> Ask the guide
          </button>
        </div>
      </div>
      <div className="kinetic"><i /></div>
    </header>
  );
}

function Footer() {
  return (
    <footer className="store-footer">
      <div className="page footer-grid">
        <div>
          <div className="brand-rule" style={{ marginBottom: 14 }}>
            <span className="brand-pulse" />
            <span className="brand-text"><b>aaas</b>.store</span>
          </div>
          <p className="body-sm fg-muted" style={{ maxWidth: 320 }}>
            Curated agents, skills, templates and bundles. Some listings are ours, some are
            partners', some are providers we vet and hand you to. The mode is always on the card.
          </p>
        </div>
        <div>
          <div className="label-overline fg-muted foot-h">Shop</div>
          <a href="plp.html?category=agents">Agents</a>
          <a href="plp.html?category=skills">Skills</a>
          <a href="plp.html?category=templates">Templates</a>
          <a href="plp.html?category=bundles">Bundles</a>
        </div>
        <div>
          <div className="label-overline fg-muted foot-h">Trust</div>
          <a href="compare.html">Compare</a>
          <a href="cart.html">Cart</a>
          <a href="#disclosure">Disclosure policy</a>
          <a href="#returns">Returns</a>
        </div>
      </div>
    </footer>
  );
}

// ── mode vocabulary atoms ──────────────────────────────────────────────
function ModeChip({ mode, style = "solid" }) {
  const m = MODES[mode];
  return <span className={`mode-chip mode-${mode} chip-style-${style} label-overline`}><Icon name={mode === "buy" ? "shopping-bag" : mode === "partner" ? "handshake" : "external-link"} size={12} />{m.label}</span>;
}

function CTABlock({ item, showDisclosure = true, size = "" }) {
  if (item.mode === "buy") {
    return (
      <div className="cta-block">
        <a className={`btn btn-primary ${size}`} href={`cart.html?add=${item.id}`}><Icon name="shopping-bag" size={16} />Buy — ${item.price}</a>
      </div>
    );
  }
  if (item.mode === "partner") {
    return (
      <div className="cta-block">
        <a className={`btn btn-outline ${size}`} href={`handoff.html?item=${item.id}`}><Icon name="handshake" size={16} />Go to partner</a>
        {showDisclosure && <p className="disclosure-line body-sm">{item.disclosure}</p>}
      </div>
    );
  }
  return (
    <div className="cta-block">
      <a className={`btn btn-outline-red ${size}`} href={`handoff.html?item=${item.id}`}><Icon name="external-link" size={16} />Open provider</a>
      {showDisclosure && <p className="disclosure-line disclosure-red body-sm">{item.disclosure}</p>}
    </div>
  );
}

function PriceBlock({ item }) {
  return (
    <div className="price-block">
      <div className="price-main">{item.price != null ? `$${item.price}` : "Quoted"}<span className="price-unit body-sm fg-muted"> {item.unitPrice}</span></div>
      <div className="price-total body-sm fg-muted">{item.totalCostLine}</div>
    </div>
  );
}

function ReturnsSummary({ item }) {
  return (
    <div className="trust-row">
      <Icon name="rotate-ccw" size={15} className="fg-circuit" />
      <span className="body-sm">{item.returns}</span>
    </div>
  );
}

function ProviderReputation({ item }) {
  return (
    <div className="trust-row provider-rep">
      <Icon name="shield-check" size={15} className="fg-circuit" />
      <span className="body-sm">
        <b>{item.provider.name}</b> · <Stars score={item.provider.reputationScore} size={12} /> {item.provider.reputationScore.toFixed(1)} ({item.provider.reviewCount} reviews)
      </span>
    </div>
  );
}

function DisclosureLine({ item, className = "" }) {
  if (!item.disclosure) return null;
  return <p className={`disclosure-line body-sm ${className}`}><Icon name="info" size={13} />{item.disclosure}</p>;
}

// ── review list (staff reply + reviewer media) ─────────────────────────
function ReviewList({ reviews }) {
  return (
    <div className="review-list">
      {reviews.map((r) => (
        <article key={r.id} className="review-item">
          <div className="review-hd">
            <span className="review-stars"><Stars score={r.rating} /></span>
            <span className="body-sm fg-muted">{r.author} · {r.date}</span>
          </div>
          <p className="body-sm">{r.body}</p>
          {r.media && (
            <div className="reviewer-media" role="group" aria-label="Reviewer media">
              <div className="media-thumb"><Icon name="image" size={20} /></div>
              <span className="body-sm fg-muted">Reviewer media — {r.media}</span>
            </div>
          )}
          {r.staffReply && (
            <div className="staff-reply">
              <div className="label-overline fg-circuit">Staff reply</div>
              <p className="body-sm">{r.staffReply}</p>
            </div>
          )}
        </article>
      ))}
    </div>
  );
}

// ── spec table ──────────────────────────────────────────────────────────
function SpecTable({ specs, sticky = false }) {
  return (
    <div className="spec-table-wrap">
      <table className={"spec-table" + (sticky ? " spec-sticky" : "")}>
        <tbody>
          {Object.entries(specs).map(([k, v]) => (
            <tr key={k}><th scope="row">{k}</th><td>{v}</td></tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

// ── gallery placeholder (in-scale, browsable, zero remote images) ──────
function GalleryPlaceholder({ item }) {
  const [active, setActive] = React.useState(0);
  const slots = [0, 1, 2, 3];
  return (
    <div className="gallery">
      <div className="gallery-main">
        <div className="gallery-box" data-slot={active}>
          <Icon name="box" size={40} />
          <span className="label-overline fg-muted">{item.category} · in-scale placeholder</span>
        </div>
      </div>
      <div className="gallery-thumbs">
        {slots.map((s) => (
          <button key={s} type="button" className={"gallery-thumb" + (s === active ? " on" : "")} onClick={() => setActive(s)} aria-label={`View ${s + 1}`}>
            <Icon name="square" size={16} />
          </button>
        ))}
      </div>
    </div>
  );
}

// ── option selector (Baymard: button-style, not a dropdown) ────────────
function OptionSelector({ label, options, value, onChange }) {
  return (
    <div className="opt-select">
      <div className="label-overline fg-muted opt-label">{label}</div>
      <div className="opt-row">
        {options.map((o) => (
          <button key={o} type="button" className={"opt-btn" + (o === value ? " on" : "")} onClick={() => onChange(o)}>{o}</button>
        ))}
      </div>
    </div>
  );
}

// ── wishlist / guest save ───────────────────────────────────────────────
function WishlistButton({ itemId }) {
  const [saved, setSaved] = React.useState(false);
  return (
    <button type="button" className={"btn btn-outline btn-sm wishlist-btn" + (saved ? " on" : "")}
      onClick={() => setSaved((s) => !s)} aria-pressed={saved}>
      <Icon name={saved ? "heart" : "heart"} size={14} className={saved ? "fg-red" : ""} />
      {saved ? "Saved for later" : "Save for later (guest)"}
    </button>
  );
}

// ── sticky mobile CTA bar ───────────────────────────────────────────────
function StickyCTABar({ item }) {
  return (
    <div className="sticky-cta-bar">
      <div className="sticky-cta-price">
        <div className="body-sm fg-muted">{item.price != null ? `$${item.price}` : "Quoted"}</div>
        <div className="label-overline fg-muted">{item.totalCostLine}</div>
      </div>
      <CTABlock item={item} showDisclosure={false} size="btn-sm" />
    </div>
  );
}

// ── trust strip (index) ─────────────────────────────────────────────────
function TrustStrip() {
  const rows = [
    { icon: "rotate-ccw", label: "Returns", body: "14-day return on every buy-mode item, no questions asked." },
    { icon: "info", label: "Disclosure", body: "Partner and provider listings say so on the card, before the click." },
    { icon: "receipt", label: "Total cost", body: "Tax and fees estimated next to every price. No surprise at checkout." },
  ];
  return (
    <div className="trust-strip">
      {rows.map((r) => (
        <div key={r.label} className="trust-cell glass">
          <Icon name={r.icon} size={20} className="fg-circuit" />
          <div className="label-overline">{r.label}</div>
          <p className="body-sm fg-muted">{r.body}</p>
        </div>
      ))}
    </div>
  );
}

// ── error banner (generic, used once on pdp-provider) ───────────────────
function ErrorBanner({ title, message, onRetry }) {
  return (
    <div className="error-banner glass" role="alert">
      <Icon name="triangle-alert" size={20} className="fg-red" />
      <div>
        <div className="h4">{title}</div>
        <p className="body-sm fg-muted">{message}</p>
      </div>
      {onRetry && <button type="button" className="btn btn-outline btn-sm" onClick={onRetry}>Retry</button>}
    </div>
  );
}

// ── empty state ──────────────────────────────────────────────────────────
function EmptyState({ title, message, actionLabel, actionHref }) {
  return (
    <div className="empty-state glass">
      <Icon name="search-x" size={28} className="fg-muted" />
      <div className="h4">{title}</div>
      <p className="body-sm fg-muted">{message}</p>
      {actionLabel && <a className="btn btn-outline btn-sm" href={actionHref}>{actionLabel}</a>}
    </div>
  );
}

// ── product card (mode visible BEFORE click) ────────────────────────────
function ProductCard({ item, chipStyle = "solid" }) {
  return (
    <article className="product-card glass">
      <div className="pc-top">
        <ModeChip mode={item.mode} style={chipStyle} />
        <button type="button" className="pc-wish" aria-label="Save for later"><Icon name="heart" size={15} /></button>
      </div>
      <div className="pc-thumb"><Icon name="box" size={28} /></div>
      <div className="label-overline fg-muted">{CATEGORIES.find((c) => c.id === item.category)?.label}</div>
      <h3 className="h4 pc-name"><a href={`pdp-${item.mode}.html?item=${item.id}`}>{item.name}</a></h3>
      <p className="body-sm fg-muted pc-best">Best for {item.bestFor.slice(0, 2).join(", ")}</p>
      <PriceBlock item={item} />
      <div className="pc-rep body-sm fg-muted"><Stars score={item.provider.reputationScore} size={11} /> {item.provider.reputationScore.toFixed(1)} ({item.provider.reviewCount})</div>
      <a className="compare-link" href={`compare.html?item=${item.id}`}>Compare <Icon name="chevrons-right" size={13} /></a>
    </article>
  );
}

// ── filters (Baymard-grade: counts per option, applied chips, show more) ─
function FilterPanel({ facets, applied, onToggle, onClearAll }) {
  const [expanded, setExpanded] = React.useState({});
  const appliedList = Object.entries(applied).flatMap(([facet, vals]) => vals.map((v) => ({ facet, v })));
  return (
    <div className="filter-panel glass">
      <div className="filter-hd">
        <div className="label-overline">Filters</div>
        {appliedList.length > 0 && <button type="button" className="clear-all body-sm" onClick={onClearAll}>Clear all</button>}
      </div>
      {appliedList.length > 0 && (
        <div className="applied-chips">
          {appliedList.map(({ facet, v }) => (
            <button key={facet + v} type="button" className="applied-chip label-overline" onClick={() => onToggle(facet, v)}>
              {v} <Icon name="x" size={11} />
            </button>
          ))}
        </div>
      )}
      {facets.map((f) => {
        const isOpen = expanded[f.id];
        const opts = isOpen ? f.options : f.options.slice(0, 6);
        return (
          <div key={f.id} className="filter-group">
            <div className="label-overline fg-muted filter-group-h">{f.label}</div>
            {opts.map((o) => {
              const on = (applied[f.id] || []).includes(o.value);
              return (
                <label key={o.value} className="filter-opt body-sm">
                  <input type="checkbox" checked={on} onChange={() => onToggle(f.id, o.value)} />
                  <span>{o.value}</span>
                  <span className="filter-count fg-muted">({o.count})</span>
                </label>
              );
            })}
            {f.options.length > 6 && (
              <button type="button" className="show-more body-sm" onClick={() => setExpanded((e) => ({ ...e, [f.id]: !isOpen }))}>
                {isOpen ? "Show less" : `Show ${f.options.length - 6} more`}
              </button>
            )}
          </div>
        );
      })}
    </div>
  );
}

// ── Agent Guide / Finder — one component, two shells ────────────────────
// GuideConversation is the scripted Q&A; AgentGuidePanel is the slide-in
// overlay (persistent button, any page); FinderPanel embeds the same
// conversation inline at the top of plp.html.
function GuideConversation({ onRecommend, compact = false }) {
  const [step, setStep] = React.useState(0);
  const [answers, setAnswers] = React.useState({});
  const qs = GUIDE_SCRIPT.questions;
  const done = step >= qs.length;
  const recId = done ? GUIDE_SCRIPT.recommend(answers) : null;
  const recItem = recId ? getItem(recId) : null;

  const pick = (qid, value) => {
    const next = { ...answers, [qid]: value };
    setAnswers(next);
    setStep((s) => s + 1);
    if (step + 1 >= qs.length) onRecommend && onRecommend(GUIDE_SCRIPT.recommend(next));
  };

  const restart = () => { setStep(0); setAnswers({}); };

  return (
    <div className={"guide-convo" + (compact ? " compact" : "")}>
      <div className="guide-msg">
        <Icon name="sparkles" size={16} className="fg-circuit" />
        <p className="body-sm">{step === 0 ? GUIDE_SCRIPT.intro : qs[step - 1] ? qs[step - 1].prompt : ""}</p>
      </div>
      {!done && (
        <div className="guide-options">
          {qs[step].options.map((o) => (
            <button key={o.value} type="button" className="opt-btn guide-opt" onClick={() => pick(qs[step].id, o.value)}>{o.label}</button>
          ))}
        </div>
      )}
      {done && recItem && (
        <div className="guide-rec glass">
          <div className="label-overline fg-muted">Recommended</div>
          <ModeChip mode={recItem.mode} />
          <h4 className="h4">{recItem.name}</h4>
          <p className="body-sm fg-muted">Best for {recItem.bestFor.slice(0, 2).join(", ")}</p>
          <PriceBlock item={recItem} />
          <CTABlock item={recItem} />
          <button type="button" className="body-sm restart-link" onClick={restart}>Start over</button>
        </div>
      )}
    </div>
  );
}

function AgentGuidePanel({ open, onClose }) {
  if (!open) return null;
  return (
    <div className="guide-overlay" role="dialog" aria-label="Agent guide">
      <div className="guide-panel glass">
        <div className="guide-panel-hd">
          <div className="label-overline">Agent guide</div>
          <button type="button" className="guide-close" onClick={onClose} aria-label="Close guide"><Icon name="x" size={16} /></button>
        </div>
        <GuideConversation />
      </div>
    </div>
  );
}

function FinderPanel({ defaultOpen = true }) {
  const [open, setOpen] = React.useState(defaultOpen);
  return (
    <div className="finder-panel glass">
      <button type="button" className="finder-hd" onClick={() => setOpen((o) => !o)} aria-expanded={open}>
        <span className="label-overline"><Icon name="sparkles" size={14} className="fg-circuit" /> Find the right thing</span>
        <Icon name={open ? "chevron-up" : "chevron-down"} size={16} />
      </button>
      {open && <GuideConversation compact />}
    </div>
  );
}

// ── shared PDP body — same layout across pdp-buy/pdp-partner/pdp-provider,
// only the CTA block (and the above-the-fold trust row) differs by mode ──
function ProductDetail({ item, showDisclosure = true, error = null }) {
  const [seats, setSeats] = React.useState("1");
  return (
    <div className="pdp">
      <Crumb trail={[{ href: "index.html", label: "Discover" }, { href: `plp.html?category=${item.category}`, label: CATEGORIES.find((c) => c.id === item.category)?.label }, { label: item.name }]} />
      {error && <div style={{ margin: "1rem 0" }}><ErrorBanner title={error.title} message={error.message} onRetry={error.onRetry} /></div>}
      <div className="pdp-grid">
        <div className="pdp-gallery"><GalleryPlaceholder item={item} /></div>
        <div className="pdp-main">
          <div className="label-overline fg-muted">{CATEGORIES.find((c) => c.id === item.category)?.label}</div>
          <ModeChip mode={item.mode} />
          <h1 className="h1 pdp-title">{item.name}</h1>
          <p className="body-sm fg-muted">Best for {item.bestFor.join(", ")}</p>

          {item.mode !== "buy" && (
            <div className="pdp-above-fold">
              <ProviderReputation item={item} />
              <DisclosureLine item={item} />
            </div>
          )}

          <OptionSelector label="Seats" options={["1", "5", "10"]} value={seats} onChange={setSeats} />
          <PriceBlock item={item} />
          <div className="pdp-cta-row">
            <CTABlock item={item} showDisclosure={showDisclosure} />
            <WishlistButton itemId={item.id} />
          </div>
          {item.mode === "buy" && <ReturnsSummary item={item} />}
          <a className="compare-link" href={`compare.html?item=${item.id}`}>Compare with alternatives <Icon name="chevrons-right" size={13} /></a>
        </div>
      </div>

      <Section id="specs">
        <h2 className="h2">Specs<span className="dot">.</span></h2>
        <SpecTable specs={item.specs} />
      </Section>

      <Section id="reviews">
        <h2 className="h2">Reviews<span className="dot">.</span></h2>
        <ReviewList reviews={item.reviews} />
      </Section>

      <StickyCTABar item={item} />
    </div>
  );
}

Object.assign(window, {
  Icon, Stars, Section, Crumb, Nav, Footer, ModeChip, CTABlock, PriceBlock, ReturnsSummary,
  ProviderReputation, DisclosureLine, ReviewList, SpecTable, GalleryPlaceholder,
  OptionSelector, WishlistButton, StickyCTABar, TrustStrip, ErrorBanner, EmptyState,
  ProductCard, FilterPanel, GuideConversation, AgentGuidePanel, FinderPanel, ProductDetail,
});
