/* ClinicFlow AI — Admin Dashboard (Orbis internal only)
   Access: index.html#__admin
   Credentials: set ADMIN_USERNAME + ADMIN_PASSCODE in Vercel environment variables.
*/

const { useState: _aas, useEffect: _aae, useRef: _aar, useCallback: _aac } = React;

// ─── Plans config (no DB table, local only) ───────────────────────────────────

const ADMIN_PLANS = [
  {
    id: 'free', name: 'Free', price: 0, billing: 'forever',
    tagline: 'Try ClinicFlow at no cost', color: '#6B7280',
    bg: 'linear-gradient(135deg, #6B7280, #9CA3AF)',
    features: ['1 clinic', '1 user seat', 'Up to 100 patients', '500 WhatsApp messages/month', 'Basic dashboard'],
    limits: { clinics: 1, users: 1, patients: 100, messages: 500 },
  },
  {
    id: 'starter', name: 'Starter', price: 2999, billing: '/month',
    tagline: 'For solo practitioners', color: '#0EA5E9',
    bg: 'linear-gradient(135deg, #0EA5E9, #6366F1)',
    features: ['3 clinics', '5 user seats', '1,000 patients', '5,000 WhatsApp messages/month', 'AI follow-up agent', 'Analytics dashboard', 'Email support'],
    limits: { clinics: 3, users: 5, patients: 1000, messages: 5000 },
  },
  {
    id: 'pro', name: 'Pro', price: 5999, billing: '/month',
    tagline: 'For growing clinics', color: '#7C3AED', popular: true,
    bg: 'linear-gradient(135deg, #4F46E5, #7C3AED)',
    features: ['10 clinics', '20 user seats', 'Unlimited patients', '25,000 WhatsApp messages/month', 'AI follow-up + risk scoring', 'Weekly summaries (WhatsApp)', 'Recovery workflows', 'Priority support'],
    limits: { clinics: 10, users: 20, patients: -1, messages: 25000 },
  },
  {
    id: 'enterprise', name: 'Enterprise', price: null, billing: 'custom',
    tagline: 'For hospital chains & networks', color: '#F59E0B',
    bg: 'linear-gradient(135deg, #F59E0B, #EC4899)',
    features: ['Unlimited clinics', 'Unlimited user seats', 'Unlimited patients', 'Unlimited messages', 'Custom AI workflows', 'White-label option', 'Dedicated success manager', '99.9% SLA guarantee'],
    limits: { clinics: -1, users: -1, patients: -1, messages: -1 },
  },
];

const INITIAL_PAYMENTS = [
  { id: 'PAY-001', clinicId: '', clinicName: 'Apollo Family Clinic',    plan: 'pro',     amount: 5999, dueDate: '2026-06-01', status: 'pending', paidDate: null,         notes: '' },
  { id: 'PAY-002', clinicId: '', clinicName: 'Apollo Family Clinic',    plan: 'pro',     amount: 5999, dueDate: '2026-05-01', status: 'paid',    paidDate: '2026-04-30', notes: 'Paid via UPI' },
  { id: 'PAY-003', clinicId: '', clinicName: 'WellCare Multispecialty', plan: 'starter', amount: 2999, dueDate: '2026-06-05', status: 'pending', paidDate: null,         notes: '' },
  { id: 'PAY-004', clinicId: '', clinicName: 'WellCare Multispecialty', plan: 'starter', amount: 2999, dueDate: '2026-05-05', status: 'paid',    paidDate: '2026-05-04', notes: 'Paid via bank transfer' },
  { id: 'PAY-005', clinicId: '', clinicName: 'NewSight Eye Centre',     plan: 'starter', amount: 2999, dueDate: '2026-05-20', status: 'overdue', paidDate: null,         notes: 'Reminder sent May 21' },
  { id: 'PAY-006', clinicId: '', clinicName: 'Metro Pediatric Hub',     plan: 'free',    amount: 0,    dueDate: null,         status: 'free',    paidDate: null,         notes: '' },
];

const BG_OPTIONS = [
  'linear-gradient(135deg, #4F46E5, #7C3AED)',
  'linear-gradient(135deg, #0EA5E9, #6366F1)',
  'linear-gradient(135deg, #10B981, #14B8A6)',
  'linear-gradient(135deg, #F59E0B, #EC4899)',
  'linear-gradient(135deg, #EC4899, #8B5CF6)',
  'linear-gradient(135deg, #06B6D4, #3B82F6)',
  'linear-gradient(135deg, #EF4444, #F97316)',
  'linear-gradient(135deg, #84CC16, #0EA5E9)',
];

// ─── Data mappers ──────────────────────────────────────────────────────────────

function mapDbClinic(c) {
  const words = (c.name || '').split(/\s+/).filter(Boolean);
  const code = words.slice(0, 2).map(w => w[0].toUpperCase()).join('').slice(0, 2) || 'CL';
  let hash = 0;
  for (let i = 0; i < c.id.length; i++) hash = (hash * 31 + c.id.charCodeAt(i)) | 0;
  return {
    id: c.id,
    code,
    name: c.name,
    specialty: c.specialty || '—',
    address: c.address || '',
    phone: c.phone || '',
    whatsappNumber: c.whatsapp_number || '',
    ownerWhatsapp: c.owner_whatsapp || '',
    plan: c.plan || 'free',
    patientCount: c.patient_count || 0,
    staffCount: c.staff_count || 0,
    created: c.created_at ? c.created_at.slice(0, 10) : '—',
    bg: BG_OPTIONS[Math.abs(hash) % BG_OPTIONS.length],
  };
}

function mapDbUser(u) {
  return {
    id: u.id,
    name: u.name,
    email: u.email,
    role: u.role || 'admin',
    clinic_id: u.clinic_id || null,
    clinicName: u.clinics?.name || '—',
    created: u.created_at ? u.created_at.slice(0, 10) : '—',
  };
}

// ─── Admin API helper ──────────────────────────────────────────────────────────

