// src/features/admin/ui/admin-leads.jsx
//
// Admin "Teacher Leads" tab. Shows every teacher who replied to a Teacher
// Finder outreach, the conversation state the bot drove it to, the rate +
// availability it extracted, and the full SMS transcript. Lets an admin flip
// the global bot kill-switch and pause / resume / mark-dead individual leads.
//
// Data: window.ADMIN_DATA.teacherLeads (data-teacher-leads.js).
// Styling: reuses the TF_TONE palette from admin-teacher-finder.jsx (loaded
// before this file). Must load AFTER admin-teacher-finder.jsx (for TF_TONE)
// and BEFORE admin-dashboard.jsx (which renders <window.AdminLeads />).

// State -> { label, bg, text } badge config.
const LEAD_STATE_BADGE = {
  outreach_sent:         { label: 'Outreach sent',  bg: 'oklch(92% 0.03 265)', text: 'oklch(35% 0.04 265)' },
  greeted:               { label: 'Greeted',        bg: 'oklch(92% 0.03 265)', text: 'oklch(35% 0.04 265)' },
  awaiting_rate:         { label: 'Awaiting rate',   bg: 'oklch(90% 0.10 90)',  text: 'oklch(35% 0.10 80)' },
  awaiting_availability: { label: 'Awaiting avail.', bg: 'oklch(90% 0.10 90)',  text: 'oklch(35% 0.10 80)' },
  awaiting_location:     { label: 'Awaiting location', bg: 'oklch(90% 0.10 90)', text: 'oklch(35% 0.10 80)' },
  ready_for_review:      { label: 'Ready for review',bg: 'oklch(90% 0.12 145)', text: 'oklch(33% 0.12 145)' },
  opted_out:             { label: 'Opted out',       bg: 'oklch(90% 0.07 25)',  text: 'oklch(40% 0.15 25)' },
  dead:                  { label: 'Dead',            bg: 'oklch(88% 0.01 265)', text: 'oklch(45% 0.02 265)' },
  human_requested:       { label: 'Human requested', bg: 'oklch(88% 0.10 300)', text: 'oklch(38% 0.14 300)' },
  paused:                { label: 'Paused',          bg: 'oklch(90% 0.06 60)',  text: 'oklch(40% 0.10 60)' },
};

const LeadStateBadge = ({ state }) => {
  const cfg = LEAD_STATE_BADGE[state] || { label: state || '—', bg: TF_TONE.border, text: TF_TONE.muted };
  return (
    <span style={{
      display: 'inline-block', padding: '3px 9px', borderRadius: 999,
      fontSize: 10, fontWeight: 700, letterSpacing: '0.03em',
      background: cfg.bg, color: cfg.text, whiteSpace: 'nowrap',
    }}>{cfg.label}</span>
  );
};

function fmtRate(cents, raw) {
  if (cents != null) return `$${(cents / 100).toFixed(cents % 100 === 0 ? 0 : 2)}/hr`;
  if (raw) return raw;
  return '—';
}

