/* ============================================================
   page-collections.jsx — Collections: bot-driven surveys, polls,
   profile-collection prompts, and acknowledgements (#8)
   ============================================================ */

/* Re-bind parseDetail — set by primitives.jsx */
const parseDetail = window.parseDetail || ((body, status) => (body && (body.detail || body.message)) || `HTTP ${status}`);

const COLL_KIND_LABELS = {
  text:     'Text',
  number:   'Number',
  rating:   'Rating',
  choice:   'Choice (single)',
  multi:    'Multi-select',
  ack:      'Acknowledgement',
  day_off:  'Day off',
  whatsapp: 'WhatsApp number',
  phone:    'Phone number',
  email:    'Email address',
};
const COLL_AUDIENCE_LABELS = { all: 'Everyone', team: 'Team', role: 'Role', users: 'Specific users' };
const COLL_SCHEDULE_LABELS = { once: 'Once', daily: 'Daily', weekly: 'Weekly', monthly: 'Monthly' };
const COLL_STATUS_LABELS   = { draft: 'Draft', active: 'Active', paused: 'Paused', done: 'Done' };
const COLL_DOW_LABELS = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];

function collStatusBadgeKind(s) {
  if (s === 'active') return 'ok';
  if (s === 'paused')  return 'warn';
  if (s === 'done')    return 'mute';
  return 'info'; // draft
}

/* ── Prompt create/edit modal ── */
function CollPromptForm({ prompt, kinds, profileFields, onClose, onSaved }) {
  const toast = useToast ? useToast() : { push: () => {} };
  const isEdit = !!(prompt && prompt.id);
  const [title, setTitle]       = useState(prompt?.title || '');
  const [question, setQuestion] = useState(prompt?.question || '');
  const [kind, setKind]         = useState(prompt?.kind || (kinds[0] || 'text'));
  const [options, setOptions]   = useState(Array.isArray(prompt?.options) ? prompt.options : []);
  const [optDraft, setOptDraft] = useState('');
  const [profileField, setProfileField] = useState(prompt?.profile_field || '');
  const [active, setActive]     = useState(prompt ? prompt.active !== false : true);
  const [busy, setBusy]         = useState(false);
  const [err, setErr]           = useState('');

  const needsOptions = kind === 'choice' || kind === 'multi';

  const addOption = () => {
    const v = optDraft.trim();
    if (!v || options.includes(v)) { setOptDraft(''); return; }
    setOptions([...options, v]);
    setOptDraft('');
  };
  const removeOption = (i) => setOptions(options.filter((_, idx) => idx !== i));

  const submit = async () => {
    if (!title.trim())    { setErr((window.appT||(s=>s))('Title required')); return; }
    if (!question.trim()) { setErr((window.appT||(s=>s))('Question required')); return; }
    if (needsOptions && options.length < 2) { setErr((window.appT||(s=>s))('Add at least 2 options')); return; }
    setErr(''); setBusy(true);
    try {
      const body = {
        title: title.trim(),
        question: question.trim(),
        kind,
        options: needsOptions ? options : null,
        profile_field: profileField || null,
        active,
      };
      const url = isEdit ? `/api/collections/prompts/${prompt.id}` : '/api/collections/prompts';
      const r = await fetch(url, {
        method: isEdit ? 'PUT' : 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      if (!r.ok) {
        const b = await r.json().catch(() => null);
        throw new Error(parseDetail(b, r.status));
      }
      await r.json();
      toast.push({ msg: (window.appT||(s=>s))(isEdit ? 'Prompt updated' : 'Prompt created'), kind: 'ok' });
      onSaved();
      onClose();
    } catch (e) {
      setErr(e.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <strong>{(window.appT||(s=>s))(isEdit ? 'Edit prompt' : 'New prompt')}</strong>
          <button className="btn btn-ghost btn-icon" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Title')}
            <input className="inp" value={title} onChange={e => setTitle(e.target.value)}
                   placeholder={(window.appT||(s=>s))('e.g. Monthly satisfaction check')} />
          </label>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Question')}
            <textarea className="inp" rows={3} value={question} onChange={e => setQuestion(e.target.value)}
                      placeholder={(window.appT||(s=>s))('What the bot will ask in the DM')} />
          </label>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Kind')}
              <select className="sel" value={kind} onChange={e => setKind(e.target.value)}>
                {kinds.map(k => <option key={k} value={k}>{(window.appT||(s=>s))(COLL_KIND_LABELS[k] || k)}</option>)}
              </select>
            </label>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Write answer to profile field')}
              <select className="sel" value={profileField} onChange={e => setProfileField(e.target.value)}>
                <option value="">{(window.appT||(s=>s))('(none)')}</option>
                {profileFields.map(f => <option key={f} value={f}>{f}</option>)}
              </select>
            </label>
          </div>
          {needsOptions && (
            <div>
              <div style={{ fontSize: 12, color: 'var(--text-2)', marginBottom: 4 }}>{(window.appT||(s=>s))('Options')}</div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5, marginBottom: 6 }}>
                {options.map((o, i) => (
                  <span key={i} style={{
                    display: 'inline-flex', alignItems: 'center', gap: 4,
                    background: 'var(--bg-elev-2)', borderRadius: 20, padding: '2px 8px 2px 10px',
                    fontSize: 12,
                  }}>
                    {o}
                    <button onClick={() => removeOption(i)} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-3)', padding: 0, fontSize: 13, lineHeight: 1 }}>×</button>
                  </span>
                ))}
                {options.length === 0 && (
                  <span style={{ fontSize: 11, color: 'var(--text-3)', fontStyle: 'italic' }}>{(window.appT||(s=>s))('No options yet')}</span>
                )}
              </div>
              <div style={{ display: 'flex', gap: 6 }}>
                <input className="inp" value={optDraft} onChange={e => setOptDraft(e.target.value)}
                       onKeyDown={e => { if (e.key === 'Enter') { e.preventDefault(); addOption(); } }}
                       placeholder={(window.appT||(s=>s))('Add option...')} style={{ flex: 1 }} />
                <button className="btn btn-ghost" onClick={addOption}>{(window.appT||(s=>s))('+ Add')}</button>
              </div>
            </div>
          )}
          <label style={{ fontSize: 12, display: 'flex', alignItems: 'center', gap: 6 }}>
            <input type="checkbox" checked={active} onChange={e => setActive(e.target.checked)} />
            {(window.appT||(s=>s))('Active')}
          </label>
          {err && <div style={{ color: 'var(--err)', fontSize: 12 }}>{err}</div>}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose} disabled={busy}>{(window.appT||(s=>s))('Cancel')}</button>
          <button className="btn btn-pri" onClick={submit} disabled={busy}>{busy ? (window.appT||(s=>s))('Saving…') : (window.appT||(s=>s))('Save')}</button>
        </div>
      </div>
    </div>
  );
}

