const { Button: JB, Card: JC, Tag: JT, SectionHeader: JSH, ChartFrame: JCF, VisionFrame: JVF, Annotate: JA, FilterChip: JChip, SegmentedControl: JSeg, GlobalDelivery: JMap, PortfolioBreakdown: JBreak, CTABand: JCTA } = window.SoftVerxDesignSystem_6fd95b;
const W = window.SX_DATA;

function ClientMark() { return null; }

/* The client marks we hold are low-resolution rasters at fifteen different crops,
   so they are set as type instead: one face, one size, one ink. */
function ClientTicker({ mobile }) {
  const names = W.projects.filter((p) => p.logo).map((p) => p.short);
  const track = names.concat(names);
  return (
    <div className="sx-ticker" style={{ borderTop: "1px solid var(--border-default)", borderBottom: "1px solid var(--border-default)", padding: mobile ? "13px 0" : "16px 0" }}>
      <div className="sx-ticker-track" style={{ gap: mobile ? 26 : 40, alignItems: "baseline", ...(mobile ? { animationDuration: "34s" } : null) }}>
        {track.map((n, i) => (
          <span key={n + i} className="sx-h3" style={{ whiteSpace: "nowrap", fontSize: mobile ? 15 : 19, color: "var(--text-body)", letterSpacing: "-0.01em" }}>{n}</span>
        ))}
      </div>
    </div>
  );
}

