// admin-gcal-imports.jsx — Admin tab: "Google imports".
//
// v88 syncs events from a teacher's connected Google Calendar INTO Mastery as
// availability *blocks* (busy time). Many teachers run their schedule on Google
// and those events are really lessons. This tab lists every imported block and
// lets the admin convert one into a real billable booking — picking an existing
// Mastery student OR creating an off-platform "guest" student (name only, no
// login account). Once converted it behaves like any lesson: it shows in the
// teacher's earnings, can be marked paid, etc.
//
// Backed by v118 RPCs: admin_gcal_list_imports() + admin_gcal_convert_block_to_lesson(...).

const GI_INK   = 'oklch(22% 0.06 265)';
const GI_MUTED = 'oklch(50% 0.03 265)';
const GI_BLUE  = 'oklch(40% 0.14 235)';

const giNum = (v) => {
  if (v === '' || v === null || v === undefined) return null;
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
};

// "Sun, May 31 · 2:00–3:00 PM" in the viewer's local timezone.
const giFmtRange = (startIso, endIso) => {
  try {
    const s = new Date(startIso);
    const e = new Date(endIso);
    const day = s.toLocaleDateString(undefined, { weekday: 'short', month: 'short', day: 'numeric' });
    const t = (d) => d.toLocaleTimeString(undefined, { hour: 'numeric', minute: '2-digit' });
    return `${day} · ${t(s)}–${t(e)}`;
  } catch (_) { return startIso || '—'; }
};

const giIsPast = (iso) => { try { return new Date(iso).getTime() < Date.now(); } catch (_) { return false; } };

