/* global React, I, useState, useEffect, useMemo, useRef */

// ============================================================================
// ODONTOGRAM
// ============================================================================
// 32 adult teeth — Universal numbering 1-32
// Upper: 1 (back R) ... 16 (back L)
// Lower: 17 (back L lower) ... 32 (back R lower)

const TOOTH_TYPES = {
  // 1=molar, 2=premolar, 3=canine, 4=incisor
  1:1, 2:1, 3:1, 4:2, 5:2, 6:3, 7:4, 8:4,
  9:4, 10:4, 11:3, 12:2, 13:2, 14:1, 15:1, 16:1,
  17:1, 18:1, 19:1, 20:2, 21:2, 22:3, 23:4, 24:4,
  25:4, 26:4, 27:3, 28:2, 29:2, 30:1, 31:1, 32:1,
};
const ANTERIOR = new Set([6,7,8,9,10,11, 22,23,24,25,26,27]);
const POSTERIOR = new Set([1,2,3,4,5, 12,13,14,15,16, 17,18,19,20,21, 28,29,30,31,32]);

// Sample existing conditions
const TOOTH_CONDITIONS = {
  3: { state: "filling", surfaces: ["O"], color: "var(--blue-500)" },
  14: { state: "crown", color: "var(--amber-500)" },
  18: { state: "missing" },
  19: { state: "filling", surfaces: ["MO"], color: "var(--blue-500)" },
  30: { state: "rct", color: "var(--violet-500)" },
  8: { state: "watch", color: "var(--amber-500)" },
  9: { state: "watch", color: "var(--amber-500)" },
  31: { state: "caries", surfaces: ["D"], color: "var(--rose-500)" },
};

function Tooth({ num, selected, onClick, locked, condition, size = 32 }) {
  const type = TOOTH_TYPES[num];
  const isMolar = type === 1;
  const isPM = type === 2;
  const isCanine = type === 3;
  const cond = condition || {};
  const w = size;
  const h = size * 1.2;

  // base color: ivory
  const base = locked ? "oklch(94% 0.005 110)" : "oklch(98% 0.005 80)";
  const stroke = selected ? "var(--sage-500)" : locked ? "oklch(88% 0.005 110)" : "oklch(75% 0.01 60)";

  // Render crown view (5 surface squares for molars/PM, simpler for incisors)
  return (
    <div
      onClick={!locked ? onClick : undefined}
      style={{
        cursor: locked ? "not-allowed" : "pointer",
        opacity: locked ? 0.4 : 1,
        display: "flex", flexDirection: "column", alignItems: "center",
        userSelect: "none",
      }}
    >
      <div style={{ fontSize: 9, color: "var(--fg-quaternary)", marginBottom: 2, fontVariantNumeric: "tabular-nums" }}>{num}</div>
      <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
        {cond.state === "missing" ? (
          <g>
            <line x1="4" y1="4" x2={w - 4} y2={h - 4} stroke="var(--rose-500)" strokeWidth="2" strokeLinecap="round" />
            <line x1={w - 4} y1="4" x2="4" y2={h - 4} stroke="var(--rose-500)" strokeWidth="2" strokeLinecap="round" />
          </g>
        ) : (
          <>
            {/* Crown background */}
            <rect x="2" y="2" width={w - 4} height={h * 0.55} rx="6" fill={base} stroke={stroke} strokeWidth={selected ? 2 : 1.2} />
            {/* Root */}
            {isMolar ? (
              <>
                <path d={`M 4 ${h*0.55} Q ${w/4} ${h*0.8} ${w/4} ${h - 2}`} fill="none" stroke={stroke} strokeWidth="1.2" />
                <path d={`M ${w-4} ${h*0.55} Q ${3*w/4} ${h*0.8} ${3*w/4} ${h - 2}`} fill="none" stroke={stroke} strokeWidth="1.2" />
                <path d={`M ${w/4} ${h-2} L ${3*w/4} ${h-2}`} fill="none" stroke="transparent" />
              </>
            ) : (
              <path d={`M ${w/2 - 4} ${h*0.55} L ${w/2 - 2} ${h - 2} L ${w/2 + 2} ${h - 2} L ${w/2 + 4} ${h*0.55} Z`} fill={base} stroke={stroke} strokeWidth="1.2" />
            )}
            {/* Surface fills */}
            {!isCanine && type !== 4 && (
              <>
                {/* Occlusal */}
                {cond.surfaces?.includes("O") && (
                  <rect x={w*0.3} y={h*0.18} width={w*0.4} height={h*0.22} fill={cond.color} opacity="0.85" />
                )}
                {cond.surfaces?.includes("MO") && (
                  <path d={`M ${w*0.15} ${h*0.16} L ${w*0.7} ${h*0.16} L ${w*0.7} ${h*0.42} L ${w*0.15} ${h*0.42} Z`} fill={cond.color} opacity="0.85" />
                )}
                {cond.surfaces?.includes("D") && (
                  <rect x={w*0.55} y={h*0.16} width={w*0.3} height={h*0.26} fill={cond.color} opacity="0.85" />
                )}
              </>
            )}
            {/* Crown overlay */}
            {cond.state === "crown" && (
              <rect x="3" y="3" width={w - 6} height={h * 0.53} rx="5" fill="none" stroke={cond.color} strokeWidth="2.4" />
            )}
            {/* RCT lines */}
            {cond.state === "rct" && (
              <g stroke={cond.color} strokeWidth="1.4">
                <line x1={w/2} y1={h*0.55} x2={w/2} y2={h - 4} />
                <line x1={w/3} y1={h*0.6} x2={w/3} y2={h - 6} />
                <line x1={2*w/3} y1={h*0.6} x2={2*w/3} y2={h - 6} />
              </g>
            )}
            {/* Watch dot */}
            {cond.state === "watch" && (
              <circle cx={w/2} cy={h*0.3} r="3" fill="var(--amber-500)" />
            )}
            {/* Caries */}
            {cond.state === "caries" && (
              <circle cx={w*0.7} cy={h*0.25} r="2.5" fill="var(--rose-500)" />
            )}
          </>
        )}
        {/* Selected highlight */}
        {selected && (
          <rect x="0" y="0" width={w} height={h} rx="6" fill="var(--sage-500)" opacity="0.08" />
        )}
      </svg>
    </div>
  );
}

