/* Case Studies section — cards summarise; full write-ups live in case-studies/<id>/ */

const CASE_STUDIES = [
  {
    id: 'govstack',
    client: 'GovStack',
    via: 'Fynarfin',
    tags: ['eng', 'pm'],
    href: 'case-studies/govstack/',
    outcome: {
      eng: 'Led solution architecture for a reusable government payments building block, shipped as open source with 0 failures across 99 executed tests.',
      pm: 'Turned a 219-requirement government payments specification into four open-source modules and a shared sandbox countries can test against.',
    },
    spine: {
      context: 'GovStack (ITU, GIZ, Estonia, DIAL) defines reusable digital building blocks for governments. The Payments Building Block covers government-to-person disbursements, vouchers and bill payments across banks and mobile money.',
      problem: { eng: "Every country's payment rails differ, and paying someone means linking a national ID to an account without leaking beneficiary data. No generic, privacy-safe government payments API existed.", pm: '219 must-have requirements, a five-organisation consortium and independent acceptance reviews, with other building blocks being built at the same time.' },
      role: "Solution architecture lead for Fynarfin's delivery team; designed the shared G2P sandbox.",
      approach: 'Extended open-source Mifos Payment Hub EE instead of building new: an identity account mapper that keeps account details away from government systems, a bulk processor that rejects bad rows before money moves, a voucher engine and bill pay.',
      metrics: '4 modules merged upstream (MPL 2.0) · 135 test cases, 99 executed, 0 failures · 88 requirements closed in one integration sprint by reusing the platform.',
    },
    annotatedOutcome: 'Open-source reference implementation plus a shared sandbox, later reused for hackathons and other government-payment programmes.',
  },
  {
    id: 'one-acre-fund',
    client: 'One Acre Fund',
    via: 'Fynarfin',
    tags: ['eng', 'pm'],
    href: 'case-studies/one-acre-fund/',
    outcome: {
      eng: 'Lead architect on a payment hub taking about 1.2M farmer repayments a month direct to M-Pesa, each validated against the loan ledger first.',
      pm: 'Replaced an aggregator with direct M-Pesa collection and USSD repayment for smallholder farmers, live in production 2022–2024.',
    },
    spine: {
      context: 'One Acre Fund lends seed and fertiliser to smallholder farmers in East Africa and collects repayment in small instalments, almost all over M-Pesa in Kenya.',
      problem: { eng: 'Repayments went through a third-party aggregator, and every payment had to be validated against the loan system before collection, with the workflow engine, M-Pesa and the ledger all agreeing afterwards.', pm: 'Collections cost too much, farmers with basic phones needed a simple USSD way to pay, and later OAF needed to pay farmers in the field without money going to the wrong phone.' },
      role: "Lead architect: deployment in OAF's cloud, M-Pesa and loan-system connectors, production operations and payouts scoping.",
      approach: 'Built on open-source Mifos Payment Hub EE: validate, collect and post as one orchestrated flow; one Helm chart instead of customer forks; immutable releases.',
      metrics: 'Live from Feb 2022 · ~1.2M repayment transactions a month direct to M-Pesa · three deployment charts consolidated into one.',
    },
    annotatedOutcome: { eng: 'OAF runs, replicates and scales the hub in its own hosting.', pm: 'Direct M-Pesa collection, USSD repayment and bulk disbursement live across QA, UAT and production.' },
  },
  {
    id: 'giv-finseer',
    client: 'Grameen Impact Ventures',
    via: 'Fynarfin',
    tags: ['eng', 'pm'],
    href: 'case-studies/giv-finseer/',
    outcome: {
      eng: 'Architected Finseer, an agent-banking platform running fingerprint cash-out, UPI QR and bill payments on one ledger for about 2.5 years in production.',
      pm: 'Product owner for a rural agent-banking platform through two forced partner API migrations without losing the service.',
    },
    spine: {
      context: 'Grameen Impact Ventures (Grameen Foundation India) runs village agents who give rural customers cash withdrawals, bill payments and merchant payments.',
      problem: { eng: 'Three partner rails (Fino AePS, Razorpay UPI/QR, BBPS) had to post into one ledger; analytics disagreed with the ledger, and production was failing almost daily in spring 2022.', pm: "Finance couldn't trust the dashboards, and partners changed their APIs with little notice, including one change that forced every QR customer to re-register." },
      role: 'Architect and product owner; production escalation.',
      approach: "Extended Apache Fineract; wrapped each partner rail behind Finseer's own API; reconciled every dashboard against finance reports before publishing; fixed the batch job behind the outages.",
      metrics: 'In production ~2.5 years · 2 forced partner migrations absorbed · daily outages ended · backups verified by restore on the money tables.',
    },
    annotatedOutcome: { eng: 'Stable, recoverable agent-banking platform on an open-source core.', pm: "Dashboards that match GIV finance's own reports." },
  },
  {
    id: 'novopay-idfc',
    client: 'IDFC Bharat Banking',
    via: 'Novopay',
    tags: ['eng'],
    href: 'case-studies/novopay-idfc/',
    outcome: {
      eng: 'Architect and lead engineer on a Fineract lending and wallet core behind 50,000+ agents and US$1B+ in yearly transactions.',
      pm: 'Delivered group and micro-enterprise lending for a newly licensed bank, with regulatory rules built into the core.',
    },
    spine: {
      context: "IDFC Bank's Bharat Banking division needed rural group lending through business correspondents; Novopay needed a ledger for its retailer-led wallet network.",
      problem: { eng: 'Regulator-grade lending rules (appropriation that switches at 90 days past due, automatic provisioning, priority-sector and FATCA tagging) plus offline biometric onboarding, on an open-source core banks were sceptical of.', pm: 'A newly licensed bank needed rural lending without buying a legacy core banking system.' },
      role: 'Architect and lead engineer, Apache Fineract lending engine and wallet ledger.',
      approach: 'Extended Apache Fineract with field origination, group lending through correspondents, and provisioning and appropriation rules implemented inside the ledger.',
      metrics: "50,000+ agents · 20+ states · 2.1M wallet clients · US$1B+ transactions a year (Novopay's figures).",
    },
    annotatedOutcome: 'Cited by the Mifos Initiative as its flagship fintech adoption in India.',
  },
];