// ── Convert modal ──────────────────────────────────────────────────────────
const GIConvertModal = ({ row, onClose, onConverted }) => {
  const [mode, setMode]   = React.useState('guest'); // 'guest' | 'existing'
  const [guestName, setGuestName] = React.useState('');
  // existing-student search
  const [query, setQuery] = React.useState('');
  const [matches, setMatches] = React.useState([]);
  const [chosen, setChosen]   = React.useState(null); // {id, full_name}
  const [searching, setSearching] = React.useState(false);
  // money
  const defaultRate = (row.instructor_rate != null ? String(row.instructor_rate) : '');
  const [studentRate, setStudentRate] = React.useState(defaultRate);
  const [teacherRate, setTeacherRate] = React.useState(defaultRate);
  const [paid, setPaid] = React.useState(false);
  const [method, setMethod] = React.useState('cash');

  const [saving, setSaving] = React.useState(false);
  const [error, setError]   = React.useState(null);

  // Debounced existing-student search against profiles (admin can read via RLS).
  React.useEffect(() => {
    if (mode !== 'existing') return;
    const q = query.trim();
    if (q.length < 2) { setMatches([]); return; }
    let live = true;
    setSearching(true);
    const t = setTimeout(async () => {
      try {
        const { data, error: e } = await window.supa
          .from('profiles')
          .select('id, full_name, is_guest')
          .eq('role', 'student')
          .ilike('full_name', `%${q}%`)
          .order('full_name')
          .limit(8);
        if (e) throw e;
        if (live) setMatches(data || []);
      } catch (_) {
        if (live) setMatches([]);
      } finally {
        if (live) setSearching(false);
      }
    }, 280);
    return () => { live = false; clearTimeout(t); };
  }, [query, mode]);

  const canSave = mode === 'guest'
    ? guestName.trim().length > 0
    : !!chosen;

  const submit = async () => {
    if (!canSave || saving) return;
    setSaving(true); setError(null);
    try {
      const { data, error: e } = await window.supa.rpc('admin_gcal_convert_block_to_lesson', {
        p_block_id:            row.block_id,
        p_existing_student_id: mode === 'existing' ? chosen.id : null,
        p_guest_name:          mode === 'guest' ? guestName.trim() : null,
        p_student_rate:        giNum(studentRate),
        p_teacher_rate:        giNum(teacherRate),
        p_paid:                !!paid,
        p_payment_method:      method || null,
      });
      if (e) throw e;
      onConverted && onConverted(row.block_id, data);
    } catch (e) {
      setError(window.friendlyError ? window.friendlyError(e, 'Could not convert') : (e.message || String(e)));
      setSaving(false);
    }
  };

  const label = { display: 'block', fontSize: 12, fontWeight: 700, color: GI_MUTED, textTransform: 'uppercase', letterSpacing: '0.04em', margin: '0 0 6px' };
  const input = { width: '100%', padding: '10px 12px', borderRadius: 9, border: '1px solid oklch(88% 0.02 265)', fontSize: 14, boxSizing: 'border-box' };
  const tab = (active) => ({
    flex: 1, padding: '9px 10px', borderRadius: 9, border: active ? `1px solid ${GI_BLUE}` : '1px solid oklch(90% 0.02 265)',
    background: active ? 'oklch(96% 0.03 235)' : '#fff', color: active ? GI_BLUE : GI_MUTED,
    fontWeight: 700, fontSize: 13, cursor: 'pointer',
  });

  return (
    <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.45)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}>
      <div onClick={(e) => e.stopPropagation()} style={{ background: '#fff', borderRadius: 14, padding: 22, maxWidth: 460, width: '100%', maxHeight: '90vh', overflowY: 'auto' }}>
        <h3 style={{ margin: '0 0 4px', fontFamily: 'Georgia, serif', fontWeight: 600, fontSize: 19, color: GI_INK }}>Convert to a lesson</h3>
        <p style={{ margin: '0 0 4px', fontSize: 14, color: GI_INK, fontWeight: 600 }}>{row.title}</p>
        <p style={{ margin: '0 0 16px', fontSize: 13, color: GI_MUTED }}>
          {row.instructor_name} · {giFmtRange(row.start_at, row.end_at)}
          {giIsPast(row.start_at) ? ' · past lesson' : ' · upcoming'}
        </p>

        {/* student */}
        <label style={label}>Student</label>
        <div style={{ display: 'flex', gap: 8, marginBottom: 12 }}>
          <button onClick={() => setMode('guest')} style={tab(mode === 'guest')}>New (off-platform)</button>
          <button onClick={() => setMode('existing')} style={tab(mode === 'existing')}>Existing student</button>
        </div>

        {mode === 'guest' ? (
          <input autoFocus value={guestName} onChange={(e) => setGuestName(e.target.value)}
                 placeholder="Student's name (e.g. Sarah Lee)" style={{ ...input, marginBottom: 16 }} />
        ) : (
          <div style={{ marginBottom: 16 }}>
            {chosen ? (
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '10px 12px', borderRadius: 9, background: 'oklch(96% 0.03 145)', border: '1px solid oklch(86% 0.08 145)' }}>
                <span style={{ fontSize: 14, fontWeight: 600, color: GI_INK }}>{chosen.full_name}</span>
                <button onClick={() => { setChosen(null); setQuery(''); }} style={{ background: 'none', border: 'none', color: GI_MUTED, cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>Change</button>
              </div>
            ) : (
              <>
                <input autoFocus value={query} onChange={(e) => setQuery(e.target.value)}
                       placeholder="Search students by name…" style={input} />
                {searching && <div style={{ fontSize: 12, color: GI_MUTED, marginTop: 6 }}>Searching…</div>}
                {!searching && query.trim().length >= 2 && matches.length === 0 && (
                  <div style={{ fontSize: 12, color: GI_MUTED, marginTop: 6 }}>No match. Use “New (off-platform)” for a student without an account.</div>
                )}
                {matches.length > 0 && (
                  <div style={{ marginTop: 6, border: '1px solid oklch(91% 0.02 265)', borderRadius: 9, overflow: 'hidden' }}>
                    {matches.map((m) => (
                      <button key={m.id} onClick={() => setChosen(m)} style={{ display: 'block', width: '100%', textAlign: 'left', padding: '9px 12px', background: '#fff', border: 'none', borderBottom: '1px solid oklch(95% 0.01 265)', cursor: 'pointer', fontSize: 14, color: GI_INK }}>
                        {m.full_name}{m.is_guest ? <span style={{ color: GI_MUTED, fontSize: 12 }}> · guest</span> : null}
                      </button>
                    ))}
                  </div>
                )}
              </>
            )}
          </div>
        )}

        {/* money */}
        <div style={{ display: 'flex', gap: 10, marginBottom: 14 }}>
          <div style={{ flex: 1 }}>
            <label style={label}>Student rate</label>
            <input type="number" inputMode="decimal" value={studentRate} onChange={(e) => setStudentRate(e.target.value)} placeholder="0" style={input} />
          </div>
          <div style={{ flex: 1 }}>
            <label style={label}>Teacher rate</label>
            <input type="number" inputMode="decimal" value={teacherRate} onChange={(e) => setTeacherRate(e.target.value)} placeholder="0" style={input} />
          </div>
        </div>

        <div style={{ display: 'flex', gap: 10, marginBottom: 18, alignItems: 'flex-end' }}>
          <div style={{ flex: 1 }}>
            <label style={label}>Payment</label>
            <select value={method} onChange={(e) => setMethod(e.target.value)} style={{ ...input, padding: '10px 12px' }}>
              <option value="cash">Cash</option>
              <option value="platform">Paid on platform</option>
              <option value="">Unspecified</option>
            </select>
          </div>
          <label style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8, fontSize: 14, color: GI_INK, fontWeight: 600, padding: '10px 0', cursor: 'pointer' }}>
            <input type="checkbox" checked={paid} onChange={(e) => setPaid(e.target.checked)} style={{ width: 17, height: 17 }} />
            Already paid
          </label>
        </div>

        {error && <div style={{ background: 'oklch(95% 0.06 25)', color: 'oklch(40% 0.15 25)', padding: '9px 12px', borderRadius: 9, fontSize: 13, marginBottom: 14 }}>{error}</div>}

        <div style={{ display: 'flex', gap: 10, justifyContent: 'flex-end' }}>
          <button onClick={onClose} disabled={saving} style={{ padding: '10px 16px', borderRadius: 9, border: '1px solid oklch(88% 0.02 265)', background: '#fff', color: GI_MUTED, fontWeight: 600, fontSize: 14, cursor: 'pointer' }}>Cancel</button>
          <button onClick={submit} disabled={!canSave || saving} style={{ padding: '10px 18px', borderRadius: 9, border: 'none', background: canSave && !saving ? GI_INK : 'oklch(80% 0.02 265)', color: '#fff', fontWeight: 700, fontSize: 14, cursor: canSave && !saving ? 'pointer' : 'not-allowed' }}>
            {saving ? 'Converting…' : 'Create lesson'}
          </button>
        </div>
      </div>
    </div>
  );
};