function Odontogram({ selectedTooth, onSelectTooth, lockedRule, compact, onToggleCompact }) {
  // lockedRule: function num => boolean (locked when true)
  const upperRight = [1,2,3,4,5,6,7,8];
  const upperLeft = [9,10,11,12,13,14,15,16];
  const lowerLeft = [17,18,19,20,21,22,23,24];
  const lowerRight = [25,26,27,28,29,30,31,32];

  return (
    <div style={{
      background: "var(--bg-surface)",
      border: "1px solid var(--border-hairline)",
      borderRadius: 10,
      padding: compact ? "10px 14px" : "16px 20px",
      transition: "padding 200ms",
    }}>
      <div style={{ display: "flex", alignItems: "center", marginBottom: compact ? 8 : 14 }}>
        <h3 style={{ margin: 0, fontSize: 13, fontWeight: 600 }}>Odontogram</h3>
        <span className="chip outline sm" style={{ marginLeft: 8 }}>Universal numbering</span>
        <div className="spacer" />
        <Legend />
        <div className="divider v" style={{ height: 18, margin: "0 10px" }} />
        <button className="btn icon ghost sm" onClick={onToggleCompact} title={compact ? "Expand" : "Minimize"}>
          {compact ? <I.ChevronDown size={13} /> : <I.ChevronUp size={13} />}
        </button>
      </div>

      {!compact && (
        <>
          <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 4, gap: 16 }}>
            <ToothRow nums={upperRight} side="R" onSelectTooth={onSelectTooth} selectedTooth={selectedTooth} lockedRule={lockedRule} />
            <ToothRow nums={upperLeft} side="L" onSelectTooth={onSelectTooth} selectedTooth={selectedTooth} lockedRule={lockedRule} />
          </div>

          <div style={{ height: 1, background: "var(--border-hairline)", margin: "10px 0" }} />

          <div style={{ display: "flex", justifyContent: "space-between", gap: 16 }}>
            <ToothRow nums={lowerLeft.slice().reverse()} side="R-flip" onSelectTooth={onSelectTooth} selectedTooth={selectedTooth} lockedRule={lockedRule} lower />
            <ToothRow nums={lowerRight.slice().reverse()} side="L-flip" onSelectTooth={onSelectTooth} selectedTooth={selectedTooth} lockedRule={lockedRule} lower />
          </div>

          <div style={{ display: "flex", justifyContent: "space-between", fontSize: 9.5, color: "var(--fg-quaternary)", marginTop: 6, padding: "0 4px", textTransform: "uppercase", letterSpacing: "0.06em" }}>
            <span>Upper Right · 1-8</span>
            <span>Upper Left · 9-16</span>
          </div>
          <div style={{ display: "flex", justifyContent: "space-between", fontSize: 9.5, color: "var(--fg-quaternary)", marginTop: 2, padding: "0 4px", textTransform: "uppercase", letterSpacing: "0.06em" }}>
            <span>Lower Right · 32-25</span>
            <span>Lower Left · 24-17</span>
          </div>
        </>
      )}

      {compact && (
        <div style={{ display: "flex", gap: 12, alignItems: "center" }}>
          <div style={{ display: "flex", gap: 2 }}>
            {[...upperRight, ...upperLeft].map(n => (
              <button key={n} onClick={() => onSelectTooth(n)} style={{
                width: 14, height: 18, borderRadius: 2,
                background: selectedTooth === n ? "var(--sage-500)" : TOOTH_CONDITIONS[n] ? "var(--blue-200)" : "var(--bg-sunken)",
                cursor: "pointer",
              }} title={`#${n}`} />
            ))}
          </div>
          <div className="muted tiny">|</div>
          <div style={{ display: "flex", gap: 2 }}>
            {[...lowerLeft.slice().reverse(), ...lowerRight.slice().reverse()].map(n => (
              <button key={n} onClick={() => onSelectTooth(n)} style={{
                width: 14, height: 18, borderRadius: 2,
                background: selectedTooth === n ? "var(--sage-500)" : TOOTH_CONDITIONS[n] ? "var(--blue-200)" : "var(--bg-sunken)",
                cursor: "pointer",
              }} title={`#${n}`} />
            ))}
          </div>
          {selectedTooth && <span className="chip sage sm">Tooth #{selectedTooth} selected</span>}
        </div>
      )}
    </div>
  );
}

function ToothRow({ nums, onSelectTooth, selectedTooth, lockedRule, lower }) {
  return (
    <div style={{ display: "flex", gap: 4, flexDirection: lower ? "column-reverse" : "column" }}>
      <div style={{ display: "flex", gap: 4 }}>
        {nums.map(n => (
          <Tooth
            key={n}
            num={n}
            selected={selectedTooth === n}
            onClick={() => onSelectTooth(n)}
            locked={lockedRule ? lockedRule(n) : false}
            condition={TOOTH_CONDITIONS[n]}
          />
        ))}
      </div>
    </div>
  );
}