async function adminFetch(token, path, opts = {}) {
  const res = await fetch(path, {
    method: opts.method || 'GET',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${token}`,
    },
    body: opts.body ? JSON.stringify(opts.body) : undefined,
  });
  const data = await res.json();
  if (!res.ok) throw new Error(data.error || `Request failed (${res.status})`);
  return data;
}

// ─── Primitive Components ──────────────────────────────────────────────────────

function AdminModal({ open, onClose, title, children, footer, wide }) {
  if (!open) return null;
  return (
    <div style={{
      position: 'fixed', inset: 0, zIndex: 9999,
      background: 'rgba(12,7,20,0.65)', backdropFilter: 'blur(4px)',
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 24,
    }} onClick={onClose}>
      <div style={{
        background: '#fff', borderRadius: 16, width: '100%',
        maxWidth: wide ? 800 : 520, maxHeight: '90vh', overflowY: 'auto',
        boxShadow: '0 24px 64px rgba(0,0,0,0.24)',
      }} onClick={e => e.stopPropagation()}>
        <div style={{
          padding: '18px 24px', borderBottom: '1px solid #F3F4F6',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          position: 'sticky', top: 0, background: '#fff', zIndex: 1,
        }}>
          <div style={{ fontWeight: 700, fontSize: 15, color: '#0C0714' }}>{title}</div>
          <button onClick={onClose} style={{
            background: '#F9FAFB', border: '1px solid #E5E7EB', borderRadius: 8,
            width: 30, height: 30, display: 'flex', alignItems: 'center',
            justifyContent: 'center', cursor: 'pointer', color: '#6B7280',
          }}>
            <I.x size={14} />
          </button>
        </div>
        <div style={{ padding: '20px 24px' }}>{children}</div>
        {footer && (
          <div style={{
            padding: '14px 24px', borderTop: '1px solid #F3F4F6',
            display: 'flex', gap: 10, justifyContent: 'flex-end',
            position: 'sticky', bottom: 0, background: '#fff',
          }}>{footer}</div>
        )}
      </div>
    </div>
  );
}

function AField({ label, children, hint }) {
  return (
    <div style={{ marginBottom: 14 }}>
      {label && <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: '#374151', marginBottom: 5 }}>{label}</label>}
      {children}
      {hint && <div style={{ fontSize: 11, color: '#9CA3AF', marginTop: 3 }}>{hint}</div>}
    </div>
  );
}

const inputStyle = {
  width: '100%', padding: '9px 12px',
  border: '1.5px solid #E5E7EB', borderRadius: 8,
  fontSize: 13, color: '#0C0714', background: '#FAFAFA',
  outline: 'none', fontFamily: 'inherit', boxSizing: 'border-box',
};

function AInput({ style, ...props }) {
  return <input style={{ ...inputStyle, ...style }} {...props} />;
}

function ASelect({ children, style, ...props }) {
  return (
    <select style={{ ...inputStyle, cursor: 'pointer', ...style }} {...props}>
      {children}
    </select>
  );
}

function ATextarea({ style, ...props }) {
  return <textarea style={{ ...inputStyle, resize: 'vertical', minHeight: 72, ...style }} {...props} />;
}

function ABadge({ status }) {
  const MAP = {
    active:       { bg: '#DCFCE7', color: '#16A34A' },
    suspended:    { bg: '#FEE2E2', color: '#DC2626' },
    pending:      { bg: '#FEF9C3', color: '#CA8A04' },
    paid:         { bg: '#DCFCE7', color: '#16A34A' },
    overdue:      { bg: '#FEE2E2', color: '#DC2626' },
    free:         { bg: '#F3F4F6', color: '#6B7280' },
    admin:        { bg: '#EDE9FE', color: '#7C3AED' },
    doctor:       { bg: '#DBEAFE', color: '#2563EB' },
    receptionist: { bg: '#F0FDF4', color: '#15803D' },
  };
  const s = MAP[status] || { bg: '#F3F4F6', color: '#6B7280' };
  return (
    <span style={{
      background: s.bg, color: s.color, padding: '2px 9px',
      borderRadius: 100, fontSize: 11, fontWeight: 600,
      textTransform: 'capitalize', whiteSpace: 'nowrap', display: 'inline-block',
    }}>{status}</span>
  );
}

function ABtn({ children, onClick, variant = 'primary', small, danger, disabled, style, ...rest }) {
  const V = {
    primary: { bg: 'linear-gradient(135deg, #7C3AED, #6D28D9)', color: '#fff', border: '1px solid #7C3AED' },
    ghost:   { bg: '#F9FAFB', color: '#374151', border: '1px solid #E5E7EB' },
  };
  const s = danger ? { bg: '#FEF2F2', color: '#DC2626', border: '1px solid #FECACA' } : V[variant];
  return (
    <button onClick={onClick} disabled={disabled} style={{
      background: s.bg, color: s.color, border: s.border,
      borderRadius: 8, padding: small ? '5px 11px' : '8px 16px',
      fontSize: small ? 12 : 13, fontWeight: 600,
      cursor: disabled ? 'not-allowed' : 'pointer', opacity: disabled ? 0.5 : 1,
      display: 'inline-flex', alignItems: 'center', gap: 6,
      fontFamily: 'inherit', whiteSpace: 'nowrap', ...style,
    }} {...rest}>{children}</button>
  );
}

function ATable({ cols, rows, emptyText = 'No records found.' }) {
  return (
    <div style={{ overflowX: 'auto', borderRadius: 12, border: '1px solid #E5E7EB' }}>
      <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 13 }}>
        <thead>
          <tr style={{ background: '#F9FAFB', borderBottom: '1px solid #E5E7EB' }}>
            {cols.map((col, i) => (
              <th key={i} style={{
                padding: '10px 16px', textAlign: 'left', fontWeight: 600,
                color: '#6B7280', fontSize: 11, textTransform: 'uppercase',
                letterSpacing: '0.05em', whiteSpace: 'nowrap',
              }}>{col}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.length === 0
            ? <tr><td colSpan={cols.length} style={{ padding: 32, textAlign: 'center', color: '#9CA3AF' }}>{emptyText}</td></tr>
            : rows.map((row, i) => (
              <tr key={i}
                style={{ borderBottom: i < rows.length - 1 ? '1px solid #F3F4F6' : 'none', background: '#fff' }}
                onMouseEnter={e => e.currentTarget.style.background = '#FAFAFA'}
                onMouseLeave={e => e.currentTarget.style.background = '#fff'}
              >
                {row.map((cell, j) => (
                  <td key={j} style={{ padding: '11px 16px', color: '#0C0714', verticalAlign: 'middle' }}>{cell}</td>
                ))}
              </tr>
            ))
          }
        </tbody>
      </table>
    </div>
  );
}

function SearchInput({ value, onChange, placeholder }) {
  return (
    <div style={{ position: 'relative', flex: 1 }}>
      <I.search size={14} style={{ position: 'absolute', left: 10, top: '50%', transform: 'translateY(-50%)', color: '#9CA3AF', pointerEvents: 'none' }} />
      <AInput value={value} onChange={onChange} placeholder={placeholder} style={{ paddingLeft: 32 }} />
    </div>
  );
}

// ─── Admin Login ───────────────────────────────────────────────────────────────

function AdminLogin({ onAuth }) {
  const [username, setUsername] = _aas('');
  const [passcode, setPasscode] = _aas('');
  const [error, setError] = _aas(null);
  const [loading, setLoading] = _aas(false);
  const [showPass, setShowPass] = _aas(false);
  const uRef = _aar(null);

  _aae(() => { uRef.current?.focus(); }, []);

  const submit = async (e) => {
    e?.preventDefault();
    setError(null);
    if (!username || !passcode) { setError('Enter both fields.'); return; }
    setLoading(true);
    try {
      const res = await fetch('/api/admin?resource=auth', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ username, passcode }),
      });
      const data = await res.json();
      if (data.ok) {
        onAuth(data.token);
      } else {
        setError(data.error || 'Invalid credentials.');
      }
    } catch {
      setError('Connection error. Try again.');
    }
    setLoading(false);
  };

  return (
    <div style={{
      minHeight: '100vh', background: '#0C0714',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'inherit',
    }}>
      <div style={{ width: '100%', maxWidth: 400, padding: 24 }}>
        <div style={{ textAlign: 'center', marginBottom: 32 }}>
          <div style={{ display: 'inline-flex', alignItems: 'center', gap: 10, marginBottom: 8 }}>
            <OrbisMark size={28} />
            <span style={{ color: '#fff', fontWeight: 700, fontSize: 18, letterSpacing: '-0.02em' }}>
              Orbis Admin
            </span>
          </div>
          <div style={{ color: '#4B5563', fontSize: 12 }}>
            Internal access only · ClinicFlow
          </div>
        </div>

        <div style={{
          background: '#150F22', borderRadius: 16,
          border: '1px solid rgba(124,58,237,0.25)', padding: 28,
        }}>
          <form onSubmit={submit}>
            <div style={{ marginBottom: 14 }}>
              <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: '#6B7280', marginBottom: 6 }}>Username</label>
              <input
                ref={uRef}
                type="text"
                value={username}
                onChange={e => { setUsername(e.target.value); setError(null); }}
                placeholder="Username"
                autoComplete="off"
                style={{
                  width: '100%', padding: '10px 14px',
                  background: '#0C0714', border: '1.5px solid rgba(255,255,255,0.1)',
                  borderRadius: 8, color: '#fff', fontSize: 13,
                  fontFamily: 'monospace', outline: 'none', boxSizing: 'border-box',
                }}
              />
            </div>
            <div style={{ marginBottom: 20 }}>
              <label style={{ display: 'block', fontSize: 12, fontWeight: 600, color: '#6B7280', marginBottom: 6 }}>
                Passcode
              </label>
              <div style={{ position: 'relative' }}>
                <input
                  type={showPass ? 'text' : 'password'}
                  value={passcode}
                  onChange={e => { setPasscode(e.target.value); setError(null); }}
                  placeholder="••••••••••"
                  autoComplete="current-password"
                  style={{
                    width: '100%', padding: '10px 14px', paddingRight: 60,
                    background: '#0C0714', border: '1.5px solid rgba(255,255,255,0.1)',
                    borderRadius: 8, color: '#fff', fontSize: 13,
                    fontFamily: 'monospace', outline: 'none', boxSizing: 'border-box',
                  }}
                />
                <button type="button" onClick={() => setShowPass(s => !s)} style={{
                  position: 'absolute', right: 10, top: '50%', transform: 'translateY(-50%)',
                  background: 'transparent', border: 'none', color: '#4B5563',
                  fontSize: 11, fontWeight: 600, cursor: 'pointer', padding: '4px 6px',
                  fontFamily: 'inherit',
                }}>{showPass ? 'Hide' : 'Show'}</button>
              </div>
            </div>

            {error && (
              <div style={{
                background: 'rgba(220,38,38,0.1)', color: '#FCA5A5',
                border: '1px solid rgba(220,38,38,0.2)',
                borderRadius: 8, padding: '8px 12px', fontSize: 12,
                marginBottom: 16, display: 'flex', alignItems: 'center', gap: 8,
              }}>
                <I.x size={13} /> {error}
              </div>
            )}

            <button type="submit" disabled={loading} style={{
              width: '100%', padding: '11px',
              background: loading ? '#4C1D95' : 'linear-gradient(135deg, #7C3AED, #6D28D9)',
              border: 'none', borderRadius: 8, color: '#fff',
              fontWeight: 700, fontSize: 14, cursor: loading ? 'not-allowed' : 'pointer',
              fontFamily: 'inherit',
              display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
            }}>
              {loading
                ? <><I.refresh size={14} style={{ animation: 'spin 0.9s linear infinite' }} /> Verifying...</>
                : 'Access Admin Panel'
              }
            </button>
          </form>
        </div>

        <div style={{ textAlign: 'center', marginTop: 20, fontSize: 11, color: '#1F2937' }}>
          Orbis Systems · Not for sharing · Internal tool
        </div>
      </div>
    </div>
  );
}

// ─── Admin Sidebar ─────────────────────────────────────────────────────────────

const ADMIN_NAV = [
  { id: 'overview',  label: 'Overview',  icon: I.layout },
  { id: 'clinics',   label: 'Clinics',   icon: I.building },
  { id: 'users',     label: 'Users',     icon: I.users },
  { id: 'plans',     label: 'Plans',     icon: I.sparkles },
  { id: 'payments',  label: 'Payments',  icon: I.trendUp },
];

function AdminSidebar({ route, navigate, onSignOut }) {
  return (
    <div style={{
      width: 220, flexShrink: 0, background: '#0C0714',
      height: '100vh', position: 'sticky', top: 0,
      display: 'flex', flexDirection: 'column',
      borderRight: '1px solid rgba(255,255,255,0.06)',
    }}>
      <div style={{
        padding: '18px 16px 14px',
        borderBottom: '1px solid rgba(255,255,255,0.06)',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 9 }}>
          <OrbisMark size={22} />
          <div>
            <div style={{ color: '#fff', fontWeight: 700, fontSize: 13, letterSpacing: '-0.01em' }}>Orbis Admin</div>
            <div style={{ color: '#4B5563', fontSize: 10, marginTop: 1 }}>ClinicFlow · Internal</div>
          </div>
        </div>
      </div>

      <div style={{ flex: 1, padding: '12px 8px', overflowY: 'auto' }}>
        {ADMIN_NAV.map(item => {
          const active = route === item.id;
          return (
            <button key={item.id} onClick={() => navigate(item.id)} style={{
              width: '100%', padding: '9px 10px', marginBottom: 2,
              background: active ? 'rgba(124,58,237,0.18)' : 'transparent',
              border: active ? '1px solid rgba(124,58,237,0.35)' : '1px solid transparent',
              borderRadius: 8, cursor: 'pointer', textAlign: 'left',
              display: 'flex', alignItems: 'center', gap: 9,
              color: active ? '#A78BFA' : '#6B7280',
              fontWeight: active ? 600 : 500, fontSize: 13,
              fontFamily: 'inherit', transition: 'all 0.12s',
            }}>
              <item.icon size={15} />
              {item.label}
            </button>
          );
        })}
      </div>

      <div style={{ padding: '10px 8px 16px', borderTop: '1px solid rgba(255,255,255,0.06)' }}>
        <button onClick={onSignOut} style={{
          width: '100%', padding: '9px 10px',
          background: 'transparent', border: '1px solid rgba(255,255,255,0.08)',
          borderRadius: 8, cursor: 'pointer',
          display: 'flex', alignItems: 'center', gap: 9,
          color: '#4B5563', fontWeight: 500, fontSize: 12,
          textAlign: 'left', fontFamily: 'inherit',
        }}>
          <I.arrowRight size={14} /> Sign out
        </button>
        <div style={{ fontSize: 10, color: '#1F2937', marginTop: 10, paddingLeft: 4, lineHeight: 1.6 }}>
          Orbis Systems © 2026<br />Internal use only
        </div>
      </div>
    </div>
  );
}

function AdminTopbar({ route }) {
  const TITLES = { overview: 'Overview', clinics: 'Clinics', users: 'Users', plans: 'Plans', payments: 'Payments' };
  return (
    <div style={{
      height: 54, borderBottom: '1px solid #F3F4F6',
      display: 'flex', alignItems: 'center', padding: '0 24px',
      background: '#fff', position: 'sticky', top: 0, zIndex: 100,
    }}>
      <div style={{ fontWeight: 700, fontSize: 15, color: '#0C0714' }}>{TITLES[route]}</div>
      <div style={{ marginLeft: 'auto' }}>
        <span style={{
          background: '#FEF9C3', border: '1px solid #FDE68A',
          borderRadius: 6, padding: '3px 10px',
          fontSize: 10, fontWeight: 700, color: '#92400E', letterSpacing: '0.04em',
        }}>
          INTERNAL ADMIN
        </span>
      </div>
    </div>
  );
}

// ─── Overview Page ─────────────────────────────────────────────────────────────

function AdminOverviewPage({ users, clinics, navigate }) {
  const kpis = [
    { label: 'Total Clinics', value: clinics.length, sub: `${clinics.length} registered`, color: '#7C3AED', icon: I.building },
    { label: 'Total Users',   value: users.length,   sub: `${users.length} accounts`,     color: '#0EA5E9', icon: I.users },
    { label: 'Total Patients',value: clinics.reduce((s, c) => s + (c.patientCount || 0), 0), sub: 'across all clinics', color: '#10B981', icon: I.users },
  ];

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: 16, marginBottom: 24 }}>
        {kpis.map((k, i) => (
          <div key={i} style={{ background: '#fff', borderRadius: 12, padding: 20, border: '1px solid #E5E7EB', boxShadow: '0 1px 3px rgba(0,0,0,0.04)' }}>
            <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
              <div style={{ fontSize: 11, fontWeight: 600, color: '#6B7280', textTransform: 'uppercase', letterSpacing: '0.04em' }}>{k.label}</div>
              <div style={{ width: 32, height: 32, borderRadius: 8, background: k.color + '18', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
                <k.icon size={15} stroke={k.color} />
              </div>
            </div>
            <div style={{ fontSize: 26, fontWeight: 700, color: '#0C0714', letterSpacing: '-0.02em' }}>{k.value}</div>
            <div style={{ fontSize: 12, color: '#9CA3AF', marginTop: 4 }}>{k.sub}</div>
          </div>
        ))}
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 20 }}>
        <div style={{ background: '#fff', borderRadius: 12, border: '1px solid #E5E7EB', overflow: 'hidden' }}>
          <div style={{ padding: '14px 20px', borderBottom: '1px solid #F3F4F6', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div style={{ fontWeight: 700, fontSize: 14, color: '#0C0714' }}>Clinics</div>
            <button onClick={() => navigate('clinics')} style={{ fontSize: 12, color: '#7C3AED', fontWeight: 600, background: 'none', border: 'none', cursor: 'pointer' }}>View all →</button>
          </div>
          {clinics.length === 0
            ? <div style={{ padding: 24, textAlign: 'center', color: '#9CA3AF', fontSize: 13 }}>No clinics yet. Create one →</div>
            : clinics.slice(0, 5).map(c => {
              const plan = ADMIN_PLANS.find(p => p.id === c.plan);
              return (
                <div key={c.id} style={{ padding: '11px 20px', borderBottom: '1px solid #F9FAFB', display: 'flex', alignItems: 'center', gap: 12 }}>
                  <span style={{ width: 30, height: 30, borderRadius: 7, background: c.bg, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 10, flexShrink: 0 }}>{c.code}</span>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontWeight: 600, fontSize: 13, color: '#0C0714', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{c.name}</div>
                    <div style={{ fontSize: 11, color: '#9CA3AF' }}>{c.specialty} · {c.patientCount.toLocaleString()} patients</div>
                  </div>
                  <span style={{ fontSize: 10, color: plan?.color || '#6B7280', fontWeight: 600 }}>{plan?.name}</span>
                </div>
              );
            })
          }
        </div>

        <div style={{ background: '#fff', borderRadius: 12, border: '1px solid #E5E7EB', overflow: 'hidden' }}>
          <div style={{ padding: '14px 20px', borderBottom: '1px solid #F3F4F6', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
            <div style={{ fontWeight: 700, fontSize: 14, color: '#0C0714' }}>Recent Users</div>
            <button onClick={() => navigate('users')} style={{ fontSize: 12, color: '#7C3AED', fontWeight: 600, background: 'none', border: 'none', cursor: 'pointer' }}>View all →</button>
          </div>
          {users.length === 0
            ? <div style={{ padding: 24, textAlign: 'center', color: '#9CA3AF', fontSize: 13 }}>No users yet. Create one →</div>
            : users.slice(0, 5).map(u => (
              <div key={u.id} style={{ padding: '10px 20px', borderBottom: '1px solid #F9FAFB', display: 'flex', alignItems: 'center', gap: 10 }}>
                <div style={{ width: 28, height: 28, borderRadius: 6, background: 'linear-gradient(135deg, #4F46E5, #7C3AED)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 10, flexShrink: 0 }}>
                  {u.name.split(' ').slice(0, 2).map(p => p[0]).join('').toUpperCase()}
                </div>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ fontWeight: 600, fontSize: 13, color: '#0C0714', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{u.name}</div>
                  <div style={{ fontSize: 11, color: '#9CA3AF' }}>{u.clinicName}</div>
                </div>
                <ABadge status={u.role} />
              </div>
            ))
          }
        </div>
      </div>
    </div>
  );
}

// ─── Users Page ────────────────────────────────────────────────────────────────

function UserFormModal({ open, data, clinics, onClose, onSave, saving }) {
  const [form, setForm] = _aas({});
  const [showPw, setShowPw] = _aas(false);
  _aae(() => { if (data) setForm({ ...data, password: '' }); }, [data]);

  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <AdminModal
      open={open} onClose={onClose}
      title={form.id ? `Edit User: ${form.name}` : 'Create New User'}
      footer={<>
        <ABtn variant="ghost" onClick={onClose} disabled={saving}>Cancel</ABtn>
        <ABtn onClick={() => onSave(form)} disabled={saving}>
          {saving ? <><I.refresh size={13} style={{ animation: 'spin 0.9s linear infinite' }} /> Saving…</> : (form.id ? 'Save changes' : 'Create user')}
        </ABtn>
      </>}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <AField label="Full Name">
          <AInput value={form.name || ''} onChange={e => set('name', e.target.value)} placeholder="Dr. First Last" />
        </AField>
        <AField label="Role">
          <ASelect value={form.role || 'admin'} onChange={e => set('role', e.target.value)}>
            <option value="admin">Admin / Owner</option>
            <option value="doctor">Doctor</option>
            <option value="receptionist">Receptionist</option>
          </ASelect>
        </AField>
      </div>
      <AField label="Email Address">
        <AInput type="email" value={form.email || ''} onChange={e => set('email', e.target.value)} placeholder="doctor@clinic.in" disabled={!!form.id} style={form.id ? { opacity: 0.5 } : {}} />
      </AField>
      <AField label={form.id ? 'New Password' : 'Password'} hint={form.id ? 'Leave blank to keep existing password.' : 'Min 8 characters. User will use this to log in.'}>
        <div style={{ position: 'relative' }}>
          <AInput
            type={showPw ? 'text' : 'password'}
            value={form.password || ''}
            onChange={e => set('password', e.target.value)}
            placeholder={form.id ? 'Leave blank to keep unchanged' : 'Set a strong password (min 8 chars)'}
            style={{ paddingRight: 60 }}
          />
          <button type="button" onClick={() => setShowPw(s => !s)} style={{
            position: 'absolute', right: 10, top: '50%', transform: 'translateY(-50%)',
            background: 'transparent', border: 'none', color: '#6B7280',
            fontSize: 11, fontWeight: 600, cursor: 'pointer', fontFamily: 'inherit',
          }}>{showPw ? 'Hide' : 'Show'}</button>
        </div>
      </AField>
      <AField label="Assign to Clinic" hint="This user will only see data for the assigned clinic.">
        <ASelect value={form.clinic_id || ''} onChange={e => set('clinic_id', e.target.value || null)}>
          <option value="">— No clinic assigned —</option>
          {clinics.map(c => (
            <option key={c.id} value={c.id}>{c.code} — {c.name}</option>
          ))}
        </ASelect>
      </AField>
    </AdminModal>
  );
}

function AdminUsersPage({ users, clinics, token, onRefresh }) {
  const [modal, setModal] = _aas(null);
  const [deleteTarget, setDeleteTarget] = _aas(null);
  const [search, setSearch] = _aas('');
  const [saving, setSaving] = _aas(false);
  const [deleting, setDeleting] = _aas(false);

  const filtered = users.filter(u =>
    u.name.toLowerCase().includes(search.toLowerCase()) ||
    u.email.toLowerCase().includes(search.toLowerCase())
  );

  const BLANK = { id: '', name: '', email: '', password: '', role: 'admin', clinic_id: null };

  const save = async (data) => {
    if (!data.name || !data.email) { window.toast('Name and email required', { type: 'error' }); return; }
    if (!data.id && !data.password) { window.toast('Password required for new user', { type: 'error' }); return; }
    setSaving(true);
    try {
      if (data.id) {
        await adminFetch(token, `/api/admin?resource=users&id=${data.id}`, {
          method: 'PATCH',
          body: { name: data.name, role: data.role, clinic_id: data.clinic_id || null, ...(data.password ? { password: data.password } : {}) },
        });
        window.toast('User updated', { type: 'success' });
      } else {
        await adminFetch(token, '/api/admin?resource=users', {
          method: 'POST',
          body: { name: data.name, email: data.email, password: data.password, role: data.role, clinic_id: data.clinic_id || null },
        });
        window.toast('User created — they can now log in', { type: 'success' });
      }
      await onRefresh();
      setModal(null);
    } catch (err) {
      window.toast(err.message, { type: 'error' });
    }
    setSaving(false);
  };

  const confirmDelete = async () => {
    setDeleting(true);
    try {
      await adminFetch(token, `/api/admin?resource=users&id=${deleteTarget.id}`, { method: 'DELETE' });
      window.toast(`Deleted ${deleteTarget.name}`, { type: 'info' });
      await onRefresh();
      setDeleteTarget(null);
    } catch (err) {
      window.toast(err.message, { type: 'error' });
    }
    setDeleting(false);
  };

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: 'flex', gap: 12, marginBottom: 20 }}>
        <SearchInput value={search} onChange={e => setSearch(e.target.value)} placeholder="Search by name or email…" />
        <ABtn onClick={() => setModal(BLANK)}><I.plus size={14} /> Add User</ABtn>
      </div>

      <ATable
        cols={['User', 'Email', 'Role', 'Assigned Clinic', 'Created', 'Actions']}
        rows={filtered.map(u => [
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <div style={{ width: 30, height: 30, borderRadius: 7, background: 'linear-gradient(135deg, #4F46E5, #7C3AED)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 11, flexShrink: 0 }}>
              {u.name.split(' ').slice(0, 2).map(p => p[0]).join('').toUpperCase()}
            </div>
            <div>
              <div style={{ fontWeight: 600, fontSize: 13, color: '#0C0714' }}>{u.name}</div>
              <div style={{ fontSize: 10, color: '#9CA3AF', fontFamily: 'monospace' }}>{u.id.slice(0, 8)}…</div>
            </div>
          </div>,
          <span style={{ fontSize: 12, fontFamily: 'monospace', color: '#374151' }}>{u.email}</span>,
          <ABadge status={u.role} />,
          <span style={{ fontSize: 12, color: u.clinicName === '—' ? '#9CA3AF' : '#374151' }}>
            {u.clinicName !== '—'
              ? (() => { const c = clinics.find(c => c.id === u.clinic_id); return c ? <span style={{ display:'flex', alignItems:'center', gap:6 }}><span style={{ width:16, height:16, borderRadius:3, background:c.bg, display:'inline-block' }} />{c.name}</span> : u.clinicName; })()
              : '— Not assigned —'
            }
          </span>,
          <span style={{ fontSize: 12, color: '#9CA3AF', fontFamily: 'monospace' }}>{u.created}</span>,
          <div style={{ display: 'flex', gap: 6 }}>
            <ABtn small onClick={() => setModal({ ...u })}>Edit</ABtn>
            <ABtn small danger onClick={() => setDeleteTarget(u)}>Delete</ABtn>
          </div>,
        ])}
        emptyText="No users yet. Click 'Add User' to create the first one."
      />

      <UserFormModal open={!!modal} data={modal} clinics={clinics} onClose={() => setModal(null)} onSave={save} saving={saving} />

      <AdminModal open={!!deleteTarget} onClose={() => setDeleteTarget(null)}
        title="Delete User"
        footer={<>
          <ABtn variant="ghost" onClick={() => setDeleteTarget(null)} disabled={deleting}>Cancel</ABtn>
          <ABtn danger onClick={confirmDelete} disabled={deleting}>
            {deleting ? 'Deleting…' : 'Delete permanently'}
          </ABtn>
        </>}
      >
        <p style={{ color: '#374151', fontSize: 14, lineHeight: 1.6 }}>
          Delete <strong>{deleteTarget?.name}</strong>? Their Supabase auth account will be removed and they will immediately lose access. This cannot be undone.
        </p>
      </AdminModal>
    </div>
  );
}

// ─── Clinics Page ──────────────────────────────────────────────────────────────

function ClinicFormModal({ open, data, onClose, onSave, saving }) {
  const [form, setForm] = _aas({});
  _aae(() => { if (data) setForm({ ...data }); }, [data]);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));

  return (
    <AdminModal open={open} onClose={onClose} wide
      title={form.id ? `Edit Clinic: ${form.name}` : 'Create New Clinic'}
      footer={<>
        <ABtn variant="ghost" onClick={onClose} disabled={saving}>Cancel</ABtn>
        <ABtn onClick={() => onSave(form)} disabled={saving}>
          {saving ? <><I.refresh size={13} style={{ animation: 'spin 0.9s linear infinite' }} /> Saving…</> : (form.id ? 'Save changes' : 'Create clinic')}
        </ABtn>
      </>}
    >
      <div style={{ display: 'grid', gridTemplateColumns: '2fr 1fr', gap: 12 }}>
        <AField label="Clinic Name">
          <AInput value={form.name || ''} onChange={e => set('name', e.target.value)} placeholder="Apollo Family Clinic" />
        </AField>
        <AField label="Specialty">
          <AInput value={form.specialty || ''} onChange={e => set('specialty', e.target.value)} placeholder="General Medicine" />
        </AField>
      </div>
      <AField label="Address">
        <AInput value={form.address || ''} onChange={e => set('address', e.target.value)} placeholder="Civil Lines, Raipur, CG 492001" />
      </AField>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <AField label="Clinic Phone">
          <AInput value={form.phone || ''} onChange={e => set('phone', e.target.value)} placeholder="+91 771 234 5678" />
        </AField>
        <AField label="Subscription Plan">
          <ASelect value={form.plan || 'free'} onChange={e => set('plan', e.target.value)}>
            {ADMIN_PLANS.map(p => (
              <option key={p.id} value={p.id}>
                {p.name}{p.price > 0 ? ` — ₹${p.price}/mo` : p.price === 0 ? ' — Free' : ' — Custom'}
              </option>
            ))}
          </ASelect>
        </AField>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
        <AField label="WhatsApp Bot Number" hint="Patient-facing outbound number">
          <AInput value={form.whatsappNumber || ''} onChange={e => set('whatsappNumber', e.target.value)} placeholder="+91 98765 43210" />
        </AField>
        <AField label="Owner Personal WhatsApp" hint="Receives weekly summary">
          <AInput value={form.ownerWhatsapp || ''} onChange={e => set('ownerWhatsapp', e.target.value)} placeholder="+91 98765 43210" />
        </AField>
      </div>
    </AdminModal>
  );
}

function AdminClinicsPage({ clinics, users, token, onRefresh }) {
  const [modal, setModal] = _aas(null);
  const [deleteTarget, setDeleteTarget] = _aas(null);
  const [search, setSearch] = _aas('');
  const [saving, setSaving] = _aas(false);
  const [deleting, setDeleting] = _aas(false);

  const filtered = clinics.filter(c =>
    c.name.toLowerCase().includes(search.toLowerCase()) ||
    c.specialty.toLowerCase().includes(search.toLowerCase())
  );

  const BLANK = { id: '', name: '', specialty: '', address: '', phone: '', whatsappNumber: '', ownerWhatsapp: '', plan: 'free' };

  const save = async (data) => {
    if (!data.name) { window.toast('Clinic name required', { type: 'error' }); return; }
    setSaving(true);
    try {
      const body = {
        name: data.name,
        specialty: data.specialty || null,
        address: data.address || null,
        phone: data.phone || null,
        whatsapp_number: data.whatsappNumber || null,
        owner_whatsapp: data.ownerWhatsapp || null,
        plan: data.plan || 'free',
      };
      if (data.id) {
        await adminFetch(token, `/api/admin?resource=clinics&id=${data.id}`, { method: 'PATCH', body });
        window.toast('Clinic updated', { type: 'success' });
      } else {
        await adminFetch(token, '/api/admin?resource=clinics', { method: 'POST', body });
        window.toast('Clinic created', { type: 'success' });
      }
      await onRefresh();
      setModal(null);
    } catch (err) {
      window.toast(err.message, { type: 'error' });
    }
    setSaving(false);
  };

  const confirmDelete = async () => {
    setDeleting(true);
    try {
      await adminFetch(token, `/api/admin?resource=clinics&id=${deleteTarget.id}`, { method: 'DELETE' });
      window.toast(`Deleted ${deleteTarget.name}`, { type: 'info' });
      await onRefresh();
      setDeleteTarget(null);
    } catch (err) {
      window.toast(err.message, { type: 'error' });
    }
    setDeleting(false);
  };

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: 'flex', gap: 12, marginBottom: 20 }}>
        <SearchInput value={search} onChange={e => setSearch(e.target.value)} placeholder="Search clinics…" />
        <ABtn onClick={() => setModal(BLANK)}><I.plus size={14} /> Add Clinic</ABtn>
      </div>

      <ATable
        cols={['Clinic', 'Specialty', 'Plan', 'Staff', 'Patients', 'Created', 'Actions']}
        rows={filtered.map(c => {
          const plan = ADMIN_PLANS.find(p => p.id === c.plan);
          return [
            <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
              <span style={{ width: 30, height: 30, borderRadius: 7, background: c.bg, display: 'inline-flex', alignItems: 'center', justifyContent: 'center', color: '#fff', fontWeight: 700, fontSize: 10, flexShrink: 0 }}>{c.code}</span>
              <div>
                <div style={{ fontWeight: 600, fontSize: 13, color: '#0C0714' }}>{c.name}</div>
                <div style={{ fontSize: 10, color: '#9CA3AF', fontFamily: 'monospace' }}>{c.id.slice(0, 8)}…</div>
              </div>
            </div>,
            <span style={{ fontSize: 12, color: '#6B7280' }}>{c.specialty}</span>,
            <span style={{ padding: '2px 8px', borderRadius: 20, background: (plan?.color || '#6B7280') + '18', color: plan?.color || '#6B7280', fontSize: 11, fontWeight: 600 }}>{plan?.name}</span>,
            <span style={{ fontSize: 13, color: '#374151' }}>{c.staffCount}</span>,
            <span style={{ fontSize: 13, color: '#374151' }}>{c.patientCount.toLocaleString()}</span>,
            <span style={{ fontSize: 12, color: '#9CA3AF', fontFamily: 'monospace' }}>{c.created}</span>,
            <div style={{ display: 'flex', gap: 6 }}>
              <ABtn small onClick={() => setModal({ ...c })}>Edit</ABtn>
              <ABtn small danger onClick={() => setDeleteTarget(c)}>Delete</ABtn>
            </div>,
          ];
        })}
        emptyText="No clinics yet. Click 'Add Clinic' to create the first one."
      />

      <ClinicFormModal open={!!modal} data={modal} onClose={() => setModal(null)} onSave={save} saving={saving} />

      <AdminModal open={!!deleteTarget} onClose={() => setDeleteTarget(null)}
        title="Delete Clinic"
        footer={<>
          <ABtn variant="ghost" onClick={() => setDeleteTarget(null)} disabled={deleting}>Cancel</ABtn>
          <ABtn danger onClick={confirmDelete} disabled={deleting}>
            {deleting ? 'Deleting…' : 'Delete permanently'}
          </ABtn>
        </>}
      >
        <p style={{ color: '#374151', fontSize: 14, lineHeight: 1.6 }}>
          Delete <strong>{deleteTarget?.name}</strong>? All patients, appointments, follow-ups, and communications for this clinic will be removed. This cannot be undone.
        </p>
      </AdminModal>
    </div>
  );
}

// ─── Plans Page ────────────────────────────────────────────────────────────────

function AdminPlansPage({ clinics }) {
  const [plans, setPlans] = _aas(ADMIN_PLANS);
  const [editPlan, setEditPlan] = _aas(null);
  const [featuresText, setFeaturesText] = _aas('');

  const openEdit = (plan) => {
    setEditPlan({ ...plan });
    setFeaturesText((plan.features || []).join('\n'));
  };

  const save = () => {
    const updated = { ...editPlan, features: featuresText.split('\n').map(f => f.trim()).filter(Boolean) };
    setPlans(prev => prev.map(p => p.id === updated.id ? updated : p));
    window.toast(`Plan "${updated.name}" updated`, { type: 'success' });
    setEditPlan(null);
  };

  const setEP = (k, v) => setEditPlan(p => ({ ...p, [k]: v }));
  const setLim = (k, v) => setEditPlan(p => ({ ...p, limits: { ...p.limits, [k]: Number(v) } }));

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 20, marginBottom: 32 }}>
        {plans.map(plan => {
          const planClinics = clinics.filter(c => c.plan === plan.id);
          return (
            <div key={plan.id} style={{ background: '#fff', borderRadius: 16, border: '1px solid #E5E7EB', overflow: 'hidden', position: 'relative' }}>
              {plan.popular && (
                <div style={{ position: 'absolute', top: 12, right: 12, background: '#7C3AED', color: '#fff', fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 20 }}>POPULAR</div>
              )}
              <div style={{ height: 5, background: plan.bg }} />
              <div style={{ padding: 20 }}>
                <div style={{ fontWeight: 700, fontSize: 16, color: '#0C0714', marginBottom: 2 }}>{plan.name}</div>
                <div style={{ fontSize: 12, color: '#9CA3AF', marginBottom: 14 }}>{plan.tagline}</div>
                <div style={{ marginBottom: 16 }}>
                  {plan.price === null
                    ? <span style={{ fontSize: 22, fontWeight: 700, color: '#0C0714' }}>Custom</span>
                    : plan.price === 0
                    ? <span style={{ fontSize: 22, fontWeight: 700, color: '#0C0714' }}>Free</span>
                    : <><span style={{ fontSize: 22, fontWeight: 700, color: '#0C0714' }}>₹{plan.price.toLocaleString()}</span><span style={{ fontSize: 13, color: '#9CA3AF' }}>/month</span></>
                  }
                </div>
                <ul style={{ margin: 0, padding: 0, listStyle: 'none', marginBottom: 16 }}>
                  {(plan.features || []).map((f, i) => (
                    <li key={i} style={{ display: 'flex', alignItems: 'flex-start', gap: 7, fontSize: 12, color: '#374151', marginBottom: 5 }}>
                      <span style={{ color: plan.color, flexShrink: 0, marginTop: 1 }}>✓</span>{f}
                    </li>
                  ))}
                </ul>
                <div style={{ background: '#F9FAFB', borderRadius: 8, padding: '10px 14px', display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
                  <span style={{ fontSize: 12, color: '#6B7280' }}>Clinics on this plan</span>
                  <span style={{ fontSize: 18, fontWeight: 700, color: '#0C0714' }}>{planClinics.length}</span>
                </div>
                <ABtn onClick={() => openEdit(plan)} style={{ width: '100%', justifyContent: 'center' }}>
                  Edit Plan
                </ABtn>
              </div>
            </div>
          );
        })}
      </div>

      <AdminModal open={!!editPlan} onClose={() => setEditPlan(null)}
        title={`Edit Plan: ${editPlan?.name}`}
        footer={<>
          <ABtn variant="ghost" onClick={() => setEditPlan(null)}>Cancel</ABtn>
          <ABtn onClick={save}>Save changes</ABtn>
        </>}
      >
        {editPlan && (
          <>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <AField label="Plan Name">
                <AInput value={editPlan.name} onChange={e => setEP('name', e.target.value)} />
              </AField>
              <AField label="Monthly Price (₹)" hint="0 = free · blank = custom/negotiated">
                <AInput type="number" value={editPlan.price === null ? '' : editPlan.price}
                  onChange={e => setEP('price', e.target.value === '' ? null : Number(e.target.value))}
                  placeholder="2999" />
              </AField>
            </div>
            <AField label="Tagline">
              <AInput value={editPlan.tagline || ''} onChange={e => setEP('tagline', e.target.value)} />
            </AField>
            <AField label="Features" hint="One feature per line">
              <ATextarea value={featuresText} onChange={e => setFeaturesText(e.target.value)} rows={6} />
            </AField>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
              <AField label="Max Clinics" hint="-1 = unlimited">
                <AInput type="number" value={editPlan.limits?.clinics ?? ''} onChange={e => setLim('clinics', e.target.value)} />
              </AField>
              <AField label="Max Users" hint="-1 = unlimited">
                <AInput type="number" value={editPlan.limits?.users ?? ''} onChange={e => setLim('users', e.target.value)} />
              </AField>
              <AField label="Max Patients" hint="-1 = unlimited">
                <AInput type="number" value={editPlan.limits?.patients ?? ''} onChange={e => setLim('patients', e.target.value)} />
              </AField>
              <AField label="Max Messages/Month" hint="-1 = unlimited">
                <AInput type="number" value={editPlan.limits?.messages ?? ''} onChange={e => setLim('messages', e.target.value)} />
              </AField>
            </div>
          </>
        )}
      </AdminModal>
    </div>
  );
}

// ─── Payments Page ─────────────────────────────────────────────────────────────

function AdminPaymentsPage({ clinics }) {
  const [payments, setPayments] = _aas(() => {
    // Pre-populate clinicNames from real DB clinics where possible
    return INITIAL_PAYMENTS.map(p => {
      const match = clinics.find(c => c.name === p.clinicName);
      return match ? { ...p, clinicId: match.id } : p;
    });
  });
  const [filter, setFilter] = _aas('all');
  const [addOpen, setAddOpen] = _aas(false);
  const [addForm, setAddForm] = _aas({ clinicId: '', plan: 'starter', amount: '', dueDate: '', notes: '' });

  const filtered = filter === 'all' ? payments : payments.filter(p => p.status === filter);

  const markPaid = (id) => {
    setPayments(prev => prev.map(p => p.id === id ? { ...p, status: 'paid', paidDate: new Date().toISOString().slice(0, 10) } : p));
    window.toast('Marked as paid', { type: 'success' });
  };

  const sendReminder = (p) => {
    window.toast(`Reminder sent to ${p.clinicName}`, {
      sub: `₹${p.amount.toLocaleString()} due ${p.dueDate}`,
      type: 'info',
    });
  };

  const addPayment = () => {
    if (!addForm.clinicId || !addForm.amount) { window.toast('Clinic and amount required', { type: 'error' }); return; }
    const clinic = clinics.find(c => c.id === addForm.clinicId);
    setPayments(prev => [
      {
        id: 'PAY-' + String(Date.now()).slice(-6),
        clinicId: addForm.clinicId,
        clinicName: clinic?.name || '—',
        plan: addForm.plan,
        amount: Number(addForm.amount),
        dueDate: addForm.dueDate,
        status: 'pending',
        paidDate: null,
        notes: addForm.notes,
      },
      ...prev,
    ]);
    window.toast('Payment record added', { type: 'success' });
    setAddOpen(false);
    setAddForm({ clinicId: '', plan: 'starter', amount: '', dueDate: '', notes: '' });
  };

  const totalCollected = payments.filter(p => p.status === 'paid').reduce((s, p) => s + p.amount, 0);
  const totalDue = payments.filter(p => p.status === 'pending' || p.status === 'overdue').reduce((s, p) => s + p.amount, 0);
  const overdueCnt = payments.filter(p => p.status === 'overdue').length;

  const FILTERS = ['all', 'pending', 'overdue', 'paid', 'free'];

  return (
    <div style={{ padding: 24 }}>
      <div style={{ display: 'flex', gap: 14, marginBottom: 24 }}>
        {[
          { label: 'Total Collected', value: `₹${totalCollected.toLocaleString()}`, color: '#10B981' },
          { label: 'Outstanding / Due', value: `₹${totalDue.toLocaleString()}`, color: '#F59E0B' },
          { label: 'Overdue Records', value: overdueCnt, color: overdueCnt > 0 ? '#EF4444' : '#9CA3AF' },
        ].map((s, i) => (
          <div key={i} style={{ background: '#fff', borderRadius: 10, padding: '14px 18px', border: '1px solid #E5E7EB', flex: 1 }}>
            <div style={{ fontSize: 11, color: '#9CA3AF', fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.05em' }}>{s.label}</div>
            <div style={{ fontSize: 22, fontWeight: 700, color: s.color, marginTop: 4 }}>{s.value}</div>
          </div>
        ))}
      </div>

      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 18 }}>
        <div style={{ display: 'flex', gap: 6, flex: 1, flexWrap: 'wrap' }}>
          {FILTERS.map(f => (
            <button key={f} onClick={() => setFilter(f)} style={{
              padding: '5px 14px', borderRadius: 20, fontSize: 12, fontWeight: 600,
              background: filter === f ? '#7C3AED' : '#F3F4F6',
              color: filter === f ? '#fff' : '#6B7280',
              border: 'none', cursor: 'pointer', fontFamily: 'inherit', textTransform: 'capitalize',
            }}>{f === 'all' ? `All (${payments.length})` : f}</button>
          ))}
        </div>
        <ABtn onClick={() => setAddOpen(true)}><I.plus size={14} /> Add Record</ABtn>
      </div>

      <ATable
        cols={['Clinic', 'Plan', 'Amount', 'Due Date', 'Status', 'Paid On', 'Notes', 'Actions']}
        rows={filtered.map(p => {
          const plan = ADMIN_PLANS.find(pl => pl.id === p.plan);
          return [
            <span style={{ fontWeight: 600, fontSize: 13, color: '#0C0714' }}>{p.clinicName}</span>,
            <span style={{ padding: '2px 8px', borderRadius: 20, background: (plan?.color || '#6B7280') + '18', color: plan?.color || '#6B7280', fontSize: 11, fontWeight: 600 }}>{p.plan}</span>,
            <span style={{ fontWeight: 700, fontSize: 13, color: '#0C0714' }}>{p.amount > 0 ? `₹${p.amount.toLocaleString()}` : '—'}</span>,
            <span style={{ fontSize: 12, color: '#6B7280', fontFamily: 'monospace' }}>{p.dueDate || '—'}</span>,
            <ABadge status={p.status} />,
            <span style={{ fontSize: 12, color: '#6B7280', fontFamily: 'monospace' }}>{p.paidDate || '—'}</span>,
            <span style={{ fontSize: 12, color: '#9CA3AF', maxWidth: 160, display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{p.notes || '—'}</span>,
            <div style={{ display: 'flex', gap: 6, flexWrap: 'nowrap' }}>
              {(p.status === 'pending' || p.status === 'overdue') && (
                <>
                  <ABtn small onClick={() => markPaid(p.id)}>Mark Paid</ABtn>
                  <ABtn small variant="ghost" onClick={() => sendReminder(p)}>
                    <I.send size={12} /> Remind
                  </ABtn>
                </>
              )}
            </div>,
          ];
        })}
      />

      <AdminModal open={addOpen} onClose={() => setAddOpen(false)}
        title="Add Payment Record"
        footer={<>
          <ABtn variant="ghost" onClick={() => setAddOpen(false)}>Cancel</ABtn>
          <ABtn onClick={addPayment}>Add record</ABtn>
        </>}
      >
        <AField label="Clinic">
          <ASelect value={addForm.clinicId} onChange={e => setAddForm(f => ({ ...f, clinicId: e.target.value }))}>
            <option value="">Select clinic…</option>
            {clinics.map(c => <option key={c.id} value={c.id}>{c.code} — {c.name}</option>)}
          </ASelect>
        </AField>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <AField label="Plan">
            <ASelect value={addForm.plan} onChange={e => setAddForm(f => ({ ...f, plan: e.target.value }))}>
              {ADMIN_PLANS.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
            </ASelect>
          </AField>
          <AField label="Amount (₹)">
            <AInput type="number" value={addForm.amount} onChange={e => setAddForm(f => ({ ...f, amount: e.target.value }))} placeholder="2999" />
          </AField>
        </div>
        <AField label="Due Date">
          <AInput type="date" value={addForm.dueDate} onChange={e => setAddForm(f => ({ ...f, dueDate: e.target.value }))} />
        </AField>
        <AField label="Notes (optional)">
          <AInput value={addForm.notes} onChange={e => setAddForm(f => ({ ...f, notes: e.target.value }))} placeholder="e.g. Paid via UPI, bank transfer…" />
        </AField>
      </AdminModal>
    </div>
  );
}

// ─── Admin App Root ────────────────────────────────────────────────────────────

function AdminApp() {
  const [authed, setAuthed] = _aas(false);
  const [token, setToken] = _aas(() => {
    try { return sessionStorage.getItem('cf_admin_token') || null; } catch { return null; }
  });
  const [route, setRoute] = _aas('overview');
  const [users, setUsers] = _aas([]);
  const [clinics, setClinics] = _aas([]);
  const [loadingData, setLoadingData] = _aas(false);

  const loadData = async (tk) => {
    const t = tk || token;
    if (!t) return;
    setLoadingData(true);
    try {
      const [cRes, uRes] = await Promise.all([
        adminFetch(t, '/api/admin?resource=clinics'),
        adminFetch(t, '/api/admin?resource=users'),
      ]);
      setClinics((cRes.clinics || []).map(mapDbClinic));
      setUsers((uRes.users || []).map(mapDbUser));
    } catch (err) {
      window.toast?.('Failed to load data: ' + err.message, { type: 'error' });
      if (err.message.includes('Unauthorized')) {
        signOut();
      }
    }
    setLoadingData(false);
  };

  _aae(() => {
    if (token) {
      setAuthed(true);
      loadData(token);
    }
  }, []);

  const auth = (tok) => {
    try { sessionStorage.setItem('cf_admin_token', tok); } catch {}
    setToken(tok);
    setAuthed(true);
    loadData(tok);
    window.toast('Welcome, Suraj', { sub: 'Orbis Admin · ClinicFlow', type: 'success' });
  };

  const signOut = () => {
    try { sessionStorage.removeItem('cf_admin_token'); } catch {}
    setToken(null);
    setAuthed(false);
    setUsers([]);
    setClinics([]);
  };

  if (!authed) return <AdminLogin onAuth={auth} />;

  if (loadingData && !users.length && !clinics.length) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh', background: '#0C0714', gap: 12 }}>
        <I.refresh size={20} stroke="#A78BFA" style={{ animation: 'spin 1s linear infinite' }} />
        <span style={{ color: '#6B7280', fontSize: 14 }}>Loading admin data…</span>
      </div>
    );
  }

  const refresh = () => loadData(token);

  return (
    <div style={{ display: 'flex', minHeight: '100vh', background: '#F9FAFB', fontFamily: 'inherit' }}>
      <AdminSidebar route={route} navigate={setRoute} onSignOut={signOut} />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, overflowX: 'hidden' }}>
        <AdminTopbar route={route} />
        <div style={{ flex: 1 }}>
          {route === 'overview'  && <AdminOverviewPage users={users} clinics={clinics} navigate={setRoute} />}
          {route === 'clinics'   && <AdminClinicsPage clinics={clinics} users={users} token={token} onRefresh={refresh} />}
          {route === 'users'     && <AdminUsersPage users={users} clinics={clinics} token={token} onRefresh={refresh} />}
          {route === 'plans'     && <AdminPlansPage clinics={clinics} />}
          {route === 'payments'  && <AdminPaymentsPage clinics={clinics} />}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { AdminApp });