const FILTERS = [
  { key: 'all', label: 'All' },
  { key: 'eng', label: 'Engineering-led' },
  { key: 'pm', label: 'Product-led' },
];

// A field is either one string or { eng, pm } per lens.
function pickLens(value, lens) {
  return typeof value === 'string' ? value : (value[lens] || value.eng);
}

function ChevronIcon({ open }) {
  return (
    <svg className={'cs-card__chevron' + (open ? ' cs-card__chevron--open' : '')}
      width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="6 9 12 15 18 9"></polyline>
    </svg>
  );
}

function CaseStudyCard({ cs, isOpen, onToggle }) {
  const { lens } = React.useContext(LensContext);
  const spine = cs.spine;

  return (
    <div className="cs-card">
      <div className="cs-card__header" onClick={onToggle} role="button" aria-expanded={isOpen} tabIndex={0}
        onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onToggle(); } }}>
        <div className="cs-card__left">
          <h3 className="cs-card__client">{cs.client} <span style={{ fontWeight: 400, fontSize: '0.75em', color: 'var(--ink-3)' }}>via {cs.via}</span></h3>
          <p className="cs-card__outcome">{pickLens(cs.outcome, lens)}</p>
        </div>
        <div className="cs-card__tags">
          {cs.tags.includes('eng') && <span className="cs-tag cs-tag--eng">Engineering</span>}
          {cs.tags.includes('pm') && <span className="cs-tag cs-tag--pm">Product</span>}
        </div>
        <ChevronIcon open={isOpen} />
      </div>
      <div className={'cs-card__body' + (isOpen ? ' cs-card__body--open' : '')}>
        <div className="cs-card__content">
          <div className="cs-spine">
            <span className="cs-spine__label">Context</span>
            <p className="cs-spine__value">{spine.context}</p>
            <span className="cs-spine__label">Problem</span>
            <p className="cs-spine__value">{pickLens(spine.problem, lens)}</p>
            <span className="cs-spine__label">My Role</span>
            <p className="cs-spine__value">{pickLens(spine.role, lens)}</p>
            <span className="cs-spine__label">Approach</span>
            <p className="cs-spine__value">{spine.approach}</p>
            <span className="cs-spine__label">Metrics</span>
            <p className="cs-spine__value">{spine.metrics}</p>
          </div>
          <div className="cs-outcome-callout">
            {pickLens(cs.annotatedOutcome, lens)}
          </div>
          <a className="btn btn--secondary" href={cs.href} style={{ marginTop: 20 }}>Read the full case study →</a>
        </div>
      </div>
    </div>
  );
}

function CaseStudies() {
  const [filter, setFilter] = React.useState('all');
  const [openId, setOpenId] = React.useState(null);

  const filtered = filter === 'all'
    ? CASE_STUDIES
    : CASE_STUDIES.filter((cs) => cs.tags.includes(filter));

  return (
    <section className="section" id="case-studies">
      <div className="container">
        <div className="section-header anim-in" data-anim>
          <p className="t-label">Featured Work</p>
          <h2 className="t-display">Case Studies</h2>
          <p>Deep dives into the systems I built and the outcomes I drove.</p>
        </div>
        <div className="cs-filters anim-in" data-anim>
          {FILTERS.map((f) => (
            <button key={f.key}
              className={'cs-filter-btn' + (filter === f.key ? ' cs-filter-btn--active' : '')}
              onClick={() => { setFilter(f.key); setOpenId(null); }}>
              {f.label}
            </button>
          ))}
        </div>
        <div className="cs-list anim-in anim-in--stagger" data-anim>
          {filtered.map((cs) => (
            <CaseStudyCard key={cs.id} cs={cs} isOpen={openId === cs.id}
              onToggle={() => setOpenId(openId === cs.id ? null : cs.id)} />
          ))}
        </div>
      </div>
    </section>
  );
}

Object.assign(window, { CaseStudies });