function Legend() {
  return (
    <div style={{ display: "flex", gap: 12, fontSize: 10.5 }}>
      <LegendDot color="var(--blue-500)" label="Existing" />
      <LegendDot color="var(--amber-500)" label="Watch" />
      <LegendDot color="var(--rose-500)" label="Caries" />
      <LegendDot color="var(--violet-500)" label="RCT" />
      <LegendDot color="oklch(60% 0.01 110)" label="Missing" cross />
    </div>
  );
}
function LegendDot({ color, label, cross }) {
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 4, color: "var(--fg-secondary)" }}>
      {cross ? (
        <span style={{ width: 8, height: 8, position: "relative" }}>
          <span style={{ position: "absolute", inset: 0, background: `linear-gradient(45deg, transparent 40%, ${color} 40% 60%, transparent 60%), linear-gradient(135deg, transparent 40%, ${color} 40% 60%, transparent 60%)` }} />
        </span>
      ) : (
        <span style={{ width: 8, height: 8, borderRadius: 2, background: color }} />
      )}
      {label}
    </span>
  );
}

// ============================================================================
// CHARTING
// ============================================================================
const PROCEDURE_CATEGORIES = [
  { id: "exam", label: "Exam", count: 8, icon: I.Stethoscope },
  { id: "xray", label: "X-rays", count: 12, icon: I.XRay },
  { id: "prev", label: "Preventive", count: 14, icon: I.Heart },
  { id: "comp", label: "Composites", count: 18, icon: I.Layers, restrictAnt: false },
  { id: "compAnt", label: "Anterior Comp", count: 4, restrictAnt: true },
  { id: "amalg", label: "Amalgam", count: 6 },
  { id: "crown", label: "Crowns", count: 9 },
  { id: "endo", label: "Endo / RCT", count: 11 },
  { id: "perio", label: "Perio", count: 8 },
  { id: "impl", label: "Implants", count: 6, explosion: true },
  { id: "surg", label: "Surgical", count: 14 },
  { id: "ortho", label: "Ortho", count: 7 },
];

const PROCEDURES = {
  exam: [
    { code: "D0120", desc: "Periodic oral evaluation", fee: 65 },
    { code: "D0150", desc: "Comprehensive oral evaluation", fee: 120 },
    { code: "D0180", desc: "Comprehensive periodontal eval", fee: 150 },
  ],
  comp: [
    { code: "D2391", desc: "Resin-based composite — 1 surf, posterior", fee: 215 },
    { code: "D2392", desc: "Resin-based composite — 2 surf, posterior", fee: 265 },
    { code: "D2393", desc: "Resin-based composite — 3 surf, posterior", fee: 320 },
  ],
  compAnt: [
    { code: "D2330", desc: "Resin-based composite — 1 surf, anterior", fee: 195 },
    { code: "D2331", desc: "Resin-based composite — 2 surf, anterior", fee: 230 },
    { code: "D2332", desc: "Resin-based composite — 3 surf, anterior", fee: 270 },
    { code: "D2335", desc: "Resin-based composite — 4+ surf, anterior", fee: 320 },
  ],
  impl: [
    { code: "D6010", desc: "Surgical placement of implant body", fee: 1850, bundle: true, parts: ["D6010 Implant placement", "D6056 Prefab abutment", "D6066 Implant crown", "D6020 Second-stage surgery"] },
  ],
};

const TREATMENT_PLAN = [
  { id: 1, code: "D2391", desc: "Resin composite 1S, posterior", tooth: "#14 (O)", phase: 1, fee: 215, insEst: 172, patEst: 43, status: "Proposed" },
  { id: 2, code: "D2392", desc: "Resin composite 2S, posterior", tooth: "#19 (MO)", phase: 1, fee: 265, insEst: 212, patEst: 53, status: "Proposed" },
  { id: 3, code: "D1110", desc: "Adult prophylaxis", tooth: "—", phase: 1, fee: 105, insEst: 105, patEst: 0, status: "Accepted" },
  { id: 4, code: "D0274", desc: "Bitewings — four films", tooth: "—", phase: 1, fee: 78, insEst: 78, patEst: 0, status: "Accepted" },
  { id: 5, code: "D2740", desc: "Crown — porcelain/ceramic", tooth: "#30", phase: 2, fee: 1450, insEst: 725, patEst: 725, status: "Proposed" },
  { id: 6, code: "D6010", desc: "Implant body — endosteal", tooth: "#19", phase: 3, fee: 1850, insEst: 925, patEst: 925, status: "Proposed" },
];

