/* ===========================================================
   Halvorsen — About + Procedures (tabs) + Outcomes (counters)
   =========================================================== */

/* ---------- ABOUT / PHILOSOPHY ---------- */
const About = () => (
  <section id="about" style={{ padding: "120px 32px", maxWidth: 1400, margin: "0 auto", position: "relative" }}>
    <div className="reveal" style={{ marginBottom: 72 }}>
      <Chapter num={2} label="Philosophy" />
    </div>

    <div style={{ display: "grid", gridTemplateColumns: "1fr 1.1fr", gap: 80, alignItems: "start" }}>
      <div className="reveal" style={{ position: "sticky", top: 120 }}>
        <KneeMotif size={320} style={{ color: "var(--sage-deep)" }} />
        <div className="mono" style={{ fontSize: 10, letterSpacing: "0.2em", color: "var(--ink-soft)", marginTop: 16, textTransform: "uppercase" }}>
          Fig. 02 · Tibiofemoral, posterior view
        </div>
      </div>
      <div className="reveal reveal-delay-1">
        <h2 className="serif" style={{ margin: 0, fontSize: "clamp(36px, 4.8vw, 64px)", lineHeight: 1.05, letterSpacing: "-0.015em", fontWeight: 400, textWrap: "pretty" }}>
          Surgery is the last <span style={{ fontStyle: "italic" }}>quiet conversation</span> between a body and the person who will carry it forward.
        </h2>
        <div style={{ marginTop: 40, columnCount: 2, columnGap: 32, fontSize: 15.5, lineHeight: 1.7, color: "var(--ink-soft)" }}>
          <p>
            For seventeen years, my practice has been built on a stubborn idea: that orthopaedic surgery is not a transaction, and that a knee is not a knee. It belongs to the violinist who needs to crouch, the parent on the floor with their child, the runner whose Sunday is a pilgrimage.
          </p>
          <p>
            I will not operate on a patient whose problem can be answered by movement, time, or honesty. When surgery is the right answer, it is approached the way a luthier approaches a violin — with patience, planning and a respect for what was working before.
          </p>
        </div>
        <div style={{ marginTop: 48, display: "grid", gridTemplateColumns: "repeat(3, 1fr)", gap: 24, paddingTop: 32, borderTop: "1px solid var(--line)" }}>
          <Tenet n="01" t="Movement first" d="Conservative care, structured rehab and a clear bar before we touch a scalpel." />
          <Tenet n="02" t="Tissue-respecting" d="The smallest correct procedure. Your tissue is irreplaceable." />
          <Tenet n="03" t="Return-to-life" d="Outcomes measured by the activity that mattered before we met." />
        </div>
      </div>
    </div>
  </section>
);

const Tenet = ({ n, t, d }) => (
  <div>
    <div className="mono" style={{ fontSize: 10, letterSpacing: "0.2em", color: "var(--sand-deep)" }}>— {n}</div>
    <div className="serif" style={{ fontSize: 22, lineHeight: 1.2, marginTop: 8 }}>{t}</div>
    <div style={{ fontSize: 13.5, lineHeight: 1.55, color: "var(--ink-muted)", marginTop: 8 }}>{d}</div>
  </div>
);

