// admin-reminders.jsx — Global reminder editor (admin tab).
//
// Two content templates (student + teacher) drive every reminder email
// on the platform. A short list of schedules controls WHEN each
// template fires. Backed by global_reminder_templates +
// global_reminder_schedules (v41-schema.sql).
//
// Constants + pure helpers live in admin-reminders-helpers.js (loaded
// before this file in index.html). This file is the React component.

const AdminReminders = () => {
  // Pull globals once at render-time so the inner JSX stays readable.
  const AR_TIME_BEFORE_OPTIONS = window.AR_TIME_BEFORE_OPTIONS;
  const AR_PLACEHOLDERS        = window.AR_PLACEHOLDERS;
  const AR_DEFAULT_TEMPLATE    = window.AR_DEFAULT_TEMPLATE;
  const arFillPlaceholders     = window.arFillPlaceholders;
  const arInsertAtCursor       = window.arInsertAtCursor;
  const [templates, setTemplates] = React.useState(null); // { student: {...}, teacher: {...} }
  const [schedules, setSchedules] = React.useState(null); // [{ id, recipient, minutes_before, enabled }]
  const [busy, setBusy]           = React.useState(false);
  const [err, setErr]             = React.useState('');
  const [saveOk, setSaveOk]       = React.useState('');
  const [activeTab, setActiveTab] = React.useState('student');

  // Refs to the contenteditable editors. Chip insert uses these directly.
  const subjectRefs = React.useRef({});
  const bodyRefs    = React.useRef({});
  // Track which contenteditable was focused last so a chip inserts there.
  const lastFocusedRef = React.useRef({ recipient: 'student', field: 'body' });

  const reload = React.useCallback(async () => {
    setErr('');
    const [tplRes, schedRes] = await Promise.all([
      window.supa.from('global_reminder_templates').select('*'),
      window.supa.from('global_reminder_schedules').select('*').order('recipient').order('minutes_before'),
    ]);
    if (tplRes.error)  { setErr(tplRes.error.message);  return; }
    if (schedRes.error){ setErr(schedRes.error.message); return; }

    const byRecipient = { student: null, teacher: null };
    for (const row of tplRes.data || []) byRecipient[row.recipient] = { ...row };
    for (const r of ['student','teacher']) {
      if (!byRecipient[r]) byRecipient[r] = { recipient: r, ...AR_DEFAULT_TEMPLATE(r), _new: true };
    }
    setTemplates(byRecipient);
    setSchedules(schedRes.data || []);
  }, []);

  React.useEffect(() => { reload(); }, [reload]);

  const updateTpl = (recipient, patch) =>
    setTemplates(t => ({ ...t, [recipient]: { ...t[recipient], ...patch, _dirty: true } }));

  const updateSched = (idx, patch) =>
    setSchedules(rs => rs.map((r, i) => i === idx ? { ...r, ...patch, _dirty: true } : r));

  const addSched = (recipient) => setSchedules(rs => [...(rs || []), {
    id: 'new-' + Date.now() + '-' + Math.random().toString(36).slice(2,6),
    recipient: recipient || 'student', minutes_before: 60, enabled: true,
    _dirty: true, _new: true,
  }]);

  const removeSched = async (idx) => {
    const r = schedules[idx];
    if (r._new) { setSchedules(rs => rs.filter((_,i) => i !== idx)); return; }
    if (!window.confirm('Delete this schedule? Reminders at this time will stop firing.')) return;
    setBusy(true);
    const { error } = await window.supa.from('global_reminder_schedules').delete().eq('id', r.id);
    setBusy(false);
    if (error) { setErr(error.message); return; }
    setSchedules(rs => rs.filter((_,i) => i !== idx));
  };

  const saveAll = async () => {
    setBusy(true); setErr(''); setSaveOk('');
    try {
      for (const recipient of ['student','teacher']) {
        const t = templates[recipient];
        if (!t || !t._dirty) continue;
        const row = { recipient, subject: t.subject || 'Lesson reminder', body: t.body || '' };
        const { error } = await window.supa.from('global_reminder_templates').upsert(row, { onConflict: 'recipient' });
        if (error) throw error;
      }
      for (const s of schedules.filter(s => s._dirty)) {
        const row = { recipient: s.recipient, minutes_before: Number(s.minutes_before) || 60, enabled: s.enabled !== false };
        if (s._new) {
          const { error } = await window.supa.from('global_reminder_schedules').insert(row);
          if (error) throw error;
        } else {
          const { error } = await window.supa.from('global_reminder_schedules').update(row).eq('id', s.id);
          if (error) throw error;
        }
      }
      await reload();
      setSaveOk('Saved');
      setTimeout(() => setSaveOk(''), 2400);
    } catch (e) {
      setErr(e.message || 'Save failed');
    } finally { setBusy(false); }
  };

  const resetToDefault = (recipient) => {
    if (!window.confirm('Reset the ' + recipient + ' template to the default subject + body?')) return;
    updateTpl(recipient, AR_DEFAULT_TEMPLATE(recipient));
  };

  const insertPlaceholder = (token) => {
    const { recipient, field } = lastFocusedRef.current;
    const el = field === 'subject' ? subjectRefs.current[recipient] : bodyRefs.current[recipient];
    window.arInsertPillAtSelection(el, token);
    // After the pill is inserted, ARRichEditor's onInput will fire and
    // call its onChange → updateTpl, so no manual state push needed.
  };

  // Install pill styles once per page lifetime.
  React.useEffect(() => { window.arInstallPillStyles && window.arInstallPillStyles(); }, []);

  // ── Styles ────────────────────────────────────────────────────────
  const fld = { width:'100%', padding:'10px 12px', borderRadius:8, border:'1.5px solid oklch(88% 0.015 265)', fontSize:13, 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(56% 0.04 265)', marginBottom:5 };
  const card = { background:'#fff', borderRadius:14, border:'1px solid oklch(91% 0.01 265)', padding:'22px 26px', marginBottom:18, boxShadow:'0 2px 10px oklch(18% 0.06 265 / 0.05)' };
  const h2   = { fontFamily:"'Cormorant Garamond', serif", fontSize:20, fontWeight:600, color:'oklch(18% 0.03 265)', marginBottom:14 };
  const previewBox = { padding:'12px 14px', borderRadius:8, border:'1.5px solid oklch(92% 0.01 265)', background:'oklch(98% 0.005 265)', fontSize:13, lineHeight:1.55, color:'oklch(22% 0.06 265)', minHeight:200, overflow:'auto', boxSizing:'border-box' };
  const tabBtn = (active) => ({
    flex:'1 0 auto', padding:'11px 14px', textAlign:'center', cursor:'pointer', whiteSpace:'nowrap',
    fontWeight: active ? 700 : 500,
    fontSize:13,
    color: active ? 'oklch(22% 0.06 265)' : 'oklch(50% 0.03 265)',
    background: active ? '#fff' : 'transparent',
    borderBottom: active ? '2px solid oklch(22% 0.06 265)' : '2px solid transparent',
    fontFamily:"'Plus Jakarta Sans', sans-serif",
    transition:'all 150ms',
  });
  const chipBtn = { fontSize:11, fontWeight:600, padding:'4px 9px', borderRadius:999, border:'1px solid oklch(86% 0.02 265)', background:'oklch(98% 0.005 265)', color:'oklch(36% 0.05 265)', cursor:'pointer', fontFamily:'ui-monospace, SFMono-Regular, Menlo, monospace' };
  const monoArea = { ...fld, minHeight:240, resize:'vertical', lineHeight:1.55, fontFamily:'ui-monospace, SFMono-Regular, Menlo, monospace', fontSize:12.5 };

  // ── Sub-renders ───────────────────────────────────────────────────
  const renderChips = () => (
    <div style={{ display:'flex', flexWrap:'wrap', gap:6, marginBottom:10 }}>
      <span style={{ fontSize:11, color:'oklch(56% 0.03 265)', marginRight:4, alignSelf:'center' }}>Insert:</span>
      {AR_PLACEHOLDERS.map(p => (
        <button key={p} type="button" onClick={() => insertPlaceholder(p)} style={chipBtn} title={'Insert {' + p + '} at cursor'}>
          {'{' + p + '}'}
        </button>
      ))}
    </div>
  );

  const renderTemplateTab = (recipient) => {
    const t = templates[recipient];
    return (
      <div style={card}>
        <div style={{ display:'flex', alignItems:'baseline', justifyContent:'space-between', marginBottom:14 }}>
          <div style={h2}>{recipient === 'student' ? 'Student email' : 'Teacher email'}</div>
          <button type="button" onClick={() => resetToDefault(recipient)}
            style={{ fontSize:11, fontWeight:600, color:'oklch(50% 0.03 265)', background:'transparent', border:'none', cursor:'pointer', textDecoration:'underline', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>
            Reset to default
          </button>
        </div>

        <div style={{ marginBottom:14 }}>
          <label style={lbl}>Subject</label>
          <window.ARRichEditor
            editorRef={(el) => { subjectRefs.current[recipient] = el; }}
            value={t.subject || ''}
            onChange={(html) => updateTpl(recipient, { subject: html })}
            onFocus={() => { lastFocusedRef.current = { recipient, field: 'subject' }; }}
            placeholder="e.g. Reminder · Your lesson in 1 hour"
            singleLine={true}
          />
          <div style={{ marginTop:6, fontSize:11, color:'oklch(56% 0.03 265)' }}>
            Renders as: <span style={{ color:'oklch(22% 0.06 265)' }}>{arFillPlaceholders(t.subject || '')}</span>
          </div>
        </div>

        {renderChips()}

        <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:14 }}>
          <div>
            <label style={lbl}>Body</label>
            <window.ARRichEditor
              editorRef={(el) => { bodyRefs.current[recipient] = el; }}
              value={t.body || ''}
              onChange={(html) => updateTpl(recipient, { body: html })}
              onFocus={() => { lastFocusedRef.current = { recipient, field: 'body' }; }}
              placeholder="Type your reminder message…"
              singleLine={false}
            />
          </div>
          <div>
            <label style={lbl}>Live preview</label>
            <div style={previewBox} dangerouslySetInnerHTML={{ __html: arFillPlaceholders(t.body || '') }} />
          </div>
        </div>
      </div>
    );
  };

  const renderSchedulesTab = () => {
    const groups = ['student','teacher'];
    return (
      <div style={card}>
        <div style={h2}>When to send</div>
        <div style={{ fontSize:12, color:'oklch(56% 0.03 265)', marginBottom:14, lineHeight:1.5 }}>
          Each enabled schedule fires once per booking at the chosen time before the lesson. The cron runs every 30 min, so the earliest accurate cadence is 30 min before.
        </div>
        {groups.map(g => {
          const rows = (schedules || []).map((s, i) => ({ s, i })).filter(x => x.s.recipient === g);
          return (
            <div key={g} style={{ marginBottom:18 }}>
              <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'0.06em', color:'oklch(40% 0.04 265)', marginBottom:8 }}>
                {g === 'student' ? 'Student reminders' : 'Teacher reminders'}
              </div>
              {rows.length === 0 ? (
                <div style={{ fontSize:12, color:'oklch(60% 0.03 265)', fontStyle:'italic', padding:'8px 0 12px' }}>No {g} reminders configured.</div>
              ) : (
                <div style={{ display:'flex', flexDirection:'column', gap:6 }}>
                  {rows.map(({ s: r, i }) => (
                    <div key={r.id} style={{
                      display:'grid', gridTemplateColumns:'1fr auto auto', gap:10, alignItems:'center',
                      padding:'8px 12px', background:'oklch(98% 0.005 265)', border:'1px solid oklch(92% 0.01 265)', borderRadius:10,
                      opacity: r.enabled === false ? 0.55 : 1,
                    }}>
                      <select value={r.minutes_before} onChange={e => updateSched(i, { minutes_before: Number(e.target.value) })} style={fld}>
                        {AR_TIME_BEFORE_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
                      </select>
                      <label style={{ display:'flex', alignItems:'center', gap:6, fontSize:12, color:'oklch(40% 0.04 265)', cursor:'pointer', whiteSpace:'nowrap' }}>
                        <input type="checkbox" checked={r.enabled !== false} onChange={e => updateSched(i, { enabled: e.target.checked })} style={{ accentColor:'oklch(22% 0.06 265)' }} />
                        On
                      </label>
                      <button onClick={() => removeSched(i)} disabled={busy} title="Delete"
                        style={{ background:'oklch(96% 0.04 25)', color:'oklch(40% 0.18 25)', border:'1px solid oklch(88% 0.05 25)', borderRadius:8, padding:'6px 10px', fontSize:12, fontWeight:600, cursor:busy?'wait':'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>×</button>
                    </div>
                  ))}
                </div>
              )}
              <button onClick={() => addSched(g)}
                style={{ marginTop:8, background:'#fff', border:'1.5px dashed oklch(78% 0.02 265)', borderRadius:10, padding:'8px 0', width:'100%', fontSize:12, fontWeight:600, color:'oklch(36% 0.05 265)', cursor:'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif" }}>
                + Add {g} reminder time
              </button>
            </div>
          );
        })}
      </div>
    );
  };

  // The Recent-sends tab is a self-contained child (admin-reminders-log.jsx):
  // it owns its own paging, live subscription, timezone, and test-send action.

  const dirty = (templates && (templates.student?._dirty || templates.teacher?._dirty))
             || (schedules && schedules.some(s => s._dirty));

  return (
    <div style={{ maxWidth:920, margin:'0 auto', paddingBottom:90 }}>
      <div style={{ ...card, paddingBottom:0 }}>
        <div style={{ fontFamily:"'Cormorant Garamond', serif", fontSize:22, fontWeight:600, color:'oklch(18% 0.03 265)', marginBottom:14 }}>Booking reminders</div>
        <div style={{ display:'flex', overflowX:'auto', borderBottom:'1px solid oklch(91% 0.01 265)', marginLeft:-26, marginRight:-26 }}>
          <div style={tabBtn(activeTab === 'student')}  onClick={() => setActiveTab('student')}>Student email</div>
          <div style={tabBtn(activeTab === 'teacher')}  onClick={() => setActiveTab('teacher')}>Teacher email</div>
          <div style={tabBtn(activeTab === 'sched')}    onClick={() => setActiveTab('sched')}>Schedules</div>
          <div style={tabBtn(activeTab === 'avail')}    onClick={() => setActiveTab('avail')}>Weekly nudge</div>
          <div style={tabBtn(activeTab === 'upcoming')} onClick={() => setActiveTab('upcoming')}>Upcoming</div>
          <div style={tabBtn(activeTab === 'log')}      onClick={() => setActiveTab('log')}>Recent sends</div>
        </div>
      </div>

      {!templates || !schedules ? (
        <div style={{ background:'#fff', borderRadius:12, padding:'24px', textAlign:'center', color:'oklch(60% 0.03 265)' }}>Loading…</div>
      ) : (
        <React.Fragment>
          {activeTab === 'student' && renderTemplateTab('student')}
          {activeTab === 'teacher' && renderTemplateTab('teacher')}
          {activeTab === 'sched'   && renderSchedulesTab()}
          {activeTab === 'avail'   && <window.AdminRemindersAvailability />}
          {activeTab === 'upcoming' && <window.AdminRemindersUpcoming schedules={schedules} />}
          {activeTab === 'log'     && <window.AdminRemindersLog schedules={schedules} />}
        </React.Fragment>
      )}

      {/* Sticky save bar — only on the Student/Teacher/Schedules tabs. The
          Recent-sends log, Weekly-nudge editor, and Upcoming forecast carry
          their own controls (or none). */}
      {activeTab !== 'log' && activeTab !== 'avail' && activeTab !== 'upcoming' && (
        <div style={{
          position:'sticky', bottom:0, marginTop:18,
          background:'rgba(255,255,255,0.96)', backdropFilter:'blur(8px)',
          borderTop:'1px solid oklch(91% 0.01 265)',
          padding:'12px 0', marginLeft:-2, marginRight:-2,
        }}>
          {err    && <div style={{ fontSize:13, color:'oklch(40% 0.15 25)',  marginBottom:10, padding:'10px 14px', background:'oklch(96% 0.06 25)',  borderRadius:8 }}>{err}</div>}
          {saveOk && <div style={{ fontSize:13, color:'oklch(28% 0.13 150)', marginBottom:10, fontWeight:600 }}>{saveOk}</div>}

          <div style={{ display:'flex', gap:12, alignItems:'center' }}>
            <div style={{ flex:1, fontSize:12, color: dirty ? 'oklch(40% 0.18 25)' : 'oklch(56% 0.03 265)' }}>
              {dirty ? 'You have unsaved changes.' : 'All changes saved.'}
            </div>
            <button onClick={saveAll} disabled={busy || !templates || !schedules || !dirty}
              style={{ background: dirty ? 'oklch(22% 0.06 265)' : 'oklch(70% 0.02 265)', color:'#fff', border:'none', borderRadius:10, padding:'12px 22px', fontWeight:600, fontSize:14, cursor:(busy||!dirty)?'wait':'pointer', fontFamily:"'Plus Jakarta Sans', sans-serif", opacity:busy?0.7:1 }}>
              {busy ? 'Saving…' : 'Save changes'}
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

window.AdminReminders = AdminReminders;