function Charting() {
  const [selectedTooth, setSelectedTooth] = useState(14);
  const [category, setCategory] = useState("comp");
  const [compact, setCompact] = useState(false);
  const [hoverImplant, setHoverImplant] = useState(false);
  const [addConditionOpen, setAddConditionOpen] = useState(false);
  const [tab, setTab] = useState("tx");

  const lockedRule = (n) => {
    if (category === "compAnt") return !ANTERIOR.has(n);
    if (category === "comp") return !POSTERIOR.has(n);
    return false;
  };

  const procs = PROCEDURES[category] || [];
  const sumPlan = TREATMENT_PLAN.reduce((acc, r) => {
    acc.fee += r.fee; acc.ins += r.insEst; acc.pat += r.patEst;
    return acc;
  }, { fee: 0, ins: 0, pat: 0 });

  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      {/* Patient header strip */}
      <PatientHeaderStrip />

      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "1fr 300px", gap: 14, padding: 14, minHeight: 0 }}>
        {/* Left: Odontogram + Tx plan */}
        <div style={{ display: "flex", flexDirection: "column", gap: 14, minHeight: 0, overflow: "auto" }}>
          <Odontogram
            selectedTooth={selectedTooth}
            onSelectTooth={(n) => { setSelectedTooth(n); if (n) setAddConditionOpen(true); }}
            lockedRule={lockedRule}
            compact={compact}
            onToggleCompact={() => setCompact(!compact)}
          />

          {/* Tx plan / Perio tabs */}
          <div className="card" style={{ flex: 1, minHeight: 280, display: "flex", flexDirection: "column" }}>
            <div style={{ padding: "0 14px", borderBottom: "1px solid var(--border-hairline)" }}>
              <div className="tabs" style={{ borderBottom: "none" }}>
                <div className={"tab " + (tab === "tx" ? "active" : "")} onClick={() => setTab("tx")}>Treatment Plan <span className="count">6</span></div>
                <div className={"tab " + (tab === "perio" ? "active" : "")} onClick={() => setTab("perio")}>Perio Charts <span className="count">8/26</span></div>
                <div className="tab">Clinical Notes</div>
                <div className="tab">Conditions</div>
                <div className="tab">Images</div>
                <div style={{ flex: 1 }} />
                {tab === "tx" && (
                  <div style={{ display: "flex", alignItems: "center", gap: 6, paddingTop: 6 }}>
                    <button className="btn sm"><I.Printer size={12} /> Print</button>
                    <button className="btn sm"><I.Send size={12} /> Send</button>
                    <button className="btn sm"><I.Smartphone size={12} /> Present (Kiosk)</button>
                  </div>
                )}
              </div>
            </div>
            <div style={{ flex: 1, overflow: "auto" }}>
              {tab === "tx" ? (
                <TxPlanTable />
              ) : (
                <PerioPreview />
              )}
            </div>
            {tab === "tx" && (
              <div style={{ padding: "10px 14px", borderTop: "1px solid var(--border-hairline)", display: "flex", alignItems: "center", gap: 16, background: "var(--bg-subtle)" }}>
                <SumStat label="Plan total" v={`$${sumPlan.fee.toFixed(0)}`} />
                <SumStat label="Insurance est." v={`$${sumPlan.ins.toFixed(0)}`} accent="sage" />
                <SumStat label="Patient est." v={`$${sumPlan.pat.toFixed(0)}`} accent="amber" />
                <div className="spacer" />
                <span className="chip sage"><I.Check size={11} /> 2 accepted</span>
                <span className="chip outline">4 proposed</span>
              </div>
            )}
          </div>
        </div>

        {/* Right: Quick codes */}
        <div className="card" style={{ display: "flex", flexDirection: "column", overflow: "hidden" }}>
          <div className="card-head">
            <h3>Quick codes</h3>
            <div className="spacer" />
            <button className="btn ghost sm icon"><I.Settings size={12} /></button>
          </div>
          <div style={{ padding: 6, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4, borderBottom: "1px solid var(--border-hairline)" }}>
            {PROCEDURE_CATEGORIES.map(c => {
              const active = category === c.id;
              const IconC = c.icon;
              return (
                <button key={c.id} onClick={() => setCategory(c.id)}
                  onMouseEnter={() => c.explosion && setHoverImplant(true)}
                  onMouseLeave={() => setHoverImplant(false)}
                  style={{
                    padding: "8px 10px",
                    borderRadius: 6,
                    background: active ? "var(--sage-50)" : "transparent",
                    color: active ? "var(--sage-700)" : "var(--fg-secondary)",
                    fontWeight: active ? 600 : 500,
                    fontSize: 12,
                    border: 0,
                    cursor: "pointer",
                    textAlign: "left",
                    display: "flex", alignItems: "center", gap: 6,
                    position: "relative",
                  }}>
                  {IconC && <IconC size={12} />}
                  <span style={{ flex: 1 }}>{c.label}</span>
                  <span className="tiny tabular" style={{ opacity: 0.5 }}>{c.count}</span>
                  {c.explosion && <I.Zap size={10} style={{ color: "var(--violet-500)" }} />}
                </button>
              );
            })}
          </div>

          {/* Procedures in category */}
          <div style={{ flex: 1, overflow: "auto", padding: 8 }}>
            <div className="tiny muted" style={{ padding: "4px 8px 8px", textTransform: "uppercase", letterSpacing: "0.06em", fontWeight: 600 }}>
              {PROCEDURE_CATEGORIES.find(c => c.id === category)?.label || "Procedures"}
            </div>
            {category === "compAnt" && (
              <div style={{ padding: 8, background: "var(--amber-50)", borderRadius: 6, marginBottom: 8, display: "flex", gap: 6, fontSize: 11.5, color: "var(--amber-700)" }}>
                <I.Lock size={12} /> Only anterior teeth selectable (6-11, 22-27). Posteriors locked.
              </div>
            )}
            {procs.length > 0 ? procs.map(p => (
              <button key={p.code} style={{
                display: "block", width: "100%", padding: "8px 10px", marginBottom: 4,
                borderRadius: 6, background: "var(--bg-subtle)", textAlign: "left", cursor: "pointer",
                border: 0,
              }}>
                <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
                  <span className="mono" style={{ fontSize: 11, fontWeight: 600, color: "var(--sage-700)" }}>{p.code}</span>
                  <span style={{ flex: 1 }} />
                  <span className="tabular tiny medium">${p.fee}</span>
                </div>
                <div style={{ fontSize: 11.5, marginTop: 2, lineHeight: 1.3 }}>{p.desc}</div>
                {p.bundle && (
                  <div style={{ marginTop: 6, padding: "6px 8px", background: "var(--violet-50)", borderRadius: 4, fontSize: 10.5 }}>
                    <div style={{ display: "flex", alignItems: "center", gap: 4, color: "var(--violet-700)", fontWeight: 600, marginBottom: 3 }}>
                      <I.Zap size={10} /> Explosion code — 4 procedures
                    </div>
                    {p.parts.map((part, i) => (
                      <div key={i} style={{ color: "var(--violet-700)", paddingLeft: 14 }}>· {part}</div>
                    ))}
                  </div>
                )}
              </button>
            )) : (
              <div className="muted tiny" style={{ padding: "20px 10px", textAlign: "center" }}>
                Pick a category to see procedures
              </div>
            )}
          </div>

          {/* Selected tooth panel */}
          {selectedTooth && (
            <div style={{ borderTop: "1px solid var(--border-hairline)", padding: 12, background: "var(--bg-subtle)" }}>
              <div style={{ display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }}>
                <span className="chip sage">Tooth #{selectedTooth}</span>
                <span className="tiny muted">{ANTERIOR.has(selectedTooth) ? "Anterior" : "Posterior"}</span>
              </div>
              <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4 }}>
                <button className="btn sm" onClick={() => setAddConditionOpen(true)}><I.Plus size={11} /> Condition</button>
                <button className="btn sm">Surface</button>
                <button className="btn sm">Note</button>
                <button className="btn sm primary">Plan procedure</button>
              </div>
            </div>
          )}
        </div>
      </div>

      {addConditionOpen && (
        <AddConditionPopup tooth={selectedTooth} onClose={() => setAddConditionOpen(false)} />
      )}
    </div>
  );
}