/* ---------- PROCEDURES (tabs) ---------- */
const PROCEDURES = [
  {
    id: "knee", label: "Knee", motif: "knee", count: "1,820 procedures",
    items: [
      { name: "ACL reconstruction", note: "Quad tendon · BPTB · hamstring", time: "60–90 min", stay: "Day case" },
      { name: "Meniscal repair / preservation", note: "All-inside, inside-out", time: "45–75 min", stay: "Day case" },
      { name: "Cartilage restoration (MACI / OATS)", note: "Single & two-stage", time: "60–120 min", stay: "1 night" },
      { name: "Robotic partial knee replacement", note: "Mako / image-matched", time: "75 min", stay: "1–2 nights" },
      { name: "Osteotomy (HTO / DFO)", note: "Joint preservation", time: "90 min", stay: "1 night" },
    ],
  },
  {
    id: "shoulder", label: "Shoulder", motif: "shoulder", count: "640 procedures",
    items: [
      { name: "Rotator cuff repair", note: "Arthroscopic, double-row", time: "60–90 min", stay: "Day case" },
      { name: "Stabilisation (Bankart / Latarjet)", note: "Recurrent dislocation", time: "75–120 min", stay: "1 night" },
      { name: "Subacromial decompression", note: "Selective indication", time: "30 min", stay: "Day case" },
      { name: "Reverse shoulder arthroplasty", note: "Cuff-deficient arthritis", time: "90–120 min", stay: "1–2 nights" },
    ],
  },
  {
    id: "hip", label: "Hip", motif: "hip", count: "560 procedures",
    items: [
      { name: "Hip arthroscopy (FAI, labral repair)", note: "Camshape / pincer", time: "75 min", stay: "Day case" },
      { name: "Anterior approach total hip", note: "Muscle-sparing", time: "90 min", stay: "1 night" },
      { name: "Periacetabular osteotomy referral", note: "Co-management", time: "—", stay: "—" },
    ],
  },
  {
    id: "ankle", label: "Foot & Ankle", motif: "ankle", count: "240 procedures",
    items: [
      { name: "Ankle ligament reconstruction", note: "Brostrom-Gould", time: "45 min", stay: "Day case" },
      { name: "Achilles tendon repair", note: "Mini-open / percutaneous", time: "45 min", stay: "Day case" },
      { name: "Cartilage repair (talus)", note: "OATS / BMAC", time: "60 min", stay: "Day case" },
    ],
  },
  {
    id: "spine", label: "Sports Spine", motif: "spine", count: "160 procedures",
    items: [
      { name: "Microdiscectomy", note: "Lumbar radiculopathy", time: "45 min", stay: "Day case" },
      { name: "Pars repair (athletes)", note: "Direct screw fixation", time: "75 min", stay: "1 night" },
    ],
  },
];

const Procedures = () => {
  const [active, setActive] = React.useState("knee");
  const cur = PROCEDURES.find((p) => p.id === active);
  const Motif = { knee: KneeMotif, shoulder: ShoulderMotif, hip: HipMotif, ankle: AnkleMotif, spine: SpineMotif }[cur.motif];

  return (
    <section id="procedures" style={{ background: "var(--bone)", padding: "120px 32px", borderTop: "1px solid var(--line)", borderBottom: "1px solid var(--line)" }}>
      <div style={{ maxWidth: 1400, margin: "0 auto" }}>
        <div className="reveal" style={{ display: "flex", justifyContent: "space-between", alignItems: "end", marginBottom: 56, gap: 32, flexWrap: "wrap" }}>
          <div>
            <Chapter num={3} label="Procedures" />
            <h2 className="serif" style={{ margin: "20px 0 0", fontSize: "clamp(36px, 4.8vw, 64px)", lineHeight: 1.0, letterSpacing: "-0.015em", fontWeight: 400, maxWidth: 720 }}>
              A practice narrowed with intention.
            </h2>
          </div>
          <div style={{ maxWidth: 360, fontSize: 14.5, lineHeight: 1.6, color: "var(--ink-soft)" }}>
            High volume in a small set of operations is, in our view, the fastest path to good outcomes. Tap a region.
          </div>
        </div>

        {/* Tab bar */}
        <div role="tablist" aria-label="Procedure regions" className="reveal" style={{ display: "flex", gap: 4, padding: 4, background: "var(--paper)", border: "1px solid var(--line)", borderRadius: 999, width: "fit-content", marginBottom: 48 }}>
          {PROCEDURES.map((p) => (
            <button
              key={p.id}
              role="tab"
              aria-selected={active === p.id}
              onClick={() => setActive(p.id)}
              style={{
                padding: "10px 20px",
                borderRadius: 999,
                border: "none",
                cursor: "pointer",
                background: active === p.id ? "var(--ink)" : "transparent",
                color: active === p.id ? "var(--paper)" : "var(--ink)",
                fontSize: 13,
                fontFamily: "var(--sans)",
                transition: "all 280ms var(--ease)",
              }}
            >
              {p.label}
            </button>
          ))}
        </div>

        {/* Content */}
        <div key={active} className="reveal in" style={{ display: "grid", gridTemplateColumns: "1fr 1.6fr", gap: 64, alignItems: "start" }}>
          <div style={{ position: "relative" }}>
            <div style={{ aspectRatio: "1/1", border: "1px solid var(--line)", background: "var(--paper)", display: "grid", placeItems: "center", color: "var(--ink-2)" }}>
              <Motif size={300} />
            </div>
            <div style={{ display: "flex", justifyContent: "space-between", marginTop: 14 }}>
              <span className="mono" style={{ fontSize: 10, letterSpacing: "0.2em", color: "var(--ink-soft)", textTransform: "uppercase" }}>
                Region · {cur.label}
              </span>
              <span className="mono" style={{ fontSize: 10, letterSpacing: "0.2em", color: "var(--ink-soft)", textTransform: "uppercase" }}>
                {cur.count}
              </span>
            </div>
          </div>

          <div>
            <ul style={{ listStyle: "none", margin: 0, padding: 0 }}>
              {cur.items.map((it, i) => (
                <li key={it.name} style={{ display: "grid", gridTemplateColumns: "40px 1fr 140px 140px 30px", alignItems: "center", padding: "22px 0", borderTop: "1px solid var(--line)", borderBottom: i === cur.items.length - 1 ? "1px solid var(--line)" : "none", gap: 16 }}>
                  <span className="mono" style={{ fontSize: 11, color: "var(--ink-muted)" }}>{String(i + 1).padStart(2, "0")}</span>
                  <div>
                    <div className="serif" style={{ fontSize: 24, lineHeight: 1.15 }}>{it.name}</div>
                    <div className="mono" style={{ fontSize: 11, color: "var(--ink-muted)", marginTop: 4, letterSpacing: "0.06em" }}>{it.note}</div>
                  </div>
                  <div className="mono" style={{ fontSize: 11, color: "var(--ink-soft)", letterSpacing: "0.06em" }}>{it.time}</div>
                  <div className="mono" style={{ fontSize: 11, color: "var(--ink-soft)", letterSpacing: "0.06em" }}>{it.stay}</div>
                  <Arrow />
                </li>
              ))}
            </ul>
          </div>
        </div>
      </div>
    </section>
  );
};

