// Patients list + Patient detail — wired to real API.

const PAY_METHODS = [
  { id: 'cash',     label: "Naqd" },
  { id: 'card',     label: 'Karta' },
  { id: 'transfer', label: "O'tkazma" },
  { id: 'debt',     label: 'Qarz' },
  { id: 'mixed',    label: 'Aralash' },
];

function EditVisitModal({ open, visit, onClose, onSaved, toast }) {
  const [doctorId, setDoctorId] = useState('');
  const [paymentMethod, setPaymentMethod] = useState('cash');
  const [notes, setNotes] = useState('');
  const [selectedSvcs, setSelectedSvcs] = useState([]);  // [{service_id, quantity, name, price}]
  const [doctors, setDoctors] = useState([]);
  const [allServices, setAllServices] = useState([]);
  const [saving, setSaving] = useState(false);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (!open || !visit) return;
    setLoading(true);
    Promise.all([
      window.API.listDoctors(),
      window.API.listServices(),
    ]).then(([docs, svcs]) => {
      setDoctors(docs);
      setAllServices(svcs);
      setDoctorId(visit.doctor?.id ? String(visit.doctor.id) : '');
      setPaymentMethod(visit.payment_method || 'cash');
      setNotes(visit.notes || '');
      const items = (visit.items || []).map(it => ({
        service_id: it.service_id,
        quantity: it.quantity,
        name: it.service?.name || `#${it.service_id}`,
        price: Number(it.service?.price || it.price_at_moment),
      }));
      setSelectedSvcs(items);
      setLoading(false);
    }).catch(err => {
      toast?.({ kind: 'danger', title: 'Yuklash xato', msg: err.message });
      setLoading(false);
    });
  }, [open, visit?.id]);

  const total = selectedSvcs.reduce((s, x) => s + Number(x.price) * x.quantity, 0);

  const toggleSvc = (svc) => {
    setSelectedSvcs(prev => {
      const exists = prev.find(x => x.service_id === svc.id);
      if (exists) return prev.filter(x => x.service_id !== svc.id);
      return [...prev, { service_id: svc.id, quantity: 1, name: svc.name, price: Number(svc.price) }];
    });
  };

  const setQty = (sid, q) => {
    const n = Math.max(1, parseInt(q) || 1);
    setSelectedSvcs(prev => prev.map(x => x.service_id === sid ? { ...x, quantity: n } : x));
  };

  const save = async () => {
    if (selectedSvcs.length === 0) {
      toast?.({ kind: 'warning', title: "Kamida 1 ta xizmat tanlang" });
      return;
    }
    setSaving(true);
    try {
      const payload = {
        doctor_id: doctorId ? Number(doctorId) : null,
        doctor_clear: !doctorId,
        services: selectedSvcs.map(s => ({ service_id: s.service_id, quantity: s.quantity })),
        payment_method: paymentMethod,
        notes: notes || null,
      };
      await window.API.updateVisit(visit.id, payload);
      toast?.({ kind: 'success', title: 'Saqlandi' });
      onSaved?.();
    } catch (err) {
      toast?.({ kind: 'danger', title: 'Saqlash xato', msg: err.message });
    } finally {
      setSaving(false);
    }
  };

  if (!open) return null;

  return (
    <Modal open={open} onClose={onClose} title={`Qabul tahrirlash #${visit?.id || ''}`} size="lg"
      footer={<>
        <Button variant="ghost" onClick={onClose}>Bekor</Button>
        <Button variant="primary" loading={saving} onClick={save}>Saqlash</Button>
      </>}>
      {loading ? (
        <div style={{ padding: 24, textAlign: 'center', color: 'var(--fg-3)' }}>Yuklanmoqda...</div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Field label="Shifokor">
            <Select value={doctorId} onChange={e => setDoctorId(e.target.value)}>
              <option value="">— shifokor yo'q —</option>
              {doctors.map(d => (
                <option key={d.id} value={d.id}>{d.full_name}{d.specialty ? ` (${d.specialty})` : ''}</option>
              ))}
            </Select>
          </Field>

          <Field label="Xizmatlar">
            <div style={{ display: 'flex', flexDirection: 'column', gap: 8, maxHeight: 220, overflowY: 'auto', border: '1px solid var(--border-2)', borderRadius: 8, padding: 8 }}>
              {allServices.filter(s => s.is_active).map(s => {
                const sel = selectedSvcs.find(x => x.service_id === s.id);
                return (
                  <label key={s.id} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: 6, borderRadius: 6, background: sel ? 'var(--brand-primary-soft)' : 'transparent', cursor: 'pointer' }}>
                    <input type="checkbox" checked={!!sel} onChange={() => toggleSvc(s)} />
                    <div style={{ flex: 1 }}>
                      <div style={{ fontSize: 13, color: 'var(--fg-1)' }}>{s.name}</div>
                      <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>{uzMoneyShort(s.price)} so'm</div>
                    </div>
                    {sel && (
                      <Input value={sel.quantity} onChange={e => setQty(s.id, e.target.value)}
                        style={{ width: 64, textAlign: 'center' }} onClick={e => e.preventDefault()} />
                    )}
                  </label>
                );
              })}
            </div>
            <div style={{ marginTop: 8, textAlign: 'right', fontSize: 13, fontWeight: 600 }}>
              Jami: <span style={{ color: 'var(--brand-primary)' }}>{uzMoneyShort(total)} so'm</span>
            </div>
          </Field>

          <Field label="To'lov rejimi">
            <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
              {PAY_METHODS.map(m => (
                <label key={m.id} style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 12px', borderRadius: 6, border: '1px solid var(--border-2)', background: paymentMethod === m.id ? 'var(--brand-primary-soft)' : 'transparent', cursor: 'pointer' }}>
                  <input type="radio" name="pm" checked={paymentMethod === m.id} onChange={() => setPaymentMethod(m.id)} />
                  <span style={{ fontSize: 13 }}>{m.label}</span>
                </label>
              ))}
            </div>
          </Field>

          <Field label="Eslatma">
            <textarea value={notes} onChange={e => setNotes(e.target.value)} rows={3}
              style={{ width: '100%', padding: 10, border: '1px solid var(--border-2)', borderRadius: 8, fontFamily: 'inherit', fontSize: 13 }}
              placeholder="Ixtiyoriy..." />
          </Field>
        </div>
      )}
    </Modal>
  );
}

