// src/features/admin/ui/admin-teacher-finder-widgets.jsx
//
// The five sub-widgets used by AdminTeacherFinder. Extracted from
// admin-teacher-finder.jsx for size.
//
// Public on window: TFAvailabilityPill, TFOutreachButton, TFRow,
// TFKillSwitch, TFTemplateEditor.
//
// No external deps — these are leaf components.

const TFAvailabilityPill = ({ value }) => {
  const map = {
    Local:      { bg: TF_TONE.pillLocal,  text: '#fff' },
    Reasonable: { bg: TF_TONE.pillReason, text: TF_TONE.accentText },
    Far:        { bg: TF_TONE.pillFar,    text: TF_TONE.accentText },
  };
  const cfg = map[value] || { 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.04em',
      background: cfg.bg, color: cfg.text, textTransform: 'uppercase',
    }}>{value}</span>
  );
};

const TFOutreachButton = ({ row, topic, area, searchId, outboundEnabled, onSent }) => {
  // Outreach is now queued, not sent instantly: clicking enqueues a row that a
  // 1-per-minute server job drains, so messages go out >=1 min apart and never
  // simultaneously. The button reflects "Queued", not "Sent" — we don't poll
  // the queue, so the most we honestly know is that the row was accepted.
  //
  // Dedup: a teacher already in the pipeline (messaged in any past search) is
  // pre-flagged by the search endpoint as row.alreadyContacted; the enqueue
  // endpoint also returns 409 DUPLICATE_PHONE/DUPLICATE_QUEUED. Either way we show a
  // calm "Already contacted" and never send — same number is never messaged twice.
  const [state, setState] = React.useState('idle'); // idle | queuing | queued | error | duplicate
  const [err, setErr] = React.useState('');
  const [dupInfo, setDupInfo] = React.useState(null);

  // row.alreadyContacted (a prop) always reflects the latest search and overrides
  // the local state machine, so a re-used row slot can't show a stale button.
  const isDuplicate = !!row.alreadyContacted || state === 'duplicate';
  const info = state === 'duplicate' ? dupInfo : (row.contactedInfo || null);

  const disabled = !row.phone || !outboundEnabled || isDuplicate
    || state === 'queuing' || state === 'queued';

  const send = async () => {
    setState('queuing');
    setErr('');
    try {
      // searchId + resultId + area link this send back to the persisted Teacher
      // Finder search (v117), so the Teacher Leads tab can group outreach by
      // search. They're optional — the server drops bad/missing ids and the
      // send still goes through, just unlinked.
      const r = await tfAuthFetch('/api/teacher-outreach', {
        method: 'POST',
        body: JSON.stringify({
          name: row.name, phone: row.phone, topic,
          searchId: searchId || null,
          resultId: row.resultId || null,
          area: area || null,
        }),
      });
      const body = await r.json();
      // Already in the pipeline — calm "Already contacted", not a red error.
      if (r.status === 409 && (body.code === 'DUPLICATE_PHONE' || body.code === 'DUPLICATE_QUEUED')) {
        setDupInfo(body.previous || {});
        setState('duplicate');
        return;
      }
      if (!r.ok || body.ok === false) throw new Error(body.error || `HTTP ${r.status}`);
      setState('queued');
      if (onSent) onSent({ row, response: body });
    } catch (e) {
      setState('error');
      setErr(e.message || 'Could not queue');
    }
  };

  const fmtWhen = (iso) => {
    if (!iso) return null;
    try { return new Date(iso).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); }
    catch (e) { return null; }
  };
  const dupDetail = info
    ? [info.topic, info.area, fmtWhen(info.contactedAt)].filter(Boolean).join(' · ')
    : '';

  let label = 'Send outreach';
  let bg = TF_TONE.accent, color = TF_TONE.accentText, cursor = 'pointer';
  if (state === 'queuing')   { label = 'Queuing…';        bg = TF_TONE.mutedLight; color = '#fff'; cursor = 'wait'; }
  if (state === 'queued')    { label = '✓ Queued';        bg = TF_TONE.successBg;  color = TF_TONE.success; cursor = 'default'; }
  if (state === 'error')     { label = 'Retry';           bg = TF_TONE.dangerBg;   color = TF_TONE.danger; }
  if (!row.phone)            { label = 'No phone';        bg = TF_TONE.border;     color = TF_TONE.muted;   cursor = 'not-allowed'; }
  // Master switch overrides per-row state (except already-queued, which stays green)
  if (!outboundEnabled && state !== 'queued' && !isDuplicate) {
    label = 'Outreach off';
    bg = TF_TONE.border;
    color = TF_TONE.muted;
    cursor = 'not-allowed';
  }
  // Duplicate overrides everything except an in-flight queued send — never offer to
  // message a number already in the pipeline.
  if (isDuplicate && state !== 'queued') {
    label = 'Already contacted';
    bg = TF_TONE.border;
    color = TF_TONE.muted;
    cursor = 'not-allowed';
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 4 }}>
      <button
        onClick={send}
        disabled={disabled}
        title={
          isDuplicate ? 'This number is already in your leads — not messaging it again.'
            : !outboundEnabled ? 'Flip the global "Outreach enabled" toggle on, above.'
              : (row.phone ? '' : 'No phone number on this teacher')
        }
        style={{
          background: bg, color, border: 'none', borderRadius: 8,
          padding: '6px 11px', fontSize: 11, fontWeight: 700, cursor,
          fontFamily: "'Plus Jakarta Sans', sans-serif",
          letterSpacing: '0.02em', whiteSpace: 'nowrap',
          opacity: disabled && state !== 'queued' && !isDuplicate ? 0.65 : 1,
          transition: 'all 0.14s',
        }}
      >{label}</button>
      {state === 'queued' && (
        <div style={{ fontSize: 10, color: TF_TONE.muted, maxWidth: 200, textAlign: 'right' }}>
          sending within ~1 min
        </div>
      )}
      {isDuplicate && dupDetail && (
        <div style={{ fontSize: 10, color: TF_TONE.muted, maxWidth: 220, textAlign: 'right' }}>
          {dupDetail}
        </div>
      )}
      {err && <div style={{ fontSize: 10, color: TF_TONE.danger, maxWidth: 200, textAlign: 'right' }}>{err}</div>}
    </div>
  );
};