/* ---------- OUTCOMES — animated counters ---------- */
const useCountUp = (target, duration = 1600, run = false) => {
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    if (!run) return;
    let raf, start;
    const step = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(target * eased);
      if (p < 1) raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [target, duration, run]);
  return val;
};

const Counter = ({ value, suffix = "", decimals = 0, run, label, sub }) => {
  const v = useCountUp(value, 1700, run);
  const formatted = decimals > 0 ? v.toFixed(decimals) : Math.round(v).toLocaleString();
  return (
    <div style={{ padding: "32px 28px", borderRight: "1px solid var(--line)" }}>
      <div className="serif" style={{ fontSize: "clamp(56px, 7vw, 96px)", lineHeight: 1, letterSpacing: "-0.02em", fontFeatureSettings: "'tnum'" }}>
        {formatted}<span style={{ fontSize: "0.5em", color: "var(--sage-deep)", marginLeft: 4 }}>{suffix}</span>
      </div>
      <div style={{ marginTop: 16, fontSize: 14, color: "var(--ink)" }}>{label}</div>
      <div className="mono" style={{ marginTop: 6, fontSize: 11, color: "var(--ink-muted)", letterSpacing: "0.08em" }}>{sub}</div>
    </div>
  );
};

const Outcomes = () => {
  const [run, setRun] = React.useState(false);
  const ref = React.useRef(null);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => { if (e.isIntersecting) { setRun(true); io.disconnect(); } });
    }, { threshold: 0.3 });
    io.observe(el);
    return () => io.disconnect();
  }, []);

  return (
    <section id="outcomes" ref={ref} style={{ padding: "120px 32px", maxWidth: 1400, margin: "0 auto" }}>
      <div className="reveal" style={{ marginBottom: 56 }}>
        <Chapter num={4} label="Outcomes" />
        <div style={{ display: "grid", gridTemplateColumns: "1fr auto", alignItems: "end", gap: 32, marginTop: 20 }}>
          <h2 className="serif" style={{ margin: 0, fontSize: "clamp(36px, 4.8vw, 64px)", lineHeight: 1, letterSpacing: "-0.015em", fontWeight: 400, maxWidth: 880 }}>
            Numbers we publish, even when they're <span style={{ fontStyle: "italic" }}>inconvenient</span>.
          </h2>
          <div className="mono" style={{ fontSize: 11, color: "var(--ink-muted)", letterSpacing: "0.1em" }}>
            DATA SOURCE · NJR + INTERNAL REGISTRY · 2009–2025
          </div>
        </div>
      </div>

      <div className="reveal" style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", border: "1px solid var(--line)" }}>
        <Counter run={run} value={94} suffix="%" label="Return to sport" sub="ACL cohort, 12-month follow-up" />
        <Counter run={run} value={3420} label="Procedures performed" sub="Since 2009" />
        <Counter run={run} value={4.9} decimals={1} suffix="/5" label="Patient-reported satisfaction" sub="n = 1,840 verified surveys" />
        <div style={{ padding: "32px 28px" }}>
          <div className="serif" style={{ fontSize: "clamp(56px, 7vw, 96px)", lineHeight: 1, letterSpacing: "-0.02em" }}>
            0.4<span style={{ fontSize: "0.5em", color: "var(--sage-deep)", marginLeft: 4 }}>%</span>
          </div>
          <div style={{ marginTop: 16, fontSize: 14 }}>30-day complication rate</div>
          <div className="mono" style={{ marginTop: 6, fontSize: 11, color: "var(--ink-muted)", letterSpacing: "0.08em" }}>
            Below national avg. of 1.6%
          </div>
        </div>
      </div>

      {/* mini chart */}
      <div className="reveal" style={{ marginTop: 56, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 56, alignItems: "start" }}>
        <div>
          <div className="mono" style={{ fontSize: 11, letterSpacing: "0.2em", color: "var(--ink-soft)", textTransform: "uppercase" }}>
            Patient-reported function · KOOS, 24mo post-op
          </div>
          <KOOSChart />
          <div className="mono" style={{ fontSize: 11, color: "var(--ink-muted)", marginTop: 12 }}>
            n = 1,240 · published in JBJS, 2024
          </div>
        </div>
        <div style={{ borderLeft: "1px solid var(--line)", paddingLeft: 32 }}>
          <div className="serif" style={{ fontSize: 28, lineHeight: 1.25, letterSpacing: "-0.01em" }}>
            "If your surgeon won't show you their full data — including the bad weeks — find another surgeon."
          </div>
          <div className="mono" style={{ marginTop: 18, fontSize: 11, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ink-soft)" }}>
            — M.H., from a 2024 lecture
          </div>
        </div>
      </div>
    </section>
  );
};