function fmtWhen(iso) {
  if (!iso) return '—';
  const d = new Date(iso);
  if (isNaN(d)) return '—';
  return d.toLocaleString([], { month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit' });
}

function lastMessageAt(lead) {
  const msgs = lead.teacher_lead_messages || [];
  if (!msgs.length) return lead.updated_at || null;
  return msgs[msgs.length - 1].created_at;
}

// Global bot kill-switch. Confirms before turning ON.
const LeadBotKillSwitch = ({ enabled, onToggled }) => {
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');

  const toggle = async () => {
    const next = !enabled;
    if (next) {
      const ok = window.confirm(
        'Turn the lead bot ON?\n\nWhen on, every teacher who replies to an outreach text will get an automated reply asking their rate and availability. Click OK to enable.'
      );
      if (!ok) return;
    }
    setBusy(true); setErr('');
    try {
      const result = await window.ADMIN_DATA.teacherLeads.setBotEnabled(next);
      onToggled(result);
    } catch (e) {
      setErr(e.message || 'Toggle failed');
    } finally {
      setBusy(false);
    }
  };

  const on = !!enabled;
  return (
    <div style={{
      background: on ? TF_TONE.successBg : TF_TONE.dangerBg,
      border: `1px solid ${on ? TF_TONE.success : TF_TONE.danger}`,
      borderRadius: 14, padding: '14px 18px', marginBottom: 16,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14, flexWrap: 'wrap',
    }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: on ? TF_TONE.success : TF_TONE.danger, letterSpacing: '0.02em' }}>
          Lead bot is {on ? 'ENABLED' : 'OFF'}
        </div>
        <div style={{ fontSize: 11, color: TF_TONE.muted, marginTop: 3 }}>
          {on
            ? 'Teachers who reply get an automated text asking their rate, then availability. Once both are in, the lead is marked ready for review and the bot stops.'
            : 'No automated replies will be sent. Inbound texts are still recorded so you can read them here.'}
        </div>
        {err && <div style={{ fontSize: 11, color: TF_TONE.danger, marginTop: 4 }}>Error: {err}</div>}
      </div>
      <button
        onClick={toggle}
        disabled={busy}
        style={{
          flexShrink: 0,
          background: on ? TF_TONE.dangerBg : TF_TONE.success,
          color: on ? TF_TONE.danger : '#fff',
          border: 'none', borderRadius: 999, padding: '8px 16px',
          fontSize: 12, fontWeight: 700, cursor: busy ? 'wait' : 'pointer',
          fontFamily: "'Plus Jakarta Sans', sans-serif",
          letterSpacing: '0.04em', textTransform: 'uppercase',
        }}
      >{busy ? '…' : on ? 'Turn off' : 'Turn on'}</button>
    </div>
  );
};

// Telegram approval gate toggle. When ON, every bot reply is sent to Joe on
// Telegram to approve before it reaches the teacher. Default ON at rollout.
// `pendingCount` shows how many replies are currently awaiting his decision.
const ApprovalModeToggle = ({ approvalMode, pendingCount, onToggled }) => {
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');

  const toggle = async () => {
    const next = !approvalMode;
    if (!next) {
      const ok = window.confirm(
        'Turn OFF Telegram approval?\n\nThe bot will then send its replies to teachers automatically, without asking you first. Click OK to let it reply on its own.'
      );
      if (!ok) return;
    }
    setBusy(true); setErr('');
    try {
      const result = await window.ADMIN_DATA.teacherLeads.setApprovalMode(next);
      onToggled(result);
    } catch (e) {
      setErr(e.message || 'Toggle failed');
    } finally {
      setBusy(false);
    }
  };

  const on = !!approvalMode;
  return (
    <div style={{
      background: TF_TONE.card,
      border: `1px solid ${TF_TONE.border}`,
      borderRadius: 14, padding: '14px 18px', marginBottom: 16,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14, flexWrap: 'wrap',
    }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: TF_TONE.text, letterSpacing: '0.02em' }}>
          Approve replies on Telegram first {on ? '(ON)' : '(OFF)'}
        </div>
        <div style={{ fontSize: 11, color: TF_TONE.muted, marginTop: 3 }}>
          When on, every bot reply is sent to you on Telegram to approve before it goes to the teacher. Turn off later to let the bot reply on its own.
        </div>
        {on && pendingCount > 0 && (
          <div style={{ fontSize: 11, color: TF_TONE.text, marginTop: 4, fontWeight: 600 }}>
            {pendingCount} awaiting your approval on Telegram
          </div>
        )}
        {err && <div style={{ fontSize: 11, color: TF_TONE.danger, marginTop: 4 }}>Error: {err}</div>}
      </div>
      <button
        onClick={toggle}
        disabled={busy}
        style={{
          flexShrink: 0,
          background: on ? TF_TONE.dangerBg : TF_TONE.success,
          color: on ? TF_TONE.danger : '#fff',
          border: 'none', borderRadius: 999, padding: '8px 16px',
          fontSize: 12, fontWeight: 700, cursor: busy ? 'wait' : 'pointer',
          fontFamily: "'Plus Jakarta Sans', sans-serif",
          letterSpacing: '0.04em', textTransform: 'uppercase',
        }}
      >{busy ? '…' : on ? 'Turn off' : 'Turn on'}</button>
    </div>
  );
};

// Per-row action buttons.
const LeadActions = ({ lead, onChanged }) => {
  const [busy, setBusy] = React.useState('');
  const [err, setErr] = React.useState('');

  const run = async (op) => {
    setBusy(op); setErr('');
    try {
      const updated = await window.ADMIN_DATA.teacherLeads[op](lead.id);
      onChanged(updated);
    } catch (e) {
      setErr(e.message || 'Failed');
    } finally {
      setBusy('');
    }
  };

  const btn = (label, op, color) => (
    <button
      onClick={(e) => { e.stopPropagation(); run(op); }}
      disabled={!!busy}
      style={{
        background: 'transparent', border: `1px solid ${color}`, color,
        borderRadius: 7, padding: '5px 10px', fontSize: 11, fontWeight: 700,
        cursor: busy ? 'wait' : 'pointer', fontFamily: "'Plus Jakarta Sans', sans-serif",
        whiteSpace: 'nowrap', opacity: busy ? 0.6 : 1,
      }}
    >{busy === op ? '…' : label}</button>
  );

  const isDeadOrOut = lead.state === 'dead' || lead.state === 'opted_out';
  return (
    <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
      {lead.state === 'paused'
        ? btn('Resume', 'resume', TF_TONE.success)
        : (!isDeadOrOut && btn('Pause', 'pause', TF_TONE.muted))}
      {!isDeadOrOut && btn('Mark dead', 'markDead', TF_TONE.danger)}
      {err && <div style={{ fontSize: 10, color: TF_TONE.danger, width: '100%', textAlign: 'right' }}>{err}</div>}
    </div>
  );
};