// ── Tab ──────────────────────────────────────────────────────────────────
const AdminGcalImports = () => {
  const [rows, setRows] = React.useState(null); // null = loading
  const [error, setError] = React.useState(null);
  const [active, setActive] = React.useState(null); // row being converted
  const [toast, setToast] = React.useState(null);

  const load = React.useCallback(async () => {
    setError(null);
    try {
      const { data, error: e } = await window.supa.rpc('admin_gcal_list_imports');
      if (e) throw e;
      setRows(data || []);
    } catch (e) {
      setError(window.friendlyError ? window.friendlyError(e, 'Could not load imports') : (e.message || String(e)));
      setRows([]);
    }
  }, []);

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

  const onConverted = (blockId) => {
    setRows((r) => (r || []).filter((x) => x.block_id !== blockId));
    setActive(null);
    setToast('Lesson created — it now shows in the teacher’s schedule & billing.');
    setTimeout(() => setToast(null), 4000);
  };

  const wrap = { maxWidth: 860, margin: '0 auto' };

  return (
    <div style={wrap}>
      <div style={{ display: 'flex', alignItems: 'flex-start', justifyContent: 'space-between', gap: 12, marginBottom: 6 }}>
        <h2 style={{ margin: 0, fontFamily: 'Georgia, serif', fontWeight: 600, fontSize: 24, color: GI_INK }}>Google imports</h2>
        <button onClick={() => { setRows(null); load(); }} style={{ padding: '8px 14px', borderRadius: 9, border: '1px solid oklch(88% 0.02 265)', background: '#fff', color: GI_MUTED, fontWeight: 600, fontSize: 13, cursor: 'pointer', whiteSpace: 'nowrap' }}>Refresh</button>
      </div>
      <p style={{ margin: '0 0 20px', fontSize: 14, color: GI_MUTED, lineHeight: 1.5 }}>
        Events from teachers’ connected Google Calendars sync in here as blocked time within ~5 minutes. If an event is actually a lesson, convert it into a real booking — it then shows in the teacher’s schedule and earnings and can be marked paid. Students without a Mastery account are added as off-platform guests.
      </p>

      {toast && (
        <div style={{ background: 'oklch(95% 0.06 145)', color: 'oklch(34% 0.13 145)', padding: '11px 14px', borderRadius: 10, fontSize: 14, fontWeight: 600, marginBottom: 16 }}>{toast}</div>
      )}
      {error && (
        <div style={{ background: 'oklch(95% 0.06 25)', color: 'oklch(40% 0.15 25)', padding: '11px 14px', borderRadius: 10, fontSize: 14, marginBottom: 16 }}>{error}</div>
      )}

      {rows === null ? (
        <div style={{ color: GI_MUTED, fontSize: 14, padding: '30px 0' }}>Loading…</div>
      ) : rows.length === 0 ? (
        <div style={{ textAlign: 'center', padding: '48px 20px', background: 'oklch(98% 0.005 265)', borderRadius: 14, border: '1px dashed oklch(88% 0.02 265)' }}>
          <p style={{ margin: '0 0 4px', fontSize: 15, fontWeight: 600, color: GI_INK }}>No imported events waiting</p>
          <p style={{ margin: 0, fontSize: 13.5, color: GI_MUTED }}>When a teacher connects Google Calendar and adds an event, it shows up here within ~5 minutes.</p>
        </div>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          {rows.map((r) => (
            <div key={r.block_id} style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14, padding: '14px 16px', background: '#fff', border: '1px solid oklch(92% 0.015 265)', borderRadius: 12, flexWrap: 'wrap' }}>
              <div style={{ minWidth: 0, flex: '1 1 220px' }}>
                <div style={{ fontSize: 15, fontWeight: 600, color: GI_INK, overflow: 'hidden', textOverflow: 'ellipsis' }}>
                  <span style={{ color: GI_BLUE, fontWeight: 700, fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.04em', marginRight: 8 }}>from Google</span>
                  {r.title}
                </div>
                <div style={{ fontSize: 13, color: GI_MUTED, marginTop: 3 }}>
                  {r.instructor_name} · {giFmtRange(r.start_at, r.end_at)}{giIsPast(r.start_at) ? ' · past' : ''}
                </div>
              </div>
              <button onClick={() => setActive(r)} style={{ padding: '9px 16px', borderRadius: 9, border: 'none', background: GI_INK, color: '#fff', fontWeight: 700, fontSize: 13.5, cursor: 'pointer', whiteSpace: 'nowrap' }}>Convert to lesson</button>
            </div>
          ))}
        </div>
      )}

      {active && <GIConvertModal row={active} onClose={() => setActive(null)} onConverted={onConverted} />}
    </div>
  );
};

Object.assign(window, { AdminGcalImports });
