// src/features/admin/ui/admin-students-modals.jsx
//
// Modals used by AdminStudents and ASCard. Extracted from
// admin-students.jsx for size.
// Public on window: ASConfirmDelete, ASRechargeModal, ASEditStudent,
// ASAddStudent. Also keeps the legacy AdminEditStudentModal alias.

// Typed-name confirmation: admin must retype the full name exactly before
// the Delete button enables. The same check is enforced server-side by
// admin_hard_delete_student (v78-delete-safety.sql) so a console caller
// can't bypass the UI. onConfirm receives the typed name and forwards it
// to data.deleteStudent → RPC.
const ASConfirmDelete = ({ name, kind = 'student', onConfirm, onClose }) => {
  const [busy, setBusy] = React.useState(false);
  const [err,  setErr]  = React.useState('');
  const [typed, setTyped] = React.useState('');
  const expected = String(name || '').trim();
  const matches  = typed.trim().toLowerCase() === expected.toLowerCase() && expected.length > 0;
  return (
    <div style={{ position:'fixed', inset:0, background:'rgba(10,12,24,0.4)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9000 }} onClick={onClose}>
      <div style={{ background:'#fff', borderRadius:14, padding:'26px', width:380, maxWidth:'calc(100vw - 32px)', boxShadow:'0 20px 60px rgba(0,0,0,0.18)', fontFamily:"'Plus Jakarta Sans', sans-serif" }} onClick={e=>e.stopPropagation()}>
        <div style={{ fontWeight:700, fontSize:16, color:'oklch(18% 0.03 265)', marginBottom:8 }}>Delete {kind} {name}?</div>
        <div style={{ fontSize:13, color:'oklch(54% 0.03 265)', lineHeight:1.55, marginBottom:14 }}>
          This permanently removes their account, all of their bookings, and any
          assignments. The email is freed up so it can be used again. The account
          is moved to <strong>Trash</strong>, where it can be restored within a
          short window.
        </div>
        <div style={{ fontSize:12, color:'oklch(40% 0.04 265)', marginBottom:6, fontWeight:600 }}>
          To confirm, type <span style={{ background:'oklch(96% 0.01 265)', padding:'1px 6px', borderRadius:4, fontWeight:700, color:'oklch(18% 0.03 265)' }}>{expected}</span>
        </div>
        <input
          type="text"
          value={typed}
          onChange={e => setTyped(e.target.value)}
          autoFocus
          placeholder={`Type ${expected} here`}
          aria-label={`Type ${kind} full name to confirm delete`}
          data-testid="confirm-delete-typed-name"
          style={{
            width:'100%', boxSizing:'border-box', padding:'10px 12px',
            borderRadius:8, fontSize:13, marginBottom:14,
            border: matches ? '1.5px solid oklch(60% 0.16 145)'
                            : '1.5px solid oklch(88% 0.02 265)',
            outline:'none', fontFamily:"'Plus Jakarta Sans', sans-serif",
          }}
        />
        {err && <div style={{ background:'oklch(95% 0.06 25)', color:'oklch(40% 0.15 25)', padding:'8px 12px', borderRadius:8, fontSize:12, marginBottom:12 }}>{err}</div>}
        <div style={{ display:'flex', gap:10 }}>
          <button
            onClick={async () => {
              if (!matches || busy) return;
              setBusy(true); setErr('');
              try { await onConfirm(typed.trim()); onClose(); }
              catch (e) { setErr(e.message || 'Failed.'); }
              finally { setBusy(false); }
            }}
            disabled={busy || !matches}
            title={!matches ? `Type "${expected}" exactly to enable Delete` : undefined}
            data-testid="confirm-delete-submit"
            style={{
              flex:1,
              background: matches ? 'oklch(40% 0.18 25)' : 'oklch(88% 0.04 25)',
              color:'#fff', border:'none', borderRadius:9, padding:'11px 0',
              fontWeight:700, fontSize:13,
              cursor: matches ? (busy?'wait':'pointer') : 'not-allowed',
              fontFamily:"'Plus Jakarta Sans', sans-serif",
              opacity: busy ? 0.7 : 1,
            }}
          >
            {busy ? 'Deleting…' : `Yes, delete ${kind}`}
          </button>
          <button onClick={onClose} style={{ padding:'11px 16px', background:'oklch(95% 0.01 265)', border:'none', borderRadius:9, fontSize:13, cursor:'pointer', color:'oklch(46% 0.04 265)', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>Cancel</button>
        </div>
      </div>
    </div>
  );
};

// ── Recharge Classes Modal ──────────────────────────────────────────────
const ASRechargeModal = ({ student, onClose }) => {
  const data = window.useAdminData();
  const [count, setCount] = React.useState(5);
  const [busy, setBusy]   = React.useState(false);
  const [err, setErr]     = React.useState('');
  const submit = async (e) => {
    e.preventDefault();
    setBusy(true); setErr('');
    try {
      const newBal = await data.addStudentCredits(student.id, Number(count));
      onClose(newBal);
    } catch (e2) { setErr(e2.message || 'Recharge failed.'); }
    finally { setBusy(false); }
  };
  return (
    <div style={{ position:'fixed', inset:0, background:'rgba(10,12,24,0.4)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9000 }} onClick={onClose}>
      <div style={{ background:'#fff', borderRadius:14, padding:'26px', width:400, boxShadow:'0 20px 60px rgba(0,0,0,0.18)', fontFamily:"'Plus Jakarta Sans', sans-serif" }} onClick={e=>e.stopPropagation()}>
        <div style={{ fontWeight:700, fontSize:16, color:'oklch(18% 0.03 265)', marginBottom:6 }}>Add classes for {student.name}</div>
        <div style={{ fontSize:12, color:'oklch(58% 0.03 265)', marginBottom:16 }}>
          Currently <strong>{student.classesBalance}</strong> left of {student.classesPurchased} ever purchased.
          Use a negative number to subtract.
        </div>
        <form onSubmit={submit}>
          <div style={{ display:'flex', alignItems:'center', gap:12, marginBottom:16 }}>
            <button type="button" onClick={() => setCount(c => Math.max(-99, c - 1))} style={{ width:36, height:36, borderRadius:8, border:'1px solid oklch(88% 0.02 265)', background:'oklch(96% 0.01 265)', cursor:'pointer', fontSize:18, fontWeight:600 }}>−</button>
            <input type="number" value={count} onChange={e=>setCount(e.target.value)} style={{ flex:1, padding:'10px 12px', borderRadius:8, border:'1.5px solid oklch(88% 0.015 265)', fontSize:18, textAlign:'center', fontWeight:700, fontFamily:"'Plus Jakarta Sans', sans-serif" }} />
            <button type="button" onClick={() => setCount(c => Math.min(99, Number(c) + 1))} style={{ width:36, height:36, borderRadius:8, border:'1px solid oklch(88% 0.02 265)', background:'oklch(96% 0.01 265)', cursor:'pointer', fontSize:18, fontWeight:600 }}>+</button>
          </div>
          <div style={{ display:'flex', gap:8, marginBottom:18, flexWrap:'wrap' }}>
            {[1,5,10,20].map(n => (
              <button key={n} type="button" onClick={() => setCount(n)} style={{ padding:'6px 14px', borderRadius:7, border:'1px solid oklch(88% 0.02 265)', background:'#fff', fontSize:12, fontWeight:600, color:'oklch(36% 0.04 265)', cursor:'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>+{n}</button>
            ))}
          </div>
          {err && <div style={{ background:'oklch(95% 0.06 25)', color:'oklch(40% 0.15 25)', padding:'8px 12px', borderRadius:8, fontSize:12, marginBottom:12 }}>{err}</div>}
          <div style={{ display:'flex', gap:10 }}>
            <button type="submit" disabled={busy || Number(count) === 0} style={{ flex:1, background:'oklch(22% 0.06 265)', color:'#fff', border:'none', borderRadius:9, padding:'11px 0', fontWeight:600, fontSize:14, cursor:busy?'wait':'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif", opacity:busy?0.7:1 }}>
              {busy ? 'Saving…' : (Number(count) > 0 ? `Add ${count} class${count>1?'es':''}` : `Subtract ${Math.abs(count)} class${Math.abs(count)>1?'es':''}`)}
            </button>
            <button type="button" onClick={onClose} style={{ padding:'11px 16px', background:'oklch(95% 0.01 265)', border:'none', borderRadius:9, fontSize:13, cursor:'pointer', color:'oklch(46% 0.04 265)', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>Cancel</button>
          </div>
        </form>
      </div>
    </div>
  );
};

// ── Edit Student Modal ──────────────────────────────────────────────────
const ASEditStudent = ({ student, onClose }) => {
  const data = window.useAdminData();
  const [form, setForm] = React.useState({
    name:     student.name || '',
    phone:    student.phone || '',
    address:  student.address || '',
    topic:    student.topics?.[0] || '',
    notes:    student.notes || '',
    hourlyRate:  student.hourlyRate == null ? '' : student.hourlyRate,
    availability: student.availability || {},
    availabilityNote: student.availabilityNote || '',
    isOnline:    !!student.isOnline,
    meetingLink: student.meetingLink || '',
  });
  const [busy, setBusy] = React.useState(false);
  const [err, setErr]   = React.useState('');
  // Timezone lives on profiles.timezone for the student.id. Load on mount,
  // save on submit. Phase 2 auto-detect: if the profile has no timezone
  // yet, prefill with the admin's detected zone.
  const [tz, setTz] = React.useState(() => window.Calendar.time.detect());
  React.useEffect(() => {
    (async () => {
      try {
        const { data: row } = await window.supa.from('profiles').select('timezone').eq('id', student.id).maybeSingle();
        if (row?.timezone) setTz(row.timezone);
      } catch (e) { /* keep detected default */ }
    })();
  }, [student.id]);

  const set = (k,v) => setForm(f => ({...f, [k]:v}));
  const fld = { width:'100%', padding:'12px 14px', borderRadius:8, border:'1.5px solid oklch(88% 0.015 265)', fontSize:16, minHeight:44, fontFamily:"'Plus Jakarta Sans', sans-serif", color:'oklch(22% 0.06 265)', background:'#fff', outline:'none', boxSizing:'border-box' };
  const lbl = { display:'block', fontSize:10, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'oklch(52% 0.04 265)', marginBottom:5 };

  // Same dropdown options as the Add Student modal — keep in sync.
  const STD_SUBJECTS = ['Piano','Guitar','Violin','Vocals','Drums','Bass','Saxophone','Cello','Flute','Ukulele','Trumpet','Drawing','Painting','Photography','Ballet','Hip Hop','Yoga','Tennis','Boxing','Acting'];
  // If the student's existing topic isn't in our standard list, keep it as
  // a one-off option so we don't silently drop it on save.
  const topicOptions = form.topic && !STD_SUBJECTS.includes(form.topic)
    ? [form.topic, ...STD_SUBJECTS]
    : STD_SUBJECTS;

  const submit = async (e) => {
    e.preventDefault();
    const phoneE164 = form.phone.trim().replace(/[\s\-().]/g, '');
    if (!/^\+[1-9]\d{6,14}$/.test(phoneE164)) {
      setErr('Enter the student’s phone with country code, e.g. +961 70 123 456 or +1 212 555 0123 — the teacher calls this number (masked).');
      return;
    }
    setBusy(true); setErr('');
    try {
      // Update profile.full_name (the public display name) if it changed.
      // student_info doesn't store the name — it lives on profiles.
      const newName = form.name.trim();
      if (newName && newName !== student.name) {
        await data.updateStudentName(student.id, newName);
      }
      await data.updateStudentInfo(student.id, {
        phone: phoneE164, address: form.address.trim(),
        topicsOfInterest: form.topic ? [form.topic] : [],
        notes: form.notes,
        availability: form.availability,
        availabilityNote: form.availabilityNote,
        isOnline: form.isOnline,
        meetingLink: form.isOnline ? form.meetingLink.trim() : '',
      });
      if ((form.hourlyRate === '' ? null : Number(form.hourlyRate)) !== student.hourlyRate) {
        await data.setStudentHourlyRate(student.id, form.hourlyRate);
      }
      // Persist timezone on profiles (RLS allows admin to write any row).
      try {
        await window.supa.from('profiles').update({ timezone: tz }).eq('id', student.id);
      } catch (e) { console.warn('[admin students] tz save failed', e); }
      onClose();
    } catch (e2) { setErr(e2.message || 'Save failed.'); }
    finally { setBusy(false); }
  };

  return (
    <div style={{ position:'fixed', inset:0, background:'rgba(10,12,24,0.4)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9000 }} onClick={onClose}>
      <div style={{ background:'#fff', borderRadius:14, padding:'26px', width:560, maxHeight:'92vh', overflowY:'auto', boxShadow:'0 20px 60px rgba(0,0,0,0.18)', fontFamily:"'Plus Jakarta Sans', sans-serif" }} onClick={e=>e.stopPropagation()}>
        <div style={{ fontWeight:700, fontSize:16, color:'oklch(18% 0.03 265)', marginBottom:6 }}>Edit {student.name}</div>
        <div style={{ fontSize:12, color:'oklch(58% 0.03 265)', marginBottom:16 }}>Email is the login — to change it, delete the user and re-add with the new email.</div>
        <form onSubmit={submit}>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginBottom:14 }}>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Full name</label>
              <input value={form.name} onChange={e=>set('name', e.target.value)} placeholder="Alex Johnson" required style={fld} />
            </div>
            <div>
              <label style={lbl}>Hourly rate ($/hr)</label>
              <input type="number" min={0} max={500} value={form.hourlyRate} onChange={e=>set('hourlyRate', e.target.value)} placeholder="80" style={fld} />
            </div>
            <div>
              <label style={lbl}>Phone * (teacher calls this)</label>
              <window.PhoneInput value={form.phone} onChange={v=>set('phone', v)} fieldStyle={fld} />
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Address</label>
              <input value={form.address} onChange={e=>set('address', e.target.value)} placeholder="245 W 72nd St, New York, NY" style={fld} />
            </div>
            <div style={{ gridColumn:'1/-1', background:'oklch(98% 0.005 265)', borderRadius:8, padding:'10px 12px', display:'flex', alignItems:'center', gap:10 }}>
              <input type="checkbox" id={`isOnlineEdit-${student.id}`} checked={!!form.isOnline} onChange={e=>set('isOnline', e.target.checked)} style={{ width:16, height:16, accentColor:'oklch(22% 0.06 265)' }} />
              <label htmlFor={`isOnlineEdit-${student.id}`} style={{ fontSize:13, color:'oklch(28% 0.05 265)', cursor:'pointer', fontWeight:600 }}>💻 Online lessons (Zoom / Meet etc.)</label>
            </div>
            {form.isOnline && (
              <div style={{ gridColumn:'1/-1' }}>
                <label style={lbl}>Permanent meeting link</label>
                <input type="url" value={form.meetingLink} onChange={e=>set('meetingLink', e.target.value)} placeholder="https://meet.google.com/abc-defg-hij  or  https://zoom.us/j/123456789" style={fld} />
                <div style={{ fontSize:10, color:'oklch(60% 0.03 265)', marginTop:3 }}>This student's permanent room. Every lesson uses it — shown to the student and their instructor, joined automatically by the recorder, and linked in reminder emails. Paste a Google Meet or Zoom URL.</div>
              </div>
            )}
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Topic / what they want to learn</label>
              <select value={form.topic} onChange={e=>set('topic', e.target.value)} style={fld}>
                <option value="">— None —</option>
                {topicOptions.map(s => <option key={s} value={s}>{s}</option>)}
              </select>
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Admin notes</label>
              <textarea value={form.notes} onChange={e=>set('notes', e.target.value)} rows={2} style={{...fld, resize:'vertical', fontFamily:"'Plus Jakarta Sans', sans-serif"}} placeholder="Anything to remember about this student" />
            </div>
          </div>

          <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', color:'oklch(52% 0.04 265)', marginBottom:8, paddingTop:12, borderTop:'1px solid oklch(92% 0.01 265)' }}>Availability</div>
          <div style={{ marginBottom:18 }}>
            <window.AvailabilityPicker value={form.availability} onChange={v => set('availability', v)} compact timezone={tz} onTimezoneChange={setTz} />
          </div>

          {err && <div style={{ background:'oklch(95% 0.06 25)', color:'oklch(40% 0.15 25)', padding:'9px 12px', borderRadius:8, fontSize:12, marginBottom:12 }}>{err}</div>}
          <div style={{ display:'flex', gap:10 }}>
            <button type="submit" disabled={busy} style={{ flex:1, background:'oklch(22% 0.06 265)', color:'#fff', border:'none', borderRadius:9, padding:'12px 0', fontWeight:600, fontSize:14, cursor:busy?'wait':'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif", opacity:busy?0.7:1 }}>
              {busy ? 'Saving…' : 'Save changes'}
            </button>
            <button type="button" onClick={onClose} style={{ padding:'12px 18px', background:'oklch(95% 0.01 265)', border:'none', borderRadius:9, fontSize:14, cursor:'pointer', color:'oklch(45% 0.04 265)', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>Cancel</button>
          </div>
        </form>
      </div>
    </div>
  );
};

// ── Add Student Modal (full version w/ hourly + initial classes) ────────
const ASAddStudent = ({ onClose }) => {
  const data = window.useAdminData();
  const defaultAvail = Object.fromEntries([0,1,2,3,4,5,6].map(i => [i, { enabled:false, blocks:[{from:9,to:17}] }]));
  const [form, setForm] = React.useState({
    name:'', email:'', phone:'', address:'', topic:'', notes:'',
    hourlyRate: 80, initialClasses: 0,
    availability: defaultAvail, availabilityNote:'',
    isOnline: false, meetingLink: '',
    // v56: when true, no magic-link email fires after creation. Used to
    // spin up experimental student accounts without spamming the real
    // owner of that email. Default unchecked → original behavior.
    skipMagicLink: false,
  });
  const [busy, setBusy] = React.useState(false);
  const [err, setErr]   = React.useState('');
  const [created, setCreated] = React.useState(null);
  // New student picks up the admin's detected zone by default. We persist
  // it to profiles.timezone right after createStudent returns the new ID.
  const [tz, setTz] = React.useState(() => window.Calendar.time.detect());

  const set = (k,v) => setForm(f => ({...f, [k]:v}));
  const fld = { width:'100%', padding:'12px 14px', borderRadius:8, border:'1.5px solid oklch(88% 0.015 265)', fontSize:16, minHeight:44, fontFamily:"'Plus Jakarta Sans', sans-serif", color:'oklch(22% 0.06 265)', background:'#fff', outline:'none', boxSizing:'border-box' };
  const lbl = { display:'block', fontSize:10, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'oklch(52% 0.04 265)', marginBottom:5 };

  const STD_SUBJECTS = ['Piano','Guitar','Violin','Vocals','Drums','Bass','Saxophone','Cello','Flute','Ukulele','Trumpet','Drawing','Painting','Photography','Ballet','Hip Hop','Yoga','Tennis','Boxing','Acting'];

  const submit = async (e) => {
    e.preventDefault();
    if (!form.name.trim() || !form.email.trim()) { setErr('Name and email are required.'); return; }
    const phoneE164 = form.phone.trim().replace(/[\s\-().]/g, '');
    if (!/^\+[1-9]\d{6,14}$/.test(phoneE164)) {
      setErr('Enter the student’s phone with country code, e.g. +961 70 123 456 or +1 212 555 0123 — the teacher calls this number (masked).');
      return;
    }
    setBusy(true); setErr('');
    try {
      const res = await data.createStudent({
        name:    form.name.trim(),
        email:   form.email.trim(),
        phone:   phoneE164,
        address: form.address.trim(),
        topic:   form.topic,
        notes:   form.notes.trim(),
        hourlyRate:    form.hourlyRate,
        initialClasses: form.initialClasses,
        availability:  form.availability,
        availabilityNote: form.availabilityNote.trim(),
        isOnline:    form.isOnline,
        meetingLink: form.isOnline ? form.meetingLink.trim() : '',
        skipMagicLink: !!form.skipMagicLink,
      });
      if (res?.phoneWarning) console.warn('[admin students] call-number mirror:', res.phoneWarning);
      // Persist timezone on the new profile (RLS: admin can write any row).
      if (res?.id) {
        try { await window.supa.from('profiles').update({ timezone: tz }).eq('id', res.id); }
        catch (e) { console.warn('[admin students] tz save failed', e); }
      }
      // When the admin asked us NOT to fire a magic link, skip the
      // MagicLinkPostCreate modal (it auto-sends on mount). Close the
      // Add Student modal and refresh — the row appears in the list and
      // will carry the amber "No invite sent" chip until later.
      if (form.skipMagicLink) {
        onClose();
        return;
      }
      setCreated({ name: form.name.trim(), email: res.email, id: res.id });
    } catch (e2) { setErr(window.friendlyError(e2, 'Could not add student')); }
    finally { setBusy(false); }
  };

  if (created) return <window.MagicLinkPostCreate name={created.name} email={created.email} studentId={created.id} onClose={onClose} />;

  return (
    <div style={{ position:'fixed', inset:0, background:'rgba(10,12,24,0.4)', display:'flex', alignItems:'center', justifyContent:'center', zIndex:9000 }} onClick={onClose}>
      <div style={{ background:'#fff', borderRadius:14, padding:'26px', width:580, maxHeight:'92vh', overflowY:'auto', boxShadow:'0 20px 60px rgba(0,0,0,0.18)', fontFamily:"'Plus Jakarta Sans', sans-serif" }} onClick={e=>e.stopPropagation()}>
        <div style={{ fontWeight:700, fontSize:16, color:'oklch(18% 0.03 265)', marginBottom:4 }}>Add a student</div>
        <div style={{ fontSize:12, color:'oklch(58% 0.03 265)', marginBottom:16 }}>Email is the login (magic link). Hourly rate is what the student pays you.</div>
        <form onSubmit={submit}>
          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12, marginBottom:14 }}>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Full name *</label>
              <input value={form.name} onChange={e=>set('name', e.target.value)} placeholder="Alex Johnson" required style={fld} />
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Email * (login)</label>
              <input type="email" value={form.email} onChange={e=>set('email', e.target.value)} placeholder="alex@example.com" required style={fld} />
            </div>
            <div style={{ gridColumn:'1/-1', background:'oklch(98% 0.005 265)', borderRadius:8, padding:'10px 12px', display:'flex', alignItems:'flex-start', gap:10 }}>
              <input type="checkbox" id="addStudentSkipMagic" checked={!!form.skipMagicLink} onChange={e=>set('skipMagicLink', e.target.checked)} style={{ width:16, height:16, marginTop:2, accentColor:'oklch(22% 0.06 265)', flexShrink:0 }} />
              <label htmlFor="addStudentSkipMagic" style={{ fontSize:13, color:'oklch(28% 0.05 265)', cursor:'pointer', fontWeight:600, lineHeight:1.4 }}>
                Don't send the magic link initially
                <div style={{ fontSize:11, color:'oklch(55% 0.03 265)', fontWeight:500, marginTop:2 }}>
                  Create the row without firing an invite email. Useful for test accounts. You can send the invite later from the student card.
                </div>
              </label>
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Phone * (teacher calls this number)</label>
              <window.PhoneInput value={form.phone} onChange={v=>set('phone', v)} fieldStyle={fld} />
              <div style={{ fontSize:11, color:'oklch(55% 0.03 265)', marginTop:4, lineHeight:1.45 }}>Pick the country (defaults to US), then type the number. The teacher reaches the student on a masked line — the student never has to add it themselves.</div>
            </div>
            <div>
              <label style={lbl}>Topic</label>
              <select value={form.topic} onChange={e=>set('topic', e.target.value)} style={fld}>
                <option value="">— None —</option>
                {STD_SUBJECTS.map(s => <option key={s} value={s}>{s}</option>)}
              </select>
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Address</label>
              <input value={form.address} onChange={e=>set('address', e.target.value)} placeholder="245 W 72nd St, New York, NY" style={fld} />
            </div>
            <div style={{ gridColumn:'1/-1', background:'oklch(98% 0.005 265)', borderRadius:8, padding:'10px 12px', display:'flex', alignItems:'center', gap:10 }}>
              <input type="checkbox" id="addStudentOnline" checked={!!form.isOnline} onChange={e=>set('isOnline', e.target.checked)} style={{ width:16, height:16, accentColor:'oklch(22% 0.06 265)' }} />
              <label htmlFor="addStudentOnline" style={{ fontSize:13, color:'oklch(28% 0.05 265)', cursor:'pointer', fontWeight:600 }}>💻 Online lessons (Zoom / Meet etc.)</label>
            </div>
            {form.isOnline && (
              <div style={{ gridColumn:'1/-1' }}>
                <label style={lbl}>Permanent meeting link</label>
                <input type="url" value={form.meetingLink} onChange={e=>set('meetingLink', e.target.value)} placeholder="https://meet.google.com/abc-defg-hij  or  https://zoom.us/j/123456789" style={fld} />
                <div style={{ fontSize:10, color:'oklch(60% 0.03 265)', marginTop:3 }}>This student's permanent room. Every lesson uses it — shown to the student and their instructor, joined automatically by the recorder, and linked in reminder emails. Paste a Google Meet or Zoom URL.</div>
              </div>
            )}
            <div>
              <label style={lbl}>Hourly rate ($/hr) *</label>
              <input type="number" min={0} max={500} value={form.hourlyRate} onChange={e=>set('hourlyRate', e.target.value)} required style={fld} />
            </div>
            <div>
              <label style={lbl}>Initial classes</label>
              <input type="number" min={0} max={99} value={form.initialClasses} onChange={e=>set('initialClasses', e.target.value)} style={fld} />
              <div style={{ fontSize:10, color:'oklch(60% 0.03 265)', marginTop:3 }}>0 = free first lesson, then needs recharge</div>
            </div>
            <div style={{ gridColumn:'1/-1' }}>
              <label style={lbl}>Admin notes</label>
              <textarea value={form.notes} onChange={e=>set('notes', e.target.value)} rows={2} placeholder="Referral source, scheduling preferences, etc." style={{...fld, resize:'vertical', fontFamily:"'Plus Jakarta Sans', sans-serif"}} />
            </div>
          </div>

          <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.07em', color:'oklch(52% 0.04 265)', marginBottom:8, paddingTop:12, borderTop:'1px solid oklch(92% 0.01 265)' }}>Availability (optional)</div>
          <div style={{ marginBottom:18 }}>
            <window.AvailabilityPicker value={form.availability} onChange={v => set('availability', v)} compact timezone={tz} onTimezoneChange={setTz} />
          </div>

          {err && <div style={{ background:'oklch(95% 0.06 25)', color:'oklch(40% 0.15 25)', padding:'9px 12px', borderRadius:8, fontSize:12, marginBottom:12 }}>{err}</div>}
          <div style={{ display:'flex', gap:10 }}>
            <button type="submit" disabled={busy} style={{ flex:1, background:'oklch(22% 0.06 265)', color:'#fff', border:'none', borderRadius:9, padding:'12px 0', fontWeight:600, fontSize:14, cursor:busy?'wait':'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif", opacity:busy?0.7:1 }}>
              {busy ? 'Creating…' : 'Add student'}
            </button>
            <button type="button" onClick={onClose} style={{ padding:'12px 18px', background:'oklch(95% 0.01 265)', border:'none', borderRadius:9, fontSize:14, cursor:'pointer', color:'oklch(45% 0.04 265)', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>Cancel</button>
          </div>
        </form>
      </div>
    </div>
  );
};

// ── Per-student class history (expanded view) ───────────────────────────


Object.assign(window, {
  ASConfirmDelete,
  ASRechargeModal,
  ASEditStudent,
  ASAddStudent,
  // Legacy alias for admin-view-as.jsx surfaces.
  AdminEditStudentModal: ASEditStudent,
});