function SumStat({ label, v, accent }) {
  const c = accent === "sage" ? "var(--sage-700)" : accent === "amber" ? "var(--amber-700)" : "var(--fg-primary)";
  return (
    <div>
      <div className="tiny muted">{label}</div>
      <div className="tabular" style={{ fontSize: 14, fontWeight: 600, color: c, letterSpacing: "-0.01em" }}>{v}</div>
    </div>
  );
}

function PatientHeaderStrip() {
  return (
    <div style={{
      padding: "10px 18px",
      background: "var(--bg-surface)",
      borderBottom: "1px solid var(--border-hairline)",
      display: "flex",
      alignItems: "center",
      gap: 12,
      flexShrink: 0,
    }}>
      <div className="avatar lg av-3">CR</div>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 15, fontWeight: 600, letterSpacing: "-0.01em" }}>Chase Rowley</div>
        <div className="tiny muted">33 y/o · DOB Nov 22, 1992 · Op 1 · Dr. Reilly</div>
      </div>
      <div style={{ flex: 1 }} />
      <div className="row" style={{ gap: 4 }}>
        <span className="chip outline sm">DO Composite #14 · #15</span>
        <span className="chip mint sm">9:00a – 10:00a</span>
        <span className="chip sage sm"><span className="dot" /> In room</span>
      </div>
      <div className="spacer" />
      <div className="row" style={{ gap: 6 }}>
        <button className="btn sm"><I.MessageSquare size={12} /></button>
        <button className="btn sm"><I.XRay size={12} /> Imaging</button>
        <button className="btn primary sm"><I.Mic size={12} /> Pillow Scribe</button>
      </div>
    </div>
  );
}

function TxPlanTable() {
  const phases = [1, 2, 3];
  const phaseLabels = { 1: "Phase 1 · Active treatment", 2: "Phase 2 · Restorative", 3: "Phase 3 · Major / Implants" };
  return (
    <table className="table" style={{ fontSize: 12 }}>
      <thead>
        <tr>
          <th style={{ width: 18 }}></th>
          <th style={{ width: 70 }}>Code</th>
          <th>Description</th>
          <th style={{ width: 90 }}>Tooth / surf</th>
          <th style={{ width: 80, textAlign: "right" }}>Fee</th>
          <th style={{ width: 90, textAlign: "right" }}>Ins. est.</th>
          <th style={{ width: 90, textAlign: "right" }}>Pat. est.</th>
          <th style={{ width: 100 }}>Status</th>
        </tr>
      </thead>
      <tbody>
        {phases.map(phase => (
          <React.Fragment key={phase}>
            <tr>
              <td colSpan={8} style={{ background: "var(--bg-subtle)", padding: "6px 12px", fontSize: 11, fontWeight: 600, color: "var(--fg-tertiary)", textTransform: "uppercase", letterSpacing: "0.05em" }}>
                {phaseLabels[phase]}
              </td>
            </tr>
            {TREATMENT_PLAN.filter(r => r.phase === phase).map(r => (
              <tr key={r.id}>
                <td><I.Move size={10} style={{ color: "var(--fg-quaternary)" }} /></td>
                <td><span className="mono" style={{ fontSize: 11, fontWeight: 600, color: "var(--sage-700)" }}>{r.code}</span></td>
                <td>{r.desc}</td>
                <td className="tabular">{r.tooth}</td>
                <td className="tabular" style={{ textAlign: "right" }}>${r.fee.toFixed(2)}</td>
                <td className="tabular" style={{ textAlign: "right", color: "var(--sage-700)" }}>${r.insEst.toFixed(2)}</td>
                <td className="tabular medium" style={{ textAlign: "right" }}>${r.patEst.toFixed(2)}</td>
                <td>
                  {r.status === "Accepted"
                    ? <span className="chip sage sm"><I.Check size={10} /> Accepted</span>
                    : <span className="chip outline sm">Proposed</span>}
                </td>
              </tr>
            ))}
          </React.Fragment>
        ))}
      </tbody>
    </table>
  );
}

function PerioPreview() {
  return (
    <div style={{ padding: 16 }}>
      <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 14 }}>
        <span className="chip sage"><I.Check size={11} /> Last full perio: Oct 14, 2025</span>
        <span className="chip mint">Next due in 92 days</span>
        <div className="spacer" />
        <button className="btn sm"><I.Mic size={12} /> Start Voice Perio</button>
      </div>
      <div style={{ overflowX: "auto" }}>
        <PerioGrid />
      </div>
    </div>
  );
}