function PatientsPage({ onNav, toast }) {
  const [q, setQ] = useState('');
  const [view, setView] = useState('table');
  const [pageNum, setPageNum] = useState(1);
  const pageSize = 12;

  const [patients, setPatients] = useState([]);
  const [loading, setLoading] = useState(true);
  const [reloadKey, setReloadKey] = useState(0);

  const me = (window.Auth && window.Auth.getUser && window.Auth.getUser()) || null;
  const canDelete = me && (me.role === 'admin' || me.role === 'super_admin');

  // Server-side search with debounce
  useEffect(() => {
    let mounted = true;
    setLoading(true);
    const t = setTimeout(() => {
      window.API.listPatients(q ? { q, limit: 200 } : { limit: 200 })
        .then(rows => { if (mounted) { setPatients(rows.map(window.normalizePatient)); setLoading(false); } })
        .catch(err => { if (mounted) { setLoading(false); console.error(err); } });
    }, q ? 250 : 0);
    return () => { mounted = false; clearTimeout(t); };
  }, [q, reloadKey]);

  const deletePatient = async (p, e) => {
    e?.stopPropagation();
    if (!confirm(`"${p.fullName || p.name}" bemorini butunlay o'chirmoqchimisiz?\n\nAgar bemorda qabullar bo'lsa, avval qabullarni o'chiring.`)) return;
    try {
      await window.API.deletePatient(p.id);
      toast?.({ kind: 'success', title: "Bemor o'chirildi", msg: p.fullName || p.name });
      setReloadKey(k => k + 1);
    } catch (err) {
      toast?.({ kind: 'danger', title: "O'chirib bo'lmadi", msg: err.message });
    }
  };

  const filtered = patients;
  const paginated = filtered.slice((pageNum - 1) * pageSize, pageNum * pageSize);

  return (
    <div className="page-in">
      <PageHeader title="Bemorlar" sub={`Jami ${patients.length} ta bemor`}
        actions={
          <Button variant="primary" icon="plus-circle" onClick={() => onNav('new-visit')}>Yangi rentgen</Button>
        }
      />

      <Card style={{ padding: 0 }}>
        <div className="table-toolbar">
          <div style={{ position: 'relative', width: 320 }}>
            <Icon name="magnifying-glass" style={{ position: 'absolute', left: 12, top: '50%', transform: 'translateY(-50%)', color: 'var(--fg-4)', fontSize: 18, pointerEvents: 'none' }} />
            <Input placeholder="F.I.O., telefon, pasport..." value={q} onChange={e => { setQ(e.target.value); setPageNum(1); }} icon style={{ paddingLeft: 36 }} />
          </div>
          <div className="table-toolbar__actions">
            <div style={{ display: 'flex', gap: 4, padding: 4, background: 'var(--surface-2)', borderRadius: 10 }}>
              <button className={`icon-btn ${view === 'table' ? 'is-active' : ''}`}
                style={{ background: view === 'table' ? 'var(--surface-1)' : 'transparent', boxShadow: view === 'table' ? 'var(--shadow-sm)' : 'none' }}
                onClick={() => setView('table')}><Icon name="list" /></button>
              <button className={`icon-btn ${view === 'cards' ? 'is-active' : ''}`}
                style={{ background: view === 'cards' ? 'var(--surface-1)' : 'transparent', boxShadow: view === 'cards' ? 'var(--shadow-sm)' : 'none' }}
                onClick={() => setView('cards')}><Icon name="squares-four" /></button>
            </div>
          </div>
        </div>

        {!loading && paginated.length === 0 ? (
          <EmptyState art="search" title="Hech narsa topilmadi" sub="Boshqa qidiruv so'zini sinab ko'ring" />
        ) : view === 'table' ? (
          <table className="table">
            <thead>
              <tr>
                <th>F.I.O.</th>
                <th>Telefon</th>
                <th>Tug'ilgan</th>
                <th>Yosh</th>
                <th className="text-right">Amallar</th>
              </tr>
            </thead>
            <tbody>
              {paginated.map(p => (
                <tr key={p.id} onClick={() => onNav('patient-detail', { patientId: p.id })}>
                  <td className="td-primary">
                    <div className="row row-3">
                      <Avatar name={p.name} size="sm" neutral />
                      <div>
                        <div>{highlight(p.fullName || p.name, q)}</div>
                        {p.passport && <div style={{ fontSize: 11, color: 'var(--fg-4)', fontFamily: 'var(--font-mono)' }}>{p.passport}</div>}
                      </div>
                    </div>
                  </td>
                  <td className="td-mono">{p.phone ? highlight(p.phone, q) : '—'}</td>
                  <td>{p.birth}</td>
                  <td>{p.birthDate ? <Badge tone="neutral" nodot>{age(p.birthDate)} yosh</Badge> : '—'}</td>
                  <td>
                    <div className="cell-actions">
                      <button className="icon-btn" title="Ko'rish" onClick={(e) => { e.stopPropagation(); onNav('patient-detail', { patientId: p.id }); }}><Icon name="eye" /></button>
                      <button className="icon-btn" title="Yangi rentgen" onClick={(e) => { e.stopPropagation(); onNav('new-visit'); }}><Icon name="plus" /></button>
                      {canDelete && (
                        <button className="icon-btn" title="O'chirish" onClick={(e) => deletePatient(p, e)} style={{ color: 'var(--color-danger)' }}><Icon name="trash" /></button>
                      )}
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        ) : (
          <div style={{ padding: 20, display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(260px, 1fr))', gap: 12 }}>
            {paginated.map(p => (
              <div key={p.id} className="card card--hover" style={{ padding: 16, cursor: 'pointer' }} onClick={() => onNav('patient-detail', { patientId: p.id })}>
                <div className="row row-3" style={{ marginBottom: 10 }}>
                  <Avatar name={p.name} size="lg" />
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--fg-1)', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</div>
                    {p.birthDate && <div style={{ fontSize: 12, color: 'var(--fg-3)' }}>{age(p.birthDate)} yosh</div>}
                  </div>
                </div>
                {p.phone && (
                  <div style={{ fontSize: 12, color: 'var(--fg-3)', display: 'flex', alignItems: 'center', gap: 6, marginBottom: 6 }}>
                    <Icon name="phone" style={{ fontSize: 13 }} /> {p.phone}
                  </div>
                )}
              </div>
            ))}
          </div>
        )}

        {paginated.length > 0 && <Pagination page={pageNum} total={filtered.length} pageSize={pageSize} onPage={setPageNum} />}
      </Card>
    </div>
  );
}

/* =========================================================
   PATIENT DETAIL
   ========================================================= */
function PatientDetailPage({ onNav, patientId, toast }) {
  const [patient, setPatient] = useState(null);
  const [visits, setVisits] = useState([]);
  const [tab, setTab] = useState('visits');
  const [loading, setLoading] = useState(true);
  const [editingVisit, setEditingVisit] = useState(null);

  const me = (window.Auth && window.Auth.getUser && window.Auth.getUser()) || null;
  const canEditVisits = me && (me.role === 'admin' || me.role === 'super_admin');

  const reload = () => {
    Promise.all([
      window.API.getPatient(patientId),
      window.API.listXrayRecords({ limit: 200 }),
    ]).then(([p, allVisits]) => {
      setPatient(window.normalizePatient(p));
      // Fetch each visit fully to get items (services) for the edit modal.
      // Listing endpoint returns VisitListItem (no items), so we just take what we have.
      // Items will be fetched on-demand when opening edit.
      setVisits(allVisits.filter(v => v.patient.id === p.id));
      setLoading(false);
    }).catch(() => setLoading(false));
  };

  useEffect(() => {
    setLoading(true);
    reload();
  }, [patientId]);

  const openEdit = async (v) => {
    try {
      const full = await window.API.getVisit(v.id);
      setEditingVisit(full);
    } catch (err) {
      toast?.({ kind: 'danger', title: 'Yuklash xato', msg: err.message });
    }
  };

  const deleteVisit = async (v) => {
    if (!confirm(`Qabul #${v.id} ni butunlay o'chirmoqchimisiz?\n\nXizmatlar, to'lovlar va rentgen yozuv ham o'chiriladi. Bu amalni qaytarib bo'lmaydi.\n\nTelegram'dagi ZIP fayl saqlanib qoladi.`)) return;
    try {
      await window.API.deleteVisit(v.id);
      toast?.({ kind: 'success', title: "Qabul o'chirildi" });
      reload();
    } catch (err) {
      toast?.({ kind: 'danger', title: "O'chirib bo'lmadi", msg: err.message });
    }
  };

  if (loading || !patient) return <div style={{ padding: 40, textAlign: 'center', color: 'var(--fg-3)' }}>Yuklanmoqda...</div>;

  const totalSpent = visits.reduce((s, v) => s + Number(v.paid_amount), 0);
  const totalDebt = visits.reduce((s, v) => s + (Number(v.total_amount) - Number(v.paid_amount)), 0);

  return (
    <div className="page-in">
      <PageHeader
        title={patient.name}
        sub={(patient.birthDate ? `${age(patient.birthDate)} yosh · ` : '') + `${visits.length} ta vizit`}
        breadcrumbs={[<a href="#" onClick={() => onNav('patients')} key="b">Bemorlar</a>, patient.name]}
        actions={
          <Button variant="primary" icon="plus-circle" onClick={() => onNav('new-visit')}>Yangi rentgen</Button>
        }
      />

      <div style={{ display: 'grid', gridTemplateColumns: '300px minmax(0, 1fr)', gap: 24 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
          <Card style={{ padding: 0, overflow: 'hidden' }}>
            <div style={{ background: 'var(--brand-gradient)', height: 80, position: 'relative' }}>
              <div style={{ position: 'absolute', bottom: -28, left: 20, padding: 4, background: 'var(--surface-1)', borderRadius: '50%' }}>
                <Avatar name={patient.name} size="xl" />
              </div>
            </div>
            <div style={{ padding: '40px 20px 20px' }}>
              <div style={{ fontSize: 16, fontWeight: 600, color: 'var(--fg-1)' }}>{patient.fullName || patient.name}</div>
              <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 2 }}>
                {patient.birthDate ? `${age(patient.birthDate)} yosh · ` : ''}Bemor
              </div>

              <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 16 }}>
                {patient.phone && <InfoRow icon="phone" label="Telefon" value={patient.phone} />}
                <InfoRow icon="calendar" label="Tug'ilgan" value={patient.birth} />
                {patient.passport && <InfoRow icon="identification-card" label="Pasport" value={patient.passport} mono />}
              </div>
            </div>
          </Card>

          <Card>
            <div className="t-eyebrow" style={{ marginBottom: 12 }}>Moliyaviy</div>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
              <div>
                <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>To'langan</div>
                <div style={{ fontSize: 18, fontWeight: 700, color: 'var(--color-success)', fontVariantNumeric: 'tabular-nums' }}>{uzMoneyShort(totalSpent)} so'm</div>
              </div>
              <div>
                <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>Qarz</div>
                <div style={{ fontSize: 18, fontWeight: 700, color: totalDebt > 0 ? 'var(--color-danger)' : 'var(--fg-3)', fontVariantNumeric: 'tabular-nums' }}>{uzMoneyShort(totalDebt)} so'm</div>
              </div>
            </div>
          </Card>
        </div>

        <div>
          <Tabs items={[
            { id: 'visits',   label: 'Vizitlar',  icon: 'list-checks', count: visits.length },
            { id: 'xray',     label: 'Rentgenlar', icon: 'image' },
            { id: 'info',     label: "Ma'lumot",  icon: 'info' },
          ]} value={tab} onChange={setTab} />

          {tab === 'visits' && (
            <Card style={{ padding: 0 }}>
              {visits.length === 0 ? (
                <EmptyState art="inbox" title="Vizitlar yo'q" sub="Yangi rentgen ro'yxati orqali qo'shing" />
              ) : (
                <table className="table">
                  <thead>
                    <tr>
                      <th>Sana</th>
                      <th>Shifokor</th>
                      <th className="text-right">Summa</th>
                      <th>To'lov</th>
                      <th>Holat</th>
                      {canEditVisits && <th className="text-right">Amallar</th>}
                    </tr>
                  </thead>
                  <tbody>
                    {visits.map(v => (
                      <tr key={v.id}>
                        <td className="td-mono">{uzDateTime(v.created_at)}</td>
                        <td>{v.doctor?.full_name || <span style={{ color: 'var(--fg-4)' }}>—</span>}</td>
                        <td className="text-right td-primary">{uzMoneyShort(v.total_amount)}</td>
                        <td><PayTypeBadge type={v.payment_method || 'debt'} /></td>
                        <td><StatusBadge status={v.payment_status} /></td>
                        {canEditVisits && (
                          <td>
                            <div className="cell-actions">
                              <button className="icon-btn" title="Tahrirlash" onClick={() => openEdit(v)}><Icon name="pencil" /></button>
                              <button className="icon-btn" title="O'chirish" onClick={() => deleteVisit(v)} style={{ color: 'var(--color-danger)' }}><Icon name="trash" /></button>
                            </div>
                          </td>
                        )}
                      </tr>
                    ))}
                  </tbody>
                </table>
              )}
            </Card>
          )}

          {tab === 'xray' && (
            <Card>
              {visits[0]?.xray_record ? (
                <>
                  <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: 16 }}>
                    <div>
                      <div className="t-h5">3D Rentgen</div>
                      <div style={{ fontSize: 12, color: 'var(--fg-3)', marginTop: 2 }}>
                        {uzDateTime(visits[0].created_at)} · Holat: <StatusBadge status={visits[0].xray_record.status} />
                      </div>
                    </div>
                    <div className="row row-2">
                      {visits[0].xray_record.external_link ? (
                        <a href={visits[0].xray_record.external_link} target="_blank" rel="noopener noreferrer">
                          <Button variant="primary" icon="cube" size="sm">3D ko'rish</Button>
                        </a>
                      ) : (
                        <Badge tone="neutral">Link biriktirilmagan</Badge>
                      )}
                    </div>
                  </div>
                  <XrayPreview3D />
                </>
              ) : (
                <EmptyState art="xray" title="Rentgen yo'q" sub="Hali rentgen yuklanmagan" />
              )}
            </Card>
          )}

          {tab === 'info' && (
            <Card>
              <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
                <Field label="F.I.O."><Input value={patient.fullName || patient.name} readOnly /></Field>
                <Field label="Tug'ilgan sana"><Input value={patient.birth || ''} readOnly /></Field>
                <Field label="Telefon"><Input value={patient.phone || ''} readOnly /></Field>
                <Field label="Pasport"><Input value={patient.passport || ''} readOnly placeholder="Kiritilmagan" /></Field>
              </div>
            </Card>
          )}
        </div>
      </div>

      <EditVisitModal
        open={!!editingVisit}
        visit={editingVisit}
        toast={toast}
        onClose={() => setEditingVisit(null)}
        onSaved={() => { setEditingVisit(null); reload(); }}
      />
    </div>
  );
}