const TFRow = ({ row, topic, area, searchId, outboundEnabled, onSent }) => (
  <tr style={{ borderBottom: `1px solid ${TF_TONE.border}` }}>
    <td style={{ padding: '11px 14px', fontSize: 13, fontWeight: 600, color: TF_TONE.text, verticalAlign: 'top' }}>
      {row.name || <span style={{ color: TF_TONE.muted, fontStyle: 'italic' }}>—</span>}
      <div style={{ fontSize: 11, fontWeight: 400, color: TF_TONE.muted, marginTop: 2 }}>{row.address}</div>
      {row.alreadyContacted && (
        <div style={{
          marginTop: 5, display: 'inline-block', fontSize: 9, fontWeight: 700,
          letterSpacing: '0.04em', textTransform: 'uppercase', color: TF_TONE.muted,
          background: TF_TONE.page, border: `1px solid ${TF_TONE.border}`,
          borderRadius: 999, padding: '2px 7px',
        }}>Already contacted</div>
      )}
    </td>
    <td style={{ padding: '11px 8px', fontSize: 13, color: TF_TONE.text, verticalAlign: 'top', whiteSpace: 'nowrap' }}>
      <div style={{ fontWeight: 700 }}>{row.driveMin != null ? `${row.driveMin} min` : '—'}</div>
      <div style={{ marginTop: 4 }}><TFAvailabilityPill value={row.availability} /></div>
    </td>
    <td style={{ padding: '11px 8px', fontSize: 13, color: TF_TONE.text, verticalAlign: 'top', whiteSpace: 'nowrap' }}>
      {row.phone || <span style={{ color: TF_TONE.muted, fontStyle: 'italic' }}>—</span>}
    </td>
    <td style={{ padding: '11px 8px', fontSize: 12, color: TF_TONE.text, verticalAlign: 'top' }}>
      {row.rating != null
        ? <span><strong>{row.rating}</strong> <span style={{ color: TF_TONE.muted }}>({row.reviews || 0})</span></span>
        : <span style={{ color: TF_TONE.muted }}>—</span>}
    </td>
    <td style={{ padding: '11px 8px', fontSize: 11, color: TF_TONE.muted, verticalAlign: 'top', maxWidth: 200, overflow: 'hidden', textOverflow: 'ellipsis' }}>
      {row.website
        ? <a href={row.website} target="_blank" rel="noreferrer" style={{ color: TF_TONE.muted, textDecoration: 'underline', wordBreak: 'break-all' }}>{row.website.replace(/^https?:\/\//, '').replace(/\/$/, '').slice(0, 30)}</a>
        : <span>—</span>}
    </td>
    <td style={{ padding: '11px 14px', verticalAlign: 'top', textAlign: 'right' }}>
      <TFOutreachButton row={row} topic={topic} area={area} searchId={searchId} outboundEnabled={outboundEnabled} onSent={onSent} />
    </td>
  </tr>
);

const TFKillSwitch = ({ outboundEnabled, onToggled }) => {
  const [busy, setBusy] = React.useState(false);
  const [err, setErr] = React.useState('');

  const toggle = async () => {
    const next = !outboundEnabled;
    // Make the user confirm when turning it ON — safety against accidental enable
    if (next) {
      const ok = window.confirm(
        'Turn outreach ON?\n\nWhen on, clicking "Send outreach" on a teacher row will:\n  • create a Sales Message contact\n  • send a real SMS from your business number\n\nClick OK to enable.'
      );
      if (!ok) return;
    }
    setBusy(true);
    setErr('');
    try {
      const r = await tfAuthFetch('/api/outreach-template', {
        method: 'PUT',
        body: JSON.stringify({ outboundEnabled: next }),
      });
      const body = await r.json();
      if (!r.ok) throw new Error(body.error || `HTTP ${r.status}`);
      if (onToggled) onToggled(body.outboundEnabled);
    } catch (e) {
      setErr(e.message || 'Toggle failed');
    } finally {
      setBusy(false);
    }
  };

  const on = !!outboundEnabled;
  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: 14,
      display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 14,
    }}>
      <div style={{ minWidth: 0 }}>
        <div style={{ fontSize: 13, fontWeight: 700, color: on ? TF_TONE.success : TF_TONE.danger, letterSpacing: '0.02em' }}>
          Outreach is {on ? 'ENABLED' : 'OFF'}
        </div>
        <div style={{ fontSize: 11, color: TF_TONE.muted, marginTop: 3 }}>
          {on
            ? 'The per-row "Send outreach" buttons will create a Sales Message contact and send a real SMS.'
            : 'No SMS can go out. Flip this on when you\'re ready to reach a teacher manually.'}
        </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>
  );
};