// Expandable transcript.
const LeadTranscript = ({ lead }) => {
  const msgs = lead.teacher_lead_messages || [];
  if (!msgs.length) {
    return <div style={{ fontSize: 12, color: TF_TONE.muted, padding: '8px 0' }}>No messages yet.</div>;
  }
  const roleStyle = {
    inbound:  { align: 'flex-start', bg: '#fff',                 border: TF_TONE.border, label: 'Teacher' },
    outbound: { align: 'flex-end',   bg: 'oklch(95% 0.04 250)',  border: 'oklch(85% 0.05 250)', label: 'Bot' },
    system:   { align: 'center',     bg: 'oklch(96% 0.01 265)',  border: TF_TONE.border, label: 'System' },
  };
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 8, padding: '10px 0' }}>
      {msgs.map((m, i) => {
        const r = roleStyle[m.direction] || roleStyle.system;
        return (
          <div key={i} style={{ display: 'flex', justifyContent: r.align }}>
            <div style={{
              maxWidth: '78%', background: r.bg, border: `1px solid ${r.border}`,
              borderRadius: 10, padding: '7px 11px',
            }}>
              <div style={{ fontSize: 9, fontWeight: 700, color: TF_TONE.muted, textTransform: 'uppercase', letterSpacing: '0.05em', marginBottom: 2 }}>
                {r.label} · {fmtWhen(m.created_at)}
              </div>
              <div style={{ fontSize: 13, color: TF_TONE.text, whiteSpace: 'pre-wrap', wordBreak: 'break-word' }}>{m.body || ''}</div>
            </div>
          </div>
        );
      })}
    </div>
  );
};

const LeadRow = ({ lead, onChanged }) => {
  const [open, setOpen] = React.useState(false);
  const td = { padding: '11px 10px', fontSize: 13, color: TF_TONE.text, verticalAlign: 'top' };
  return (
    <React.Fragment>
      <tr
        onClick={() => setOpen(o => !o)}
        style={{ borderBottom: `1px solid ${TF_TONE.border}`, cursor: 'pointer' }}
      >
        <td style={{ ...td, fontWeight: 600, whiteSpace: 'nowrap' }}>
          <span style={{ color: TF_TONE.muted, marginRight: 6 }}>{open ? '▾' : '▸'}</span>
          {lead.phone}
        </td>
        <td style={td}>{lead.name || <span style={{ color: TF_TONE.muted, fontStyle: 'italic' }}>—</span>}</td>
        <td style={td}>{lead.topic || <span style={{ color: TF_TONE.muted }}>—</span>}</td>
        <td style={td}><LeadStateBadge state={lead.state} /></td>
        <td style={{ ...td, whiteSpace: 'nowrap', fontWeight: 600 }}>{fmtRate(lead.extracted_rate_cents, lead.extracted_rate_raw)}</td>
        <td style={td}>{lead.extracted_availability || <span style={{ color: TF_TONE.muted }}>—</span>}</td>
        <td style={td}>{lead.extracted_location || <span style={{ color: TF_TONE.muted }}>—</span>}</td>
        <td style={{ ...td, whiteSpace: 'nowrap', color: TF_TONE.muted, fontSize: 11 }}>{fmtWhen(lastMessageAt(lead))}</td>
        <td style={{ ...td, textAlign: 'right' }}><LeadActions lead={lead} onChanged={onChanged} /></td>
      </tr>
      {open && (
        <tr style={{ background: TF_TONE.page }}>
          <td colSpan={9} style={{ padding: '4px 16px 14px' }}>
            <LeadTranscript lead={lead} />
          </td>
        </tr>
      )}
    </React.Fragment>
  );
};