/* ── Campaign create/edit modal ── */
function CollCampaignForm({ campaign, prompts, onClose, onSaved }) {
  const toast = useToast ? useToast() : { push: () => {} };
  const isEdit = !!(campaign && campaign.id);
  const [promptId, setPromptId]         = useState(campaign?.prompt_id ?? (prompts[0]?.id ?? ''));
  const [title, setTitle]               = useState(campaign?.title || '');
  const [audienceKind, setAudienceKind] = useState(campaign?.audience_kind || 'all');
  const [audienceValue, setAudienceValue] = useState(campaign?.audience_value || '');
  const [scheduleKind, setScheduleKind] = useState(campaign?.schedule_kind || 'once');
  const [dayOfWeek, setDayOfWeek]       = useState(campaign?.day_of_week ?? 0);
  const [dayOfMonth, setDayOfMonth]     = useState(campaign?.day_of_month ?? 1);
  const [hourUtc, setHourUtc]           = useState(campaign?.hour_utc ?? 9);
  const [status, setStatus]             = useState(campaign?.status || 'draft');
  const [busy, setBusy]                 = useState(false);
  const [err, setErr]                   = useState('');
  // Audience pickers: real teams + employees (so no free-typing team names or
  // raw user IDs). userSel holds selected employee ids for audience_kind=users.
  const [teams, setTeams]     = useState([]);
  const [emps, setEmps]       = useState([]);
  const [userQuery, setUserQuery] = useState('');
  const [userSel, setUserSel] = useState(() => (
    (campaign?.audience_kind === 'users' && campaign?.audience_value)
      ? campaign.audience_value.split(',').map(s => Number(s.trim())).filter(Boolean)
      : []
  ));
  React.useEffect(() => {
    fetch('/api/teams', { credentials: 'include' }).then(r => r.ok ? r.json() : [])
      .then(d => {
        const list = Array.isArray(d) ? d : (d.teams || []);
        setTeams(list.map(t => (typeof t === 'string' ? t : (t.name || t.team_name))).filter(Boolean));
      }).catch(() => {});
    fetch('/api/employees', { credentials: 'include' }).then(r => r.ok ? r.json() : [])
      .then(d => {
        const list = Array.isArray(d) ? d : (d.employees || d.users || []);
        setEmps(list.filter(e => e && e.id));
      }).catch(() => {});
  }, []);
  const toggleUser = (id) => setUserSel(sel => sel.includes(id) ? sel.filter(x => x !== id) : [...sel, id]);

  const submit = async () => {
    if (!promptId) { setErr((window.appT||(s=>s))('Pick a prompt')); return; }
    const audValue = audienceKind === 'all' ? null
      : audienceKind === 'users' ? userSel.join(',')
      : audienceValue.trim();
    if (audienceKind !== 'all' && !audValue) { setErr((window.appT||(s=>s))('Pick at least one target for this audience')); return; }
    setErr(''); setBusy(true);
    try {
      const body = {
        prompt_id: Number(promptId),
        title: title.trim() || null,
        audience_kind: audienceKind,
        audience_value: audValue,
        schedule_kind: scheduleKind,
        day_of_week: scheduleKind === 'weekly' ? Number(dayOfWeek) : null,
        day_of_month: scheduleKind === 'monthly' ? Number(dayOfMonth) : null,
        hour_utc: Number(hourUtc),
        status,
      };
      const url = isEdit ? `/api/collections/campaigns/${campaign.id}` : '/api/collections/campaigns';
      const r = await fetch(url, {
        method: isEdit ? 'PUT' : 'POST',
        credentials: 'include',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body),
      });
      if (!r.ok) {
        const b = await r.json().catch(() => null);
        throw new Error(parseDetail(b, r.status));
      }
      await r.json();
      toast.push({ msg: (window.appT||(s=>s))(isEdit ? 'Campaign updated' : 'Campaign created'), kind: 'ok' });
      onSaved();
      onClose();
    } catch (e) {
      setErr(e.message);
    } finally {
      setBusy(false);
    }
  };

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()}>
        <div className="modal-head">
          <strong>{(window.appT||(s=>s))(isEdit ? 'Edit campaign' : 'New campaign')}</strong>
          <button className="btn btn-ghost btn-icon" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Prompt')}
            <select className="sel" value={promptId} onChange={e => setPromptId(e.target.value)}>
              {prompts.length === 0 && <option value="">{(window.appT||(s=>s))('No prompts available')}</option>}
              {prompts.map(p => <option key={p.id} value={p.id}>{p.title}</option>)}
            </select>
          </label>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Title (optional)')}
            <input className="inp" value={title} onChange={e => setTitle(e.target.value)}
                   placeholder={(window.appT||(s=>s))('Defaults to prompt title')} />
          </label>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Audience')}
              <select className="sel" value={audienceKind} onChange={e => setAudienceKind(e.target.value)}>
                {Object.entries(COLL_AUDIENCE_LABELS).map(([v, l]) => <option key={v} value={v}>{(window.appT||(s=>s))(l)}</option>)}
              </select>
            </label>
            {audienceKind === 'team' && (
              <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Team')}
                <select className="sel" value={audienceValue} onChange={e => setAudienceValue(e.target.value)}>
                  <option value="">{(window.appT||(s=>s))('— pick a team —')}</option>
                  {teams.map(t => <option key={t} value={t}>{t}</option>)}
                </select>
              </label>
            )}
            {audienceKind === 'role' && (
              <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Role')}
                <select className="sel" value={audienceValue} onChange={e => setAudienceValue(e.target.value)}>
                  <option value="">{(window.appT||(s=>s))('— pick a role —')}</option>
                  {['employee', 'manager', 'moderator', 'admin', 'superadmin', 'hr'].map(r =>
                    <option key={r} value={r}>{r}</option>)}
                </select>
              </label>
            )}
            {audienceKind === 'users' && (
              <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Selected')}
                <input className="inp" readOnly value={`${userSel.length} ${(window.appT||(s=>s))('employee(s)')}`} />
              </label>
            )}
          </div>
          {audienceKind === 'users' && (
            <div style={{ border: '1px solid var(--line)', borderRadius: 8, padding: 8 }}>
              <input className="inp" value={userQuery} onChange={e => setUserQuery(e.target.value)}
                     placeholder={(window.appT||(s=>s))('Search employees…')} style={{ marginBottom: 6 }} />
              <div style={{ maxHeight: 180, overflowY: 'auto', display: 'flex', flexDirection: 'column', gap: 2 }}>
                {emps.filter(e => {
                  const q = userQuery.trim().toLowerCase();
                  return !q || (e.display_name || e.name || '').toLowerCase().includes(q)
                    || (e.matrix_id || '').toLowerCase().includes(q);
                }).map(e => (
                  <label key={e.id} style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 12.5,
                                             padding: '3px 4px', cursor: 'pointer', color: 'var(--text)' }}>
                    <input type="checkbox" checked={userSel.includes(e.id)} onChange={() => toggleUser(e.id)} />
                    <span>{e.display_name || e.name || `#${e.id}`}</span>
                    {e.team ? <span className="muted" style={{ fontSize: 11 }}>· {e.team}</span> : null}
                  </label>
                ))}
                {emps.length === 0 && <div className="muted" style={{ fontSize: 12, padding: 4 }}>{(window.appT||(s=>s))('Loading employees…')}</div>}
              </div>
            </div>
          )}
          <div style={{ display: 'grid', gridTemplateColumns: audienceKind !== 'all' ? '1fr 1fr 1fr' : '1fr 1fr', gap: 10 }}>
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Schedule')}
              <select className="sel" value={scheduleKind} onChange={e => setScheduleKind(e.target.value)}>
                {Object.entries(COLL_SCHEDULE_LABELS).map(([v, l]) => <option key={v} value={v}>{(window.appT||(s=>s))(l)}</option>)}
              </select>
            </label>
            {scheduleKind === 'weekly' && (
              <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Day of week')}
                <select className="sel" value={dayOfWeek} onChange={e => setDayOfWeek(e.target.value)}>
                  {COLL_DOW_LABELS.map((d, i) => <option key={i} value={i}>{d}</option>)}
                </select>
              </label>
            )}
            {scheduleKind === 'monthly' && (
              <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Day of month')}
                <input type="number" className="inp" min={1} max={28} value={dayOfMonth} onChange={e => setDayOfMonth(e.target.value)} />
              </label>
            )}
            <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Hour (UTC)')}
              <input type="number" className="inp" min={0} max={23} value={hourUtc} onChange={e => setHourUtc(e.target.value)} />
            </label>
          </div>
          <label style={{ fontSize: 12, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Status')}
            <select className="sel" value={status} onChange={e => setStatus(e.target.value)}>
              {Object.entries(COLL_STATUS_LABELS).map(([v, l]) => <option key={v} value={v}>{(window.appT||(s=>s))(l)}</option>)}
            </select>
          </label>
          {err && <div style={{ color: 'var(--err)', fontSize: 12 }}>{err}</div>}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose} disabled={busy}>{(window.appT||(s=>s))('Cancel')}</button>
          <button className="btn btn-pri" onClick={submit} disabled={busy}>{busy ? (window.appT||(s=>s))('Saving…') : (window.appT||(s=>s))('Save')}</button>
        </div>
      </div>
    </div>
  );
}