const TFTemplateEditor = ({ initialTemplate, onSaved }) => {
  const [tpl, setTpl] = React.useState(initialTemplate || '');
  const [saving, setSaving] = React.useState(false);
  const [savedAt, setSavedAt] = React.useState(null);
  const [err, setErr] = React.useState('');

  React.useEffect(() => { setTpl(initialTemplate || ''); }, [initialTemplate]);

  const save = async () => {
    setSaving(true);
    setErr('');
    try {
      const r = await tfAuthFetch('/api/outreach-template', {
        method: 'PUT',
        body: JSON.stringify({ template: tpl }),
      });
      const body = await r.json();
      if (!r.ok) throw new Error(body.error || `HTTP ${r.status}`);
      setSavedAt(new Date());
      if (onSaved) onSaved(body.template);
    } catch (e) {
      setErr(e.message || 'Save failed');
    } finally {
      setSaving(false);
    }
  };

  const dirty = tpl !== (initialTemplate || '');

  return (
    <div style={{
      background: TF_TONE.card, border: `1px solid ${TF_TONE.border}`, borderRadius: 14,
      padding: '20px 22px', marginBottom: 22,
    }}>
      <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 10 }}>
        <h3 style={{ margin: 0, fontSize: 14, fontWeight: 700, color: TF_TONE.text, letterSpacing: '0.02em' }}>
          Outreach message template
        </h3>
        <span style={{ fontSize: 11, color: TF_TONE.muted }}>
          Variables: <code style={{ background: TF_TONE.page, padding: '1px 5px', borderRadius: 4 }}>{'{firstName}'}</code>{' '}
          <code style={{ background: TF_TONE.page, padding: '1px 5px', borderRadius: 4 }}>{'{topic}'}</code>{' '}
          <code style={{ background: TF_TONE.page, padding: '1px 5px', borderRadius: 4 }}>{'{name}'}</code>
        </span>
      </div>
      <textarea
        value={tpl}
        onChange={e => setTpl(e.target.value)}
        rows={3}
        placeholder="Hey {firstName}, Alex from Coaching — saw you teach {topic} in the area. Are you taking new students right now?"
        style={{
          width: '100%', boxSizing: 'border-box',
          border: `1px solid ${TF_TONE.border}`, borderRadius: 8,
          padding: '10px 12px', fontSize: 13, fontFamily: 'inherit',
          color: TF_TONE.text, background: TF_TONE.page,
          resize: 'vertical', minHeight: 70,
        }}
      />
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginTop: 10 }}>
        <div style={{ fontSize: 11, color: err ? TF_TONE.danger : TF_TONE.muted }}>
          {err ? `Error: ${err}` :
           savedAt ? `Saved ${savedAt.toLocaleTimeString()}` :
           dirty ? 'Unsaved changes' : 'No changes'}
        </div>
        <button
          onClick={save}
          disabled={!dirty || saving || !tpl.trim()}
          style={{
            background: dirty ? TF_TONE.accent : TF_TONE.border,
            color: dirty ? TF_TONE.accentText : TF_TONE.muted,
            border: 'none', borderRadius: 8,
            padding: '8px 18px', fontSize: 12, fontWeight: 700,
            cursor: dirty && !saving ? 'pointer' : 'not-allowed',
            fontFamily: "'Plus Jakarta Sans', sans-serif",
          }}
        >{saving ? 'Saving…' : 'Save template'}</button>
      </div>
    </div>
  );
};



Object.assign(window, {
  TFAvailabilityPill,
  TFOutreachButton,
  TFRow,
  TFKillSwitch,
  TFTemplateEditor,
});