const AdminLeads = () => {
  const [loading, setLoading] = React.useState(true);
  const [err, setErr] = React.useState('');
  const [botEnabled, setBotEnabled] = React.useState(false);
  const [approvalMode, setApprovalMode] = React.useState(true);
  const [pendingCount, setPendingCount] = React.useState(0);
  const [leads, setLeads] = React.useState([]);

  const load = React.useCallback(async () => {
    setLoading(true); setErr('');
    try {
      const { botEnabled: be, approvalMode: am, pendingCount: pc, leads: rows } =
        await window.ADMIN_DATA.teacherLeads.list();
      setBotEnabled(be);
      setApprovalMode(am);
      setPendingCount(pc);
      setLeads(rows);
    } catch (e) {
      setErr(e.message || 'Failed to load leads');
    } finally {
      setLoading(false);
    }
  }, []);

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

  // Patch one lead in place after an action, so the table updates without a
  // full reload.
  const onChanged = (updated) => {
    if (!updated) return;
    setLeads(rows => rows.map(l => (l.id === updated.id ? { ...l, ...updated } : l)));
  };

  const th = { textAlign: 'left', padding: '10px', fontSize: 10, fontWeight: 700, color: TF_TONE.muted, textTransform: 'uppercase', letterSpacing: '0.05em', whiteSpace: 'nowrap' };

  return (
    <div style={{ fontFamily: "'Plus Jakarta Sans', sans-serif", color: TF_TONE.text }}>
      <div style={{ marginBottom: 16 }}>
        <h2 style={{ margin: 0, fontFamily: "'Cormorant Garamond', serif", fontSize: 28, fontWeight: 700, color: TF_TONE.text }}>
          In-Person Teachers
        </h2>
        <div style={{ fontSize: 13, color: TF_TONE.muted, marginTop: 4 }}>
          Local music teachers you found via Teacher Finder and texted about in-person lessons. When one replies, the bot asks their rate and availability, then marks the lead ready for review so you can take over. See every search — and each teacher's rate — under “By search” below.
        </div>
      </div>

      {/* Bot brain editor + test sandbox (admin-leads-bot-settings.jsx). */}
      {window.AdminLeadsBotSettings && <window.AdminLeadsBotSettings />}

      <LeadBotKillSwitch enabled={botEnabled} onToggled={setBotEnabled} />

      <ApprovalModeToggle approvalMode={approvalMode} pendingCount={pendingCount} onToggled={setApprovalMode} />

      {/* Outreach grouped BY SEARCH (admin-leads-campaigns.jsx). Sits above the
          flat per-lead list below; the flat list is unchanged. */}
      {window.AdminLeadsCampaigns && <window.AdminLeadsCampaigns />}

      <div style={{ borderTop: `1px solid ${TF_TONE.border}`, margin: '4px 0 16px' }} />
      <div style={{ fontSize: 13, fontWeight: 700, color: TF_TONE.text, marginBottom: 8 }}>All leads</div>

      <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 10 }}>
        <button
          onClick={load}
          disabled={loading}
          style={{
            background: 'transparent', border: `1px solid ${TF_TONE.border}`, borderRadius: 8,
            padding: '7px 13px', fontSize: 12, fontWeight: 600, color: TF_TONE.muted,
            cursor: loading ? 'wait' : 'pointer', fontFamily: "'Plus Jakarta Sans', sans-serif",
          }}
        >{loading ? 'Refreshing…' : 'Refresh'}</button>
      </div>

      {err && (
        <div style={{ background: TF_TONE.dangerBg, color: TF_TONE.danger, padding: '12px 14px', borderRadius: 10, fontSize: 13, marginBottom: 12 }}>
          {err}
        </div>
      )}

      {!err && !loading && leads.length === 0 && (
        <div style={{ background: TF_TONE.card, border: `1px solid ${TF_TONE.border}`, borderRadius: 12, padding: '24px', textAlign: 'center', color: TF_TONE.muted, fontSize: 13 }}>
          No leads yet. Send an outreach text from the Teacher Finder tab — replies will show up here.
        </div>
      )}

      {leads.length > 0 && (
        <div style={{ background: TF_TONE.card, border: `1px solid ${TF_TONE.border}`, borderRadius: 12, overflowX: 'auto' }}>
          <table style={{ width: '100%', borderCollapse: 'collapse', minWidth: 760 }}>
            <thead>
              <tr style={{ background: TF_TONE.page }}>
                <th style={th}>Phone</th>
                <th style={th}>Name</th>
                <th style={th}>Topic</th>
                <th style={th}>State</th>
                <th style={th}>Rate</th>
                <th style={th}>Availability</th>
                <th style={th}>Location</th>
                <th style={th}>Last msg</th>
                <th style={{ ...th, textAlign: 'right' }}>Actions</th>
              </tr>
            </thead>
            <tbody>
              {leads.map(lead => <LeadRow key={lead.id} lead={lead} onChanged={onChanged} />)}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

window.AdminLeads = AdminLeads;