function PerioGrid() {
  // Quick-render perio chart preview
  const teeth = Array.from({length: 16}, (_, i) => i + 1);
  return (
    <table className="mono" style={{ borderCollapse: "collapse", fontSize: 11 }}>
      <thead>
        <tr>
          <th style={{ width: 80 }}></th>
          {teeth.map(t => <th key={t} style={{ width: 30, padding: 2, color: "var(--fg-tertiary)", fontWeight: 500 }}>{t}</th>)}
        </tr>
      </thead>
      <tbody>
        {[
          ["PD facial", () => [Math.floor(Math.random()*3)+1, Math.floor(Math.random()*3)+1, Math.floor(Math.random()*3)+1]],
          ["GM facial", () => [0, 0, 0]],
          ["CAL facial", () => [Math.floor(Math.random()*3)+1, Math.floor(Math.random()*3)+1, Math.floor(Math.random()*3)+1]],
          ["MGJ", () => [Math.floor(Math.random()*2)+3, "", ""]],
        ].map(([label, gen]) => (
          <tr key={label}>
            <td style={{ padding: "4px 8px", color: "var(--fg-tertiary)", fontWeight: 500, fontSize: 10 }}>{label}</td>
            {teeth.map(t => (
              <td key={t} style={{ padding: 2, textAlign: "center", borderLeft: "1px solid var(--border-hairline)" }}>
                <span className="tabular" style={{ fontSize: 10 }}>{gen().filter(Boolean).join(" ")}</span>
              </td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

function AddConditionPopup({ tooth, onClose }) {
  const conditions = [
    "Caries", "Chip", "Crack", "Discoloration", "Erosion",
    "Fractured restoration", "Gingival recession", "Hypersensitivity",
    "Mobility I", "Mobility II", "Mobility III",
    "Open contact", "Open margin", "Plaque", "Calculus",
    "Wear facet", "Watch",
  ];
  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={{ width: 520 }} onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <h2>Add condition</h2>
          <span className="chip sage">Tooth #{tooth}</span>
          <div className="spacer" />
          <button className="btn icon ghost" onClick={onClose}><I.X size={14} /></button>
        </div>
        <div className="modal-body">
          <div className="field" style={{ marginBottom: 14 }}>
            <input className="input" placeholder="Search conditions…" />
          </div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4 }}>
            {conditions.map(c => (
              <button key={c} className="btn sm" style={{ justifyContent: "flex-start" }}>
                <I.Plus size={11} /> {c}
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// VOICE PERIO
// ============================================================================
function VoicePerio() {
  const [listening, setListening] = useState(true);
  const [activeTooth, setActiveTooth] = useState(8);
  const [transcript, setTranscript] = useState([
    { sp: "dr", t: "Hey Archy, start probing", ts: "0:00" },
    { sp: "sys", t: "Listening — tooth 1, position 1 (DF)" },
    { sp: "dr", t: "Two… three… two…", ts: "0:04" },
    { sp: "sys", t: "Recorded: PD 2 3 2 facial #1" },
    { sp: "dr", t: "Skip to six", ts: "0:09" },
    { sp: "sys", t: "Jumped to tooth #6 DF" },
    { sp: "dr", t: "Three… four… three… bleeding distal", ts: "0:12" },
    { sp: "sys", t: "Recorded PD 3 4 3 · BOP-D #6" },
    { sp: "dr", t: "Next", ts: "0:18" },
    { sp: "sys", t: "Moved to tooth #7 facial" },
    { sp: "dr", t: "Calculus mesial, two three two", ts: "0:22" },
    { sp: "sys", t: "Recorded CAL-M · PD 2 3 2 #7" },
  ]);

  // simulate "live" tooth blink
  useEffect(() => {
    const i = setInterval(() => {
      setActiveTooth(t => (t % 16) + 1);
    }, 1400);
    return () => clearInterval(i);
  }, []);

  return (
    <div style={{ flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" }}>
      <PatientHeaderStrip />

      <div style={{ flex: 1, display: "grid", gridTemplateColumns: "1fr 360px", overflow: "hidden", minHeight: 0 }}>
        {/* Chart area */}
        <div style={{ padding: 18, overflow: "auto" }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 14 }}>
            <div style={{
              display: "flex", alignItems: "center", gap: 10,
              padding: "10px 16px",
              background: listening ? "linear-gradient(90deg, var(--sage-50), var(--mint-100))" : "var(--bg-subtle)",
              borderRadius: 12,
              border: "1px solid " + (listening ? "var(--sage-200)" : "var(--border-hairline)"),
            }}>
              <div style={{ position: "relative", width: 28, height: 28 }}>
                <div style={{
                  position: "absolute", inset: 0, borderRadius: "50%",
                  background: listening ? "var(--sage-500)" : "var(--fg-quaternary)",
                  display: "grid", placeItems: "center", color: "white",
                  animation: listening ? "pulse 1.4s ease-out infinite" : "none",
                }}>
                  <I.Mic size={14} />
                </div>
                {listening && <div style={{
                  position: "absolute", inset: -4, borderRadius: "50%",
                  border: "2px solid var(--sage-500)", opacity: 0.4,
                  animation: "ripple 1.4s ease-out infinite",
                }} />}
              </div>
              <div>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{listening ? "Listening" : "Paused"}</div>
                <div className="tiny muted">Tooth #{activeTooth} · DF position</div>
              </div>
              <button className="btn sm" style={{ marginLeft: 10 }} onClick={() => setListening(!listening)}>
                {listening ? <I.Pause size={12} /> : <I.Play size={12} />}
                {listening ? "Pause" : "Resume"}
              </button>
            </div>

            <div style={{ flex: 1 }} />

            <span className="chip mint"><I.Sparkles size={11} /> Voice Perio · launched May 1, 2026</span>
            <button className="btn sm">Switch to manual</button>
          </div>

          {/* Perio chart */}
          <PerioFullChart activeTooth={activeTooth} />

          {/* Comparison */}
          <div className="card" style={{ marginTop: 14 }}>
            <div className="card-head">
              <h3>Compare to last visit · Oct 14, 2025</h3>
              <div className="spacer" />
              <span className="chip amber sm">↑ 4 sites worsened</span>
              <span className="chip sage sm">↓ 2 improved</span>
            </div>
            <div className="card-body">
              <div style={{ display: "flex", gap: 14, fontSize: 12 }}>
                <Pct v={68} label="Sites ≤ 3mm" color="sage" delta="+2%" />
                <Pct v={22} label="4mm pocketing" color="amber" delta="−1%" />
                <Pct v={8} label="≥ 5mm" color="rose" delta="+1%" />
                <Pct v={11} label="BOP %" color="amber" delta="+3%" />
                <Pct v={4} label="Mobility" color="amber" delta="0" />
                <Pct v={2} label="Furcation" color="rose" delta="0" />
              </div>
            </div>
          </div>
        </div>

        {/* Right: Commands + Transcript */}
        <div style={{ borderLeft: "1px solid var(--border-hairline)", background: "var(--bg-subtle)", display: "flex", flexDirection: "column", overflow: "hidden" }}>
          <div style={{ padding: "12px 14px", borderBottom: "1px solid var(--border-hairline)" }}>
            <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--fg-tertiary)", marginBottom: 6 }}>Live transcript</div>
            <div className="card" style={{ padding: 8, maxHeight: 220, overflowY: "auto", background: "var(--bg-surface)" }}>
              {transcript.slice().reverse().map((t, i) => (
                <div key={i} style={{ display: "flex", gap: 6, padding: "4px 0", fontSize: 12, opacity: 1 - i * 0.08 }}>
                  {t.sp === "dr" ? (
                    <>
                      <span className="chip sage sm" style={{ minWidth: 36, justifyContent: "center" }}>Dr</span>
                      <span>{t.t}</span>
                      {t.ts && <span className="tiny muted tabular" style={{ marginLeft: "auto" }}>{t.ts}</span>}
                    </>
                  ) : (
                    <>
                      <span className="chip mint sm" style={{ minWidth: 36, justifyContent: "center" }}>Sys</span>
                      <span style={{ color: "var(--fg-secondary)" }}>{t.t}</span>
                    </>
                  )}
                </div>
              ))}
            </div>
          </div>

          <div style={{ padding: "12px 14px", flex: 1, overflowY: "auto" }}>
            <div style={{ fontSize: 11, fontWeight: 600, textTransform: "uppercase", letterSpacing: "0.06em", color: "var(--fg-tertiary)", marginBottom: 6 }}>Commands</div>
            <CommandGroup title="Navigation" items={["Start probing", "Stop", "Pause / Resume", "Skip to [tooth]", "Next", "Back", "Go to mandibular", "Switch to lingual"]} />
            <CommandGroup title="Chart findings" items={["Bleeding facial / lingual", "Suppuration distal", "Calculus mesial", "Plaque mesial", "Mobility I/II/III", "Furcation I/II/III", "MGJ [number]"]} />
            <CommandGroup title="Removal" items={["Undo last", "Clear tooth", "Reset facial #N", "Cancel that"]} />
            <CommandGroup title="Regional" items={["Same for all anteriors", "Repeat last reading", "Generalized bleeding 4-7"]} />
          </div>
        </div>
      </div>

      <style>{`
        @keyframes pulse {
          0%, 100% { opacity: 1; }
          50% { opacity: 0.7; }
        }
        @keyframes ripple {
          0% { transform: scale(0.9); opacity: 0.8; }
          100% { transform: scale(1.4); opacity: 0; }
        }
      `}</style>
    </div>
  );
}

function Pct({ v, label, color, delta }) {
  return (
    <div style={{ flex: 1 }}>
      <div className="tiny muted">{label}</div>
      <div style={{ display: "flex", alignItems: "baseline", gap: 4 }}>
        <span className="tabular" style={{ fontSize: 18, fontWeight: 600, color: `var(--${color}-700)` }}>{v}{label.includes("%") ? "" : "%"}</span>
        <span className={"tiny tabular " + (delta.startsWith("+") ? "rose" : delta.startsWith("-") || delta.startsWith("−") ? "sage" : "muted")} style={{ color: delta.startsWith("+") ? "var(--rose-700)" : delta.startsWith("−") ? "var(--sage-700)" : "var(--fg-tertiary)" }}>
          {delta}
        </span>
      </div>
      <div style={{ height: 3, background: "var(--bg-sunken)", borderRadius: 2, marginTop: 4 }}>
        <div style={{ height: "100%", width: `${v}%`, background: `var(--${color}-500)`, borderRadius: 2 }} />
      </div>
    </div>
  );
}

function CommandGroup({ title, items }) {
  return (
    <div style={{ marginBottom: 12 }}>
      <div style={{ fontSize: 11, color: "var(--fg-tertiary)", fontWeight: 500, marginBottom: 4 }}>{title}</div>
      <div style={{ display: "flex", flexDirection: "column", gap: 3 }}>
        {items.map(i => (
          <div key={i} className="mono" style={{
            padding: "5px 8px", background: "var(--bg-surface)", borderRadius: 4,
            border: "1px solid var(--border-hairline)", fontSize: 11.5,
          }}>"{i}"</div>
        ))}
      </div>
    </div>
  );
}

function PerioFullChart({ activeTooth }) {
  // Generate realistic perio data
  const data = useMemo(() => {
    const seedRand = (s) => { let x = Math.sin(s) * 10000; return Math.abs(x - Math.floor(x)); };
    const teeth = Array.from({length: 16}, (_, i) => i + 1);
    return teeth.map(t => {
      const baseDepth = t === 1 || t === 16 ? 3 : (t >= 6 && t <= 11) ? 2 : 2.5;
      return {
        t,
        facial: [Math.round(baseDepth + seedRand(t) * 2), Math.round(baseDepth + seedRand(t+1)), Math.round(baseDepth + seedRand(t+2) * 1.5)],
        lingual: [Math.round(baseDepth + seedRand(t+10)), Math.round(baseDepth + seedRand(t+11)), Math.round(baseDepth + seedRand(t+12))],
        bopF: seedRand(t+20) > 0.7,
        bopL: seedRand(t+25) > 0.8,
        plaqueF: seedRand(t+30) > 0.6,
        mobility: t === 19 || t === 30 ? 1 : 0,
        recession: t === 6 || t === 11 ? 2 : 0,
      };
    });
  }, []);

  const teeth = Array.from({length: 16}, (_, i) => i + 1);
  const cellW = 38;

  return (
    <div style={{ background: "var(--bg-surface)", border: "1px solid var(--border-hairline)", borderRadius: 10, padding: 14 }}>
      <div style={{ display: "flex", alignItems: "center", marginBottom: 8 }}>
        <h3 style={{ margin: 0, fontSize: 13, fontWeight: 600 }}>Upper · Maxillary · Facial</h3>
        <div className="spacer" />
        <button className="btn sm ghost"><I.Eye size={11} /> Show lingual</button>
      </div>

      <div style={{ overflowX: "auto" }}>
        <table style={{ borderCollapse: "collapse", fontSize: 10.5 }} className="mono tabular">
          <thead>
            <tr>
              <th style={{ width: 72, textAlign: "left", padding: "6px 8px", color: "var(--fg-tertiary)", fontWeight: 500, fontSize: 10 }}>Tooth</th>
              {teeth.map(t => (
                <th key={t} style={{ width: cellW, padding: "4px 0", textAlign: "center", color: "var(--fg-tertiary)", fontWeight: 600,
                  background: t === activeTooth ? "var(--sage-50)" : "transparent",
                  borderRadius: t === activeTooth ? "4px 4px 0 0" : 0,
                }}>{t}</th>
              ))}
            </tr>
            <tr>
              <th></th>
              {teeth.map(t => (
                <th key={t} style={{ padding: 2, background: t === activeTooth ? "var(--sage-50)" : "transparent" }}>
                  <div style={{ display: "flex", justifyContent: "center", gap: 1 }}>
                    {data[t-1].plaqueF && <span style={{ width: 5, height: 5, borderRadius: "50%", background: "var(--blue-500)" }} title="Plaque" />}
                    {data[t-1].bopF && <span style={{ width: 5, height: 5, borderRadius: "50%", background: "var(--rose-500)" }} title="BOP" />}
                  </div>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            <RowHeader label="PD facial" />
            <tr>
              <td style={{ background: "var(--bg-subtle)" }}></td>
              {teeth.map(t => (
                <td key={t} style={{ padding: 0, background: t === activeTooth ? "var(--sage-50)" : "transparent" }}>
                  <div style={{ display: "flex", justifyContent: "space-around" }}>
                    {data[t-1].facial.map((n, i) => (
                      <span key={i} style={{
                        color: n >= 5 ? "var(--rose-700)" : n === 4 ? "var(--amber-700)" : "var(--fg-secondary)",
                        fontWeight: n >= 4 ? 600 : 400,
                      }}>{n}</span>
                    ))}
                  </div>
                </td>
              ))}
            </tr>
            <RowHeader label="GM" />
            <tr>
              <td style={{ background: "var(--bg-subtle)" }}></td>
              {teeth.map(t => (
                <td key={t} style={{ padding: 0, background: t === activeTooth ? "var(--sage-50)" : "transparent", textAlign: "center", color: "var(--fg-tertiary)" }}>
                  {data[t-1].recession > 0 ? `-${data[t-1].recession}` : 0}
                </td>
              ))}
            </tr>
            <RowHeader label="CAL" />
            <tr>
              <td style={{ background: "var(--bg-subtle)" }}></td>
              {teeth.map(t => (
                <td key={t} style={{ padding: 0, background: t === activeTooth ? "var(--sage-50)" : "transparent" }}>
                  <div style={{ display: "flex", justifyContent: "space-around" }}>
                    {data[t-1].facial.map((n, i) => (
                      <span key={i}>{n + (data[t-1].recession || 0)}</span>
                    ))}
                  </div>
                </td>
              ))}
            </tr>
            <RowHeader label="Mobility" />
            <tr>
              <td style={{ background: "var(--bg-subtle)" }}></td>
              {teeth.map(t => (
                <td key={t} style={{ padding: 0, background: t === activeTooth ? "var(--sage-50)" : "transparent", textAlign: "center", color: data[t-1].mobility ? "var(--amber-700)" : "var(--fg-quaternary)" }}>
                  {data[t-1].mobility || "·"}
                </td>
              ))}
            </tr>
            <tr>
              <td style={{ padding: "10px 8px 4px", color: "var(--fg-tertiary)", fontSize: 10, fontWeight: 500 }}>Tooth img</td>
              {teeth.map(t => (
                <td key={t} style={{ padding: 4, background: t === activeTooth ? "var(--sage-50)" : "transparent", textAlign: "center" }}>
                  <div style={{ display: "flex", justifyContent: "center" }}>
                    <Tooth num={t} size={26} />
                  </div>
                </td>
              ))}
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  );
}
function RowHeader({ label }) {
  return (
    <tr>
      <td style={{ padding: "6px 8px 0", color: "var(--fg-tertiary)", fontWeight: 500, fontSize: 10, background: "var(--bg-subtle)" }}>{label}</td>
      {Array.from({length: 16}, (_, i) => <td key={i} style={{ background: "var(--bg-subtle)" }}></td>)}
    </tr>
  );
}

Object.assign(window, { Charting, VoicePerio, Odontogram });