function InfoRow({ icon, label, value, mono }) {
  return (
    <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start' }}>
      <Icon name={icon} style={{ color: 'var(--fg-4)', fontSize: 16, marginTop: 2 }} />
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 11, color: 'var(--fg-4)' }}>{label}</div>
        <div style={{ fontSize: 13, color: 'var(--fg-1)', fontFamily: mono ? 'var(--font-mono)' : 'inherit', wordBreak: 'break-word' }}>{value}</div>
      </div>
    </div>
  );
}

function InfoTile({ icon, label, value }) {
  return (
    <div style={{ padding: 14, background: 'var(--surface-2)', borderRadius: 10, display: 'flex', gap: 10, alignItems: 'center' }}>
      <div style={{ width: 36, height: 36, background: 'var(--brand-primary-soft)', color: 'var(--brand-primary)', borderRadius: 10, display: 'grid', placeItems: 'center' }}>
        <Icon name={icon} />
      </div>
      <div>
        <div style={{ fontSize: 11, color: 'var(--fg-3)' }}>{label}</div>
        <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--fg-1)' }}>{value}</div>
      </div>
    </div>
  );
}

/* =========================================================
   3D X-RAY PREVIEW (mock — CSS+SVG art that conveys CBCT viewer)
   ========================================================= */