const KOOSChart = () => {
  /* simple line chart — pre vs post over 24mo */
  const data = [42, 48, 56, 64, 72, 80, 86, 90, 92, 93, 94, 94, 94];
  const w = 520, h = 180, pad = 16;
  const max = 100, min = 0;
  const stepX = (w - pad * 2) / (data.length - 1);
  const points = data.map((v, i) => [pad + i * stepX, h - pad - ((v - min) / (max - min)) * (h - pad * 2)]);
  const path = points.map(([x, y], i) => (i === 0 ? `M${x},${y}` : `L${x},${y}`)).join(" ");
  const areaPath = `${path} L${pad + (data.length - 1) * stepX},${h - pad} L${pad},${h - pad} Z`;
  return (
    <svg viewBox={`0 0 ${w} ${h}`} width="100%" style={{ marginTop: 16, color: "var(--sage-deep)" }} aria-label="KOOS chart">
      <g stroke="var(--line)" strokeDasharray="2 4">
        {[0.25, 0.5, 0.75].map((p) => (
          <line key={p} x1={pad} x2={w - pad} y1={pad + p * (h - pad * 2)} y2={pad + p * (h - pad * 2)} />
        ))}
      </g>
      <path d={areaPath} fill="currentColor" opacity="0.10" />
      <path d={path} fill="none" stroke="currentColor" strokeWidth="1.5" />
      {points.map(([x, y], i) => (
        <circle key={i} cx={x} cy={y} r="2.4" fill="var(--paper)" stroke="currentColor" strokeWidth="1.2" />
      ))}
      <text x={points[0][0] + 6} y={points[0][1] - 6} fontFamily="var(--mono)" fontSize="10" fill="var(--ink-muted)">pre · 42</text>
      <text x={points[points.length - 1][0] - 36} y={points[points.length - 1][1] - 8} fontFamily="var(--mono)" fontSize="10" fill="var(--ink)">24mo · 94</text>
    </svg>
  );
};

Object.assign(window, { About, Procedures, Outcomes, KOOSChart });