/* ── Responses panel modal ── */
function CollResponsesModal({ campaign, onClose }) {
  const [data, setData]       = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError]     = useState(null);

  useEffect(() => {
    let cancelled = false;
    setLoading(true); setError(null);
    fetch(`/api/collections/campaigns/${campaign.id}/responses`, { credentials: 'include' })
      .then(async r => {
        if (!r.ok) {
          const b = await r.json().catch(() => null);
          throw new Error(parseDetail(b, r.status));
        }
        return r.json();
      })
      .then(d => { if (!cancelled) setData(d); })
      .catch(e => { if (!cancelled) setError(e.message); })
      .finally(() => { if (!cancelled) setLoading(false); });
    return () => { cancelled = true; };
  }, [campaign.id]);

  const tallyEntries = data && data.tally ? Object.entries(data.tally).sort((a, b) => b[1] - a[1]) : [];
  const maxTally = Math.max(...tallyEntries.map(([, c]) => c), 1);

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ maxWidth: 640 }}>
        <div className="modal-head">
          <strong>{(window.appT||(s=>s))('Responses')} — {campaign.title}</strong>
          <button className="btn btn-ghost btn-icon" onClick={onClose}><Icon name="x" size={14}/></button>
        </div>
        <div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 12, maxHeight: '65vh', overflowY: 'auto' }}>
          {loading && <Loading rows={3} label={(window.appT||(s=>s))('Loading responses…')} />}
          {!loading && error && <div style={{ color: 'var(--err)', fontSize: 13 }}>{error}</div>}
          {!loading && !error && data && (
            <>
              <div style={{ display: 'flex', gap: 16, fontSize: 12, color: 'var(--text-2)' }}>
                <span>{(window.appT||(s=>s))('Total:')} <strong>{data.total}</strong></span>
                <span>{(window.appT||(s=>s))('Answered:')} <strong style={{ color: 'var(--ok)' }}>{data.answered}</strong></span>
                <span>{(window.appT||(s=>s))('Pending:')} <strong style={{ color: 'var(--warn)' }}>{data.pending}</strong></span>
                {data.declined > 0 && (
                  <span>{(window.appT||(s=>s))('Declined:')} <strong style={{ color: 'var(--err)' }}>{data.declined}</strong></span>
                )}
              </div>

              {data.declined > 0 && (data.declined_users || []).length > 0 && (
                <div style={{ fontSize: 12, color: 'var(--text-2)' }}>
                  <span style={{ fontWeight: 600 }}>{(window.appT||(s=>s))('Declined by:')}</span>{' '}
                  {(data.declined_users || []).map(u => u || '—').join(', ')}
                </div>
              )}

              {tallyEntries.length > 0 && (
                <div>
                  <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 6, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Tally')}</div>
                  <div style={{ display: 'grid', gap: 6 }}>
                    {tallyEntries.map(([val, count]) => (
                      <div key={val}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 2 }}>
                          <span>{val}</span><span className="mono">{count}</span>
                        </div>
                        <div className="kpi-bar">
                          <div className="kpi-bar-fill" style={{ width: `${(count / maxTally) * 100}%`, background: 'var(--brand)' }} />
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              <div>
                <div style={{ fontSize: 12, fontWeight: 600, marginBottom: 6, color: 'var(--text-2)' }}>{(window.appT||(s=>s))('Responses')}</div>
                {data.responses.length === 0 ? (
                  <Empty icon="·" title={(window.appT||(s=>s))('No responses yet')} />
                ) : (
                  <div style={{ overflowX: 'auto' }}>
                    <table className="t" style={{ width: '100%', fontSize: 12 }}>
                      <thead><tr>
                        <th>{(window.appT||(s=>s))('User')}</th>
                        <th>{(window.appT||(s=>s))('Status')}</th>
                        <th>{(window.appT||(s=>s))('Answer')}</th>
                        <th>{(window.appT||(s=>s))('Profile')}</th>
                        <th>{(window.appT||(s=>s))('Answered')}</th>
                      </tr></thead>
                      <tbody>
                        {data.responses.map((r, i) => (
                          <tr key={i}>
                            <td>{r.user || '—'}</td>
                            <td><Badge kind={r.declined ? 'err' : r.status === 'answered' ? 'ok' : 'mute'}>{(window.appT||(s=>s))(r.declined ? 'declined' : r.status)}</Badge></td>
                            <td style={{ maxWidth: 220, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={r.raw || ''}>
                              {r.answer != null ? String(r.answer) : (r.raw || '—')}
                            </td>
                            <td>{r.applied_to_profile ? <Badge kind="info">{(window.appT||(s=>s))('applied')}</Badge> : '—'}</td>
                            <td className="mono" style={{ fontSize: 11, whiteSpace: 'nowrap' }}>{r.answered_at || '—'}</td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                )}
              </div>
            </>
          )}
        </div>
        <div className="modal-foot">
          <button className="btn btn-ghost" onClick={onClose}>{(window.appT||(s=>s))('Close')}</button>
        </div>
      </div>
    </div>
  );
}

/* ── Main page ── */
function CollectionsPage() {
  const toast = useToast ? useToast() : { push: () => {} };
  const [tab, setTab] = useState('prompts'); // 'prompts' | 'campaigns'

  const [prompts, setPrompts]             = useState([]);
  const [kinds, setKinds]                 = useState([]);
  const [profileFields, setProfileFields] = useState([]);
  const [campaigns, setCampaigns]         = useState([]);
  const [loadingPrompts, setLoadingPrompts]     = useState(true);
  const [loadingCampaigns, setLoadingCampaigns] = useState(true);

  const [editPrompt, setEditPrompt]     = useState(null);
  const [editCampaign, setEditCampaign] = useState(null);
  const [responsesFor, setResponsesFor] = useState(null);

  const loadPrompts = () => {
    setLoadingPrompts(true);
    fetch('/api/collections/prompts', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`)))
      .then(d => {
        setPrompts(d.prompts || []);
        setKinds(d.kinds || []);
        setProfileFields(d.profile_fields || []);
      })
      .catch(e => toast.push({ msg: `${(window.appT||(s=>s))('Prompts fetch failed:')} ${e.message}`, kind: 'err' }))
      .finally(() => setLoadingPrompts(false));
  };

  const loadCampaigns = () => {
    setLoadingCampaigns(true);
    fetch('/api/collections/campaigns', { credentials: 'include' })
      .then(r => r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`)))
      .then(d => setCampaigns(d.campaigns || []))
      .catch(e => toast.push({ msg: `${(window.appT||(s=>s))('Campaigns fetch failed:')} ${e.message}`, kind: 'err' }))
      .finally(() => setLoadingCampaigns(false));
  };

  useEffect(() => { loadPrompts(); loadCampaigns(); }, []);

  const deletePrompt = async (p) => {
    if (!window.confirm(`${(window.appT||(s=>s))('Delete prompt')} "${p.title}"?`)) return;
    try {
      const r = await fetch(`/api/collections/prompts/${p.id}`, { method: 'DELETE', credentials: 'include' });
      if (!r.ok) {
        const b = await r.json().catch(() => null);
        throw new Error(parseDetail(b, r.status));
      }
      const d = await r.json();
      toast.push({ msg: (window.appT||(s=>s))(d.disabled ? 'Built-in prompt disabled' : 'Prompt deleted'), kind: 'ok' });
      loadPrompts();
    } catch (e) {
      toast.push({ msg: `${(window.appT||(s=>s))('Delete failed:')} ${e.message}`, kind: 'err' });
    }
  };

  const deleteCampaign = async (c) => {
    if (!window.confirm(`${(window.appT||(s=>s))('Delete campaign')} "${c.title}"?`)) return;
    try {
      const r = await fetch(`/api/collections/campaigns/${c.id}`, { method: 'DELETE', credentials: 'include' });
      if (!r.ok) {
        const b = await r.json().catch(() => null);
        throw new Error(parseDetail(b, r.status));
      }
      toast.push({ msg: (window.appT||(s=>s))('Campaign deleted'), kind: 'ok' });
      loadCampaigns();
    } catch (e) {
      toast.push({ msg: `${(window.appT||(s=>s))('Delete failed:')} ${e.message}`, kind: 'err' });
    }
  };

  const sendCampaign = async (c) => {
    try {
      const r = await fetch(`/api/collections/campaigns/${c.id}/send`, { method: 'POST', credentials: 'include' });
      if (!r.ok) {
        const b = await r.json().catch(() => null);
        throw new Error(parseDetail(b, r.status));
      }
      const d = await r.json();
      const n = d.queued || 0;
      const blocked = d.blocked || 0;
      const isAr = window.appLang && window.appLang() === 'ar';
      let msg = isAr ? `تم إرسال ${n} رسالة` : `Queued ${n} DM${n === 1 ? '' : 's'}`;
      if (blocked > 0) {
        msg += isAr ? ` · ${blocked} محظور (قائمة عدم المراسلة)` : ` · ${blocked} blocked (never-DM list)`;
      }
      toast.push({ msg, kind: blocked > 0 ? 'warn' : 'ok' });
      loadCampaigns();
    } catch (e) {
      toast.push({ msg: `${(window.appT||(s=>s))('Send failed:')} ${e.message}`, kind: 'err' });
    }
  };

  const promptTitleFor = (id) => {
    const p = prompts.find(x => x.id === id);
    return p ? p.title : null;
  };

  return (
    <div className="page">
      <PageHeader
        title={(window.appT||(s=>s))('Collections')}
        meta={(window.appT||(s=>s))('Bot-driven surveys, polls, profile-fill prompts, and acknowledgements')}
      />

      {/* Section tabs */}
      <div style={{ display: 'flex', gap: 4, marginBottom: 16, borderBottom: '1px solid var(--line)' }}>
        {[['prompts', 'Prompts'], ['campaigns', 'Campaigns']].map(([id, label]) => (
          <button
            key={id}
            onClick={() => setTab(id)}
            style={{
              background: 'none', border: 'none',
              borderBottom: tab === id ? '2px solid var(--brand)' : '2px solid transparent',
              padding: '8px 14px', cursor: 'pointer', fontSize: 13,
              fontWeight: tab === id ? 600 : 400,
              color: tab === id ? 'var(--text-1)' : 'var(--text-3)',
              marginBottom: -1,
            }}
          >
            {(window.appT||(s=>s))(label)}
          </button>
        ))}
      </div>

      {tab === 'prompts' && (
        <div className="card">
          <SectionHeader
            title={(window.appT||(s=>s))('Prompt templates')}
            sub={(window.appT||(s=>s))('Reusable questions the bot can send via a campaign')}
            tip={(window.appT||(s=>s))('Built-in prompts ship with the bot and cannot be deleted — disabling them turns them off instead.')}
            right={
              <button className="btn btn-pri" onClick={() => setEditPrompt({})}>
                <Icon name="plus" size={13}/> {(window.appT||(s=>s))('New prompt')}
              </button>
            }
          />
          {loadingPrompts ? (
            <Loading rows={3} label={(window.appT||(s=>s))('Loading prompts…')} />
          ) : prompts.length === 0 ? (
            <Empty icon="·" title={(window.appT||(s=>s))('No prompts yet')} subtitle={(window.appT||(s=>s))('Create one to start collecting answers.')} />
          ) : (
            <div style={{ overflowX: 'auto' }}>
              <table className="t" style={{ width: '100%' }}>
                <thead>
                  <tr>
                    <th>{(window.appT||(s=>s))('Title')}</th>
                    <th>{(window.appT||(s=>s))('Kind')}</th>
                    <th>{(window.appT||(s=>s))('Profile field')}</th>
                    <th>{(window.appT||(s=>s))('Active')}</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                  {prompts.map(p => (
                    <tr key={p.id}>
                      <td>
                        {p.title}
                        {p.is_builtin && <Badge kind="mute" style={{ marginLeft: 6 }}>{(window.appT||(s=>s))('built-in')}</Badge>}
                      </td>
                      <td>{(window.appT||(s=>s))(COLL_KIND_LABELS[p.kind] || p.kind)}</td>
                      <td className="mono" style={{ fontSize: 11 }}>{p.profile_field || '—'}</td>
                      <td><Badge kind={p.active ? 'ok' : 'mute'}>{p.active ? (window.appT||(s=>s))('active') : (window.appT||(s=>s))('inactive')}</Badge></td>
                      <td style={{ whiteSpace: 'nowrap' }}>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px' }} onClick={() => setEditPrompt(p)}>
                          {(window.appT||(s=>s))('Edit')}
                        </button>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px', color: 'var(--err)' }} onClick={() => deletePrompt(p)}>
                          {p.is_builtin ? (window.appT||(s=>s))('Disable') : (window.appT||(s=>s))('Delete')}
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}

      {tab === 'campaigns' && (
        <div className="card">
          <SectionHeader
            title={(window.appT||(s=>s))('Campaigns')}
            sub={(window.appT||(s=>s))('Schedule or send a prompt to an audience')}
            tip={(window.appT||(s=>s))('A campaign dispatches its prompt to the chosen audience on its schedule, or immediately via Send now.')}
            right={
              <button className="btn btn-pri" disabled={prompts.length === 0} onClick={() => setEditCampaign({})}>
                <Icon name="plus" size={13}/> {(window.appT||(s=>s))('New campaign')}
              </button>
            }
          />
          {loadingCampaigns ? (
            <Loading rows={3} label={(window.appT||(s=>s))('Loading campaigns…')} />
          ) : campaigns.length === 0 ? (
            <Empty icon="·" title={(window.appT||(s=>s))('No campaigns yet')} subtitle={(window.appT||(s=>s))('Create one to start sending a prompt.')} />
          ) : (
            <div style={{ overflowX: 'auto' }}>
              <table className="t" style={{ width: '100%' }}>
                <thead>
                  <tr>
                    <th>{(window.appT||(s=>s))('Title')}</th>
                    <th>{(window.appT||(s=>s))('Prompt')}</th>
                    <th>{(window.appT||(s=>s))('Audience')}</th>
                    <th>{(window.appT||(s=>s))('Schedule')}</th>
                    <th>{(window.appT||(s=>s))('Status')}</th>
                    <th>{(window.appT||(s=>s))('Last run')}</th>
                    <th></th>
                  </tr>
                </thead>
                <tbody>
                  {campaigns.map(c => (
                    <tr key={c.id}>
                      <td>{c.title}</td>
                      <td>{c.prompt_title || promptTitleFor(c.prompt_id) || '—'}</td>
                      <td>
                        {(window.appT||(s=>s))(COLL_AUDIENCE_LABELS[c.audience_kind] || c.audience_kind)}
                        {c.audience_value ? ` · ${c.audience_value}` : ''}
                      </td>
                      <td>
                        {(window.appT||(s=>s))(COLL_SCHEDULE_LABELS[c.schedule_kind] || c.schedule_kind)}
                        {c.schedule_kind === 'weekly' && c.day_of_week != null ? ` (${COLL_DOW_LABELS[c.day_of_week]})` : ''}
                        {c.schedule_kind === 'monthly' && c.day_of_month != null ? ` (${(window.appT||(s=>s))('day')} ${c.day_of_month})` : ''}
                        {c.schedule_kind !== 'once' ? ` @ ${String(c.hour_utc).padStart(2, '0')}:00 UTC` : ''}
                      </td>
                      <td><Badge kind={collStatusBadgeKind(c.status)}>{(window.appT||(s=>s))(COLL_STATUS_LABELS[c.status] || c.status)}</Badge></td>
                      <td className="mono" style={{ fontSize: 11, whiteSpace: 'nowrap' }}>{c.last_run_at || '—'}</td>
                      <td style={{ whiteSpace: 'nowrap' }}>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px' }} onClick={() => sendCampaign(c)}>
                          {(window.appT||(s=>s))('Send now')}
                        </button>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px' }} onClick={() => setResponsesFor(c)}>
                          {(window.appT||(s=>s))('Responses')}
                        </button>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px' }} onClick={() => setEditCampaign(c)}>
                          {(window.appT||(s=>s))('Edit')}
                        </button>
                        <button className="btn btn-ghost" style={{ fontSize: 12, padding: '3px 8px', color: 'var(--err)' }} onClick={() => deleteCampaign(c)}>
                          {(window.appT||(s=>s))('Delete')}
                        </button>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </div>
      )}

      {editPrompt && (
        <CollPromptForm
          prompt={editPrompt.id ? editPrompt : null}
          kinds={kinds.length ? kinds : Object.keys(COLL_KIND_LABELS)}
          profileFields={profileFields}
          onClose={() => setEditPrompt(null)}
          onSaved={loadPrompts}
        />
      )}
      {editCampaign && (
        <CollCampaignForm
          campaign={editCampaign.id ? editCampaign : null}
          prompts={prompts}
          onClose={() => setEditCampaign(null)}
          onSaved={loadCampaigns}
        />
      )}
      {responsesFor && (
        <CollResponsesModal campaign={responsesFor} onClose={() => setResponsesFor(null)} />
      )}
    </div>
  );
}

window.CollectionsPage = CollectionsPage;