function XrayPreview3D() {
  const [rotate, setRotate] = useState(15);
  const [zoom, setZoom] = useState(1);
  return (
    <div className="xray-preview">
      <div className="xray-preview__overlay"></div>
      <span className="xray-preview__corner tl"></span>
      <span className="xray-preview__corner tr"></span>
      <span className="xray-preview__corner bl"></span>
      <span className="xray-preview__corner br"></span>

      <div className="xray-preview__hud">
        <span>X: {Math.round(rotate)}°</span>
        <span>Z: {zoom.toFixed(2)}x</span>
        <span style={{ color: '#34D399' }}>● LIVE</span>
      </div>

      <div style={{ width: '70%', maxWidth: 400, transform: `rotateY(${rotate}deg) scale(${zoom})`, transition: 'transform 400ms ease' }}>
        <ToothScanSVG />
      </div>

      <span className="xray-preview__label">VIEW: PANORAMIC — SLICE 28/64</span>

      <div style={{ position: 'absolute', right: 16, top: '50%', transform: 'translateY(-50%)', display: 'flex', flexDirection: 'column', gap: 8 }}>
        <button className="icon-btn" style={{ background: 'rgba(56,189,248,0.1)', color: '#7DD3FC', border: '1px solid rgba(56,189,248,0.3)' }} onClick={() => setZoom(z => Math.min(2, z + 0.2))}><Icon name="plus" /></button>
        <button className="icon-btn" style={{ background: 'rgba(56,189,248,0.1)', color: '#7DD3FC', border: '1px solid rgba(56,189,248,0.3)' }} onClick={() => setZoom(z => Math.max(0.5, z - 0.2))}><Icon name="minus" /></button>
        <button className="icon-btn" style={{ background: 'rgba(56,189,248,0.1)', color: '#7DD3FC', border: '1px solid rgba(56,189,248,0.3)' }} onClick={() => setRotate(r => r + 30)}><Icon name="arrow-clockwise" /></button>
      </div>

      <div style={{ position: 'absolute', left: 56, right: 56, bottom: 36, display: 'flex', alignItems: 'center', gap: 12 }}>
        <input type="range" min="0" max="63" defaultValue="28"
          style={{ flex: 1, accentColor: '#38BDF8', background: 'transparent' }}
          onChange={e => setRotate(parseInt(e.target.value))} />
      </div>
    </div>
  );
}