function ProjectCard({ p, mobile }) {
  const href = p.slug === "lesco" ? "/lesco" : (window.SX_STUDIES && window.SX_STUDIES[p.slug] ? "/case?p=" + p.slug : null);
  const flagship = p.tier === "flagship";
  const body = (
    <>
      <div style={{ display: "flex", gap: 10, alignItems: "baseline", justifyContent: "space-between" }}>
        <span className="sx-micro" style={{ color: "var(--text-quiet)" }}>{p.sector.toLowerCase()}{p.country ? " · " + p.country.toLowerCase() : ""}</span>
        <span className="sx-micro" style={{ color: "var(--text-quiet)" }}>{p.year || p.era}</span>
      </div>
      <h3 className={flagship ? "sx-h2" : "sx-h3"} style={{ marginTop: mobile ? 8 : 12, fontSize: flagship ? undefined : "var(--t-h3)" }}>{p.client}</h3>
      <p className="sx-small" style={{ marginTop: mobile ? 5 : 8, color: "var(--text-accent)" }}>{p.title}</p>
      <p className="sx-small" style={{ marginTop: mobile ? 8 : 12, color: "var(--text-body)", display: "-webkit-box", WebkitLineClamp: flagship ? 3 : 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{p.summary}</p>
      <div style={{ display: "flex", gap: 8, marginTop: mobile ? 12 : 18, flexWrap: "wrap", alignItems: "center" }}>
        <JT>{p.practice.toLowerCase()}</JT>
        {p.product && <JT tone="accent">our own product</JT>}
        {flagship && p.url && <a className="sx-micro" href={p.url} target="_blank" rel="noopener" style={{ color: "var(--text-accent)" }}>{p.url.replace(/^https?:\/\/(www\.)?/, "")}</a>}
        {flagship && p.metrics && <JT tone="field">{p.metrics[0].v} {p.metrics[0].l.split(" ").slice(0, 2).join(" ")}</JT>}
      </div>
      {href && (
        <a href={href} className="sx-small" style={{ marginTop: mobile ? 12 : 18, display: "inline-flex", alignItems: "center", gap: 8, height: 38, padding: "0 14px", borderRadius: "var(--r-control)", background: "var(--sx-accent)", color: "var(--sx-accent-ink)", textDecoration: "none", fontWeight: 500, whiteSpace: "nowrap" }}>
          Read the case study
          <svg aria-hidden width="14" height="14" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"><path d="M4 10h11M11 6l4 4-4 4" /></svg>
        </a>
      )}
    </>
  );
  if (p.tier === "delivery" || (mobile && p.tier === "deployment")) {
    const compact = p.tier === "delivery";
    return (
      <JC as="article" id={p.slug} padding={mobile ? "14px 14px" : "var(--sp-5)"} style={{ scrollMarginTop: 88, display: "grid", gridTemplateColumns: p.image ? "48px minmax(0,1fr)" : "1fr", gap: p.image ? 12 : 0, alignItems: "start" }}>
        {p.image && <img src={p.image} alt="" style={{ width: 48, height: 48, objectFit: "cover", borderRadius: 4, border: "1px solid var(--border-default)", display: "block" }} />}
        <div style={{ minWidth: 0 }}>
        <div style={{ display: "flex", gap: 10, justifyContent: "space-between", alignItems: "baseline" }}>
          <span className="sx-small" style={{ color: "var(--text-strong)" }}>{p.client}</span>
          <span className="sx-micro" style={{ color: "var(--text-quiet)", whiteSpace: "nowrap", flexShrink: 0 }}>{p.year || p.era}</span>
        </div>
        <p className="sx-small" style={{ marginTop: mobile ? 4 : 6, color: "var(--text-body)" }}>{p.title}</p>
        {!compact && <p className="sx-caption" style={{ marginTop: 7, color: "var(--text-body)", textTransform: "none", letterSpacing: 0, fontFamily: "var(--font-body)", display: "-webkit-box", WebkitLineClamp: 2, WebkitBoxOrient: "vertical", overflow: "hidden" }}>{p.summary}</p>}
        <div style={{ display: "flex", alignItems: "center", gap: 10, marginTop: mobile ? 8 : 10, flexWrap: "wrap" }}>
          <span className="sx-caption" style={{ color: "var(--text-quiet)", textTransform: "none" }}>{p.sector.toLowerCase()} · {p.practice.toLowerCase()}{p.country ? " · " + p.country.toLowerCase() : ""}</span>
          {!compact && href && <a href={href} className="sx-micro" style={{ marginLeft: "auto", color: "var(--text-accent)", whiteSpace: "nowrap" }}>Case study</a>}
        </div>
        </div>
      </JC>
    );
  }
  return (
    <JC as="article" id={p.slug} spotlight padding="0" style={{ overflow: "hidden", gridColumn: flagship && !mobile ? "span 2" : undefined, scrollMarginTop: 88 }}>
      {p.image
        ? <div style={{ position: "relative", aspectRatio: "16 / 9", background: p.imageKind === "screen" ? "var(--bg-well)" : "var(--surface-card)", borderBottom: "1px solid var(--border-default)", overflow: "hidden" }}>
            {/* A photograph fills the frame. A screenshot is shown whole: cropping
                a dashboard to 16:9 removes the column worth looking at. */}
            <img src={p.image} alt="" loading="lazy" decoding="async"
              style={{ width: "100%", height: "100%", objectFit: p.imageKind === "screen" ? "contain" : "cover", display: "block" }} />
          </div>
        : <div className="sx-bg-plus" style={{ height: 44, borderBottom: "1px solid var(--border-default)", display: "flex", alignItems: "center", gap: 10, padding: "0 12px", background: "var(--surface-raised)", overflow: "hidden" }}>
            <span className="sx-micro" style={{ color: "var(--text-quiet)", minWidth: 0, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontSize: 11 }}>{p.practice.toLowerCase()}</span>
            {p.logo && <ClientMark p={p} style={{ marginLeft: "auto" }} />}
          </div>}
      <div style={{ padding: mobile ? "16px 16px 18px" : "var(--sp-6)" }}>{body}</div>
    </JC>
  );
}

function TimelineView({ mobile }) {
  return (
    <div>
      <JCF title="Delivery spine" subtitle="1999 → 2026 · press play, or drag across the plot" note="One dot per programme on a true year axis; the accumulation band underneath counts the capability layers live in each year.">
        <AnimatedSpine mobile={mobile} />
      </JCF>
      <div style={{ marginTop: 24, display: "grid", gap: 16, gridTemplateColumns: mobile ? "1fr" : "repeat(5, minmax(0,1fr))" }}>
        {W.eras.map((e) => {
          const list = W.projects.filter((p) => p.era === e.label.slice(0, 4) || (p.era === "2000s" && +e.label.slice(0, 4) < 2010) || (p.era === "2010s" && +e.label.slice(0, 4) >= 2012));
          return (
            <div key={e.id} style={{ borderTop: "1px solid var(--border-strong)", paddingTop: 14 }}>
              <p className="sx-micro sx-num" style={{ color: "var(--sx-accent)" }}>{e.label}</p>
              <h3 className="sx-h3" style={{ marginTop: 10, fontSize: "var(--t-h3)" }}>{e.title}</h3>
              <p className="sx-small" style={{ marginTop: 8, color: "var(--text-body)" }}>{e.detail}</p>
              <p className="sx-caption" style={{ marginTop: 12, color: "var(--text-quiet)", textTransform: "none" }}>{list.length} programmes recorded in this era</p>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function MapView({ mobile }) {
  return (
    <div style={{ display: "grid", gap: 20 }}>
      <JCF title="Where the systems run" subtitle={`${W.countries.length} countries with delivered platforms`} note="Countries are recorded only where the client's own name or the contract states one. Every non-Pakistan engagement here was delivered from Lahore.">
        <DeliveryGlobe mobile={mobile} />
      </JCF>
      <JCF title="Sector × capability layer" subtitle={`${W.projects.length} documented programmes`} note="Each programme counted once, against the layer its primary practice sits in. The table view carries the same numbers row by row.">
        <SectorLayerHeatmap mobile={mobile} />
      </JCF>
    </div>
  );
}

const VIEWS = [
  { id: "grid", label: "grid" },
  { id: "timeline", label: "spine" },
  { id: "map", label: "map" },
];

/* One selector shape for all three facets: a quiet field that opens a list.
   Counts stay visible; the field states the current pick rather than 43 chips. */
function Picker({ label, value, options, onPick, width = 210 }) {
  const [open, setOpen] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    if (!open) return;
    const away = (e) => { if (ref.current && !ref.current.contains(e.target)) setOpen(false); };
    const key = (e) => { if (e.key === "Escape") setOpen(false); };
    document.addEventListener("pointerdown", away); document.addEventListener("keydown", key);
    return () => { document.removeEventListener("pointerdown", away); document.removeEventListener("keydown", key); };
  }, [open]);
  const current = options.find((o) => o.id === value) || options[0];
  const set = value !== "all";
  return (
    <div ref={ref} style={{ position: "relative", width }}>
      <button type="button" onClick={() => setOpen(!open)} aria-expanded={open}
        style={{ appearance: "none", fontFamily: "var(--font-body)", cursor: "pointer", width: "100%", textAlign: "left", display: "flex", alignItems: "center", gap: 10, padding: "9px 12px", background: "var(--surface-card)", border: "1px solid " + (open || set ? "var(--border-strong)" : "var(--border-default)"), borderRadius: "var(--r-control)" }}>
        <span className="sx-caption" style={{ color: "var(--text-quiet)", textTransform: "none", letterSpacing: 0 }}>{label}</span>
        <span className="sx-small" style={{ color: set ? "var(--text-strong)" : "var(--text-body)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{current.label}</span>
        <span className="sx-micro sx-num" style={{ marginLeft: "auto", color: "var(--text-quiet)" }}>{current.count}</span>
        <svg aria-hidden width="12" height="12" viewBox="0 0 20 20" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round"
          style={{ color: "var(--text-quiet)", flexShrink: 0, transform: open ? "rotate(180deg)" : "none", transition: "transform 150ms linear" }}><path d="M6 8l4 4 4-4" /></svg>
      </button>
      {open && (
        <div role="listbox" style={{ position: "absolute", zIndex: 40, top: "calc(100% + 5px)", left: 0, width: "100%", maxHeight: 264, overflowY: "auto", background: "var(--surface-raised)", border: "1px solid var(--border-strong)", borderRadius: "var(--r-control)", boxShadow: "var(--shadow-dropdown, 0 18px 40px rgba(0,0,0,.45))", padding: 4 }}>
          {options.map((o) => {
            const on = o.id === value;
            return (
              <button key={o.id} type="button" role="option" aria-selected={on} onClick={() => { onPick(o.id); setOpen(false); }}
                style={{ appearance: "none", fontFamily: "var(--font-body)", cursor: "pointer", width: "100%", display: "flex", alignItems: "baseline", gap: 10, textAlign: "left", background: on ? "var(--bg-well)" : "transparent", border: "none", borderRadius: 6, padding: "7px 9px" }}>
                <span className="sx-small" style={{ color: on ? "var(--text-accent)" : "var(--text-body)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>{o.label}</span>
                <span className="sx-micro sx-num" style={{ marginLeft: "auto", color: "var(--text-quiet)" }}>{o.count}</span>
              </button>
            );
          })}
        </div>
      )}
    </div>
  );
}

function ViewTabs({ view, setView, mobile }) {
  return (
    <div style={{ display: "inline-flex", gap: 2, padding: 3, background: "var(--surface-card)", border: "1px solid var(--border-default)", borderRadius: 999 }}>
      {VIEWS.map((v) => {
        const on = view === v.id;
        return (
          <button key={v.id} type="button" role="tab" aria-selected={on} onClick={() => setView(v.id)}
            style={{ appearance: "none", fontFamily: "var(--font-body)", cursor: "pointer", border: "none", borderRadius: 999, padding: mobile ? "7px 14px" : "7px 18px", background: on ? "var(--surface-overlay)" : "transparent" }}>
            <span className="sx-small" style={{ color: on ? "var(--text-strong)" : "var(--text-quiet)" }}>{v.label}</span>
          </button>
        );
      })}
    </div>
  );
}

function ProjectsPage({ mobile }) {
  const [view, setView] = React.useState(() => ({ "#spine": "timeline", "#map": "map" }[window.location.hash] || "grid"));
  const [sector, setSector] = React.useState("all");
  const [practice, setPractice] = React.useState("all");
  const list = W.projects.filter((p) => (sector === "all" || p.sector === sector) && (practice === "all" || p.practice === practice));
  const filtered = sector !== "all" || practice !== "all";
  const tiers = ["flagship", "deployment", "delivery"];
  const practicesUsed = [...new Set(W.projects.map((p) => p.practice))];
  return (
    <main>
      <PageHero mobile={mobile} title="250+ delivered since 1999. These are the ones we can show you."
        lead="Recent work first: agents, document intelligence, data platforms and vision. Then the enterprise record the firm was built on."
        actions={<><JB as="a" href="/lesco">Read the LESCO case study</JB><JB as="a" href="/about#start" variant="secondary">Ask about a similar build</JB></>}
        meta={[{ l: "documented here", v: W.projects.length }, { l: "sectors", v: W.sectors.length }, { l: "countries", v: W.countries.length }, { l: "earliest", v: 1999 }]} />

      <Section mobile={mobile} bordered={false} style={{ paddingBlock: mobile ? 20 : 32 }}>
        <ClientTicker mobile={mobile} />
        <p className="sx-caption" style={{ marginTop: 14, color: "var(--text-quiet)", textTransform: "none" }}>Marks shown where we hold the client's logo. The full record is below.</p>
      </Section>

      <Section mobile={mobile}>
        <div id="spine" style={{ scrollMarginTop: 90 }} />
        <h2 className="sx-h2" style={{ marginBottom: mobile ? 18 : 26 }}>The record, three ways to read it</h2>
        <div style={{ display: "flex", gap: 14, flexWrap: "wrap", alignItems: "center", justifyContent: "space-between", borderTop: "1px solid var(--border-strong)", paddingTop: mobile ? 16 : 18 }}>
          <ViewTabs view={view} setView={setView} mobile={mobile} />
          <div style={{ display: "flex", gap: 8, flexWrap: "wrap", alignItems: "center", width: mobile ? "100%" : undefined }}>
            <Picker label="sector" value={sector} onPick={setSector} width={mobile ? "100%" : 224}
              options={[{ id: "all", label: `all ${W.sectors.length} sectors`, count: W.projects.length }].concat(W.sectors.map((s) => ({ id: s.label, label: s.label.toLowerCase(), count: s.value })))} />
            <Picker label="practice" value={practice} onPick={setPractice} width={mobile ? "100%" : 244}
              options={[{ id: "all", label: `all ${practicesUsed.length} practices`, count: W.projects.length }].concat(practicesUsed.map((pr) => ({ id: pr, label: pr.toLowerCase(), count: W.projects.filter((p) => p.practice === pr).length })))} />
            {filtered && (
              <button type="button" onClick={() => { setSector("all"); setPractice("all"); }} className="sx-micro"
                style={{ appearance: "none", fontFamily: "var(--font-body)", cursor: "pointer", background: "transparent", border: "none", color: "var(--text-accent)", padding: "6px 2px" }}>Clear</button>
            )}
          </div>
        </div>

        <p className="sx-caption" style={{ marginTop: 14, color: "var(--text-quiet)", textTransform: "none" }}>
          {list.length} of {W.projects.length} documented programmes shown
        </p>

        <div style={{ marginTop: mobile ? 18 : 26 }}>
          {view === "grid" && (
            <div style={{ display: "grid", gap: 22 }}>
              {tiers.map((t) => {
                const rows = list.filter((p) => p.tier === t);
                if (!rows.length) return null;
                return (
                  <div key={t}>
                    <div style={{ display: "flex", alignItems: "center", gap: 12, borderTop: "1px solid var(--border-strong)", paddingTop: 12 }}>
                      <span className="sx-micro" style={{ color: "var(--text-accent)" }}>{t}</span>
                      <span className="sx-caption" style={{ color: "var(--text-quiet)", textTransform: "none" }}>
                        {t === "flagship" ? "full programmes, documented scope" : t === "deployment" ? "delivered systems in production" : "smaller deliveries, listed plainly"}
                      </span>
                      <span className="sx-micro sx-num" style={{ marginLeft: "auto", color: "var(--text-quiet)" }}>{rows.length}</span>
                    </div>
                    <div style={{ marginTop: 14, display: "grid", gap: 14, gridTemplateColumns: mobile ? "1fr" : t === "delivery" ? "repeat(3, minmax(0,1fr))" : "repeat(4, minmax(0,1fr))", gridAutoRows: "min-content", alignItems: "start" }}>
                      {rows.map((p) => <ProjectCard key={p.slug} p={p} mobile={mobile} />)}
                    </div>
                  </div>
                );
              })}
            </div>
          )}
          {view === "timeline" && <TimelineView mobile={mobile} />}
          {view === "map" && <MapView mobile={mobile} />}
        </div>
      </Section>

      <Section mobile={mobile} well>
        <JSH title="What is on this page, and what is not" lead="More than 250 programmes have been delivered since 1999, including short builds of a month or less. The ones documented here are those we can describe in public: the rest are under NDA or small enough that publishing them would pad the page. Entries show the delivery period rather than a single date." />
      </Section>
      <JCTA mobile={mobile} title="Ask us to substantiate any of this" lead="Every figure here comes from our own project record. We will walk you through the one closest to your operation, including what went wrong in it." />
    </main>
  );
}

Object.assign(window, { ProjectsPage, ProjectCard, ClientMark, ClientTicker });