function ToothScanSVG() {
  return (
    <svg viewBox="0 0 360 220" fill="none" xmlns="http://www.w3.org/2000/svg" style={{ width: '100%', height: 'auto' }}>
      <defs>
        <radialGradient id="tg" cx="0.5" cy="0.5" r="0.5">
          <stop offset="0" stopColor="#7DD3FC" stopOpacity="0.7"/>
          <stop offset="0.5" stopColor="#38BDF8" stopOpacity="0.4"/>
          <stop offset="1" stopColor="#0EA5E9" stopOpacity="0.05"/>
        </radialGradient>
        <linearGradient id="tg2" x1="0" x2="0" y1="0" y2="1">
          <stop offset="0" stopColor="#E0F2FE" stopOpacity="0.95"/>
          <stop offset="1" stopColor="#0EA5E9" stopOpacity="0.4"/>
        </linearGradient>
      </defs>
      <path d="M30 60 C 50 160, 100 200, 180 200 C 260 200, 310 160, 330 60" stroke="rgba(125,211,252,0.4)" strokeWidth="1" fill="none" strokeDasharray="2 3"/>
      <path d="M40 80 C 60 160, 110 195, 180 195 C 250 195, 300 160, 320 80" stroke="rgba(125,211,252,0.3)" strokeWidth="1" fill="none" strokeDasharray="2 3"/>
      {Array.from({length: 14}).map((_, i) => {
        const t = (i + 0.5) / 14;
        const a = Math.PI * (t);
        const cx = 50 + (310 - 50) * t;
        const cy = 100 - Math.sin(a) * 25;
        const angle = (t - 0.5) * 80;
        const w = 14 + Math.sin(a) * 6;
        const h = 22 + Math.sin(a) * 6;
        const highlight = i === 6 || i === 7;
        return (
          <g key={`u${i}`} transform={`translate(${cx} ${cy}) rotate(${angle})`}>
            <path
              d={`M ${-w/2} 0 q 0 -${h*0.4} ${w/2} -${h*0.6} q ${w/2} ${h*0.2} ${w/2} ${h*0.6} q 0 ${h*0.4} -${w/2} ${h*0.5} q -${w/2} -${h*0.1} -${w/2} -${h*0.5} z`}
              fill="url(#tg2)" stroke={highlight ? '#FBBF24' : 'rgba(125,211,252,0.5)'} strokeWidth={highlight ? '1.5' : '0.6'}
              filter={highlight ? 'drop-shadow(0 0 6px #FBBF24)' : 'none'}
            />
          </g>
        );
      })}
      {Array.from({length: 14}).map((_, i) => {
        const t = (i + 0.5) / 14;
        const a = Math.PI * (t);
        const cx = 55 + (305 - 55) * t;
        const cy = 145 + Math.sin(a) * 30;
        const angle = -(t - 0.5) * 80;
        const w = 13 + Math.sin(a) * 5;
        const h = 20 + Math.sin(a) * 5;
        return (
          <g key={`l${i}`} transform={`translate(${cx} ${cy}) rotate(${angle})`}>
            <path
              d={`M ${-w/2} 0 q 0 ${h*0.4} ${w/2} ${h*0.6} q ${w/2} -${h*0.2} ${w/2} -${h*0.6} q 0 -${h*0.4} -${w/2} -${h*0.5} q -${w/2} ${h*0.1} -${w/2} ${h*0.5} z`}
              fill="url(#tg2)" stroke="rgba(125,211,252,0.5)" strokeWidth="0.6"
            />
          </g>
        );
      })}
      <g stroke="#FBBF24" strokeWidth="0.8" opacity="0.7">
        <line x1="180" y1="50" x2="180" y2="80"/>
        <line x1="180" y1="120" x2="180" y2="150"/>
        <line x1="155" y1="100" x2="170" y2="100"/>
        <line x1="190" y1="100" x2="205" y2="100"/>
      </g>
      <circle cx="180" cy="100" r="20" stroke="#FBBF24" strokeWidth="0.8" fill="none" strokeDasharray="3 2" opacity="0.8"/>
    </svg>
  );
}

Object.assign(window, { PatientsPage, PatientDetailPage, EditVisitModal, XrayPreview3D, ToothScanSVG, InfoRow, InfoTile });
