// New Lead modal + Reports + Playbook + Settings — INLEARN CRM

function NewLeadModal({ open, onClose, onCreate, leadSources, subjects: subjectCatalog }) {
  const [form, setForm] = useState({
    name: '', email: '', phone: '+27 ',
    segment: 'HighSchool', gradeOrYear: 'Grade 10',
    subjects: [],
    struggleSubjectDetail: '',
    whoNeedsTutoring: 'Myself', studentName: '',
    budgetWilling: 'Yes', budgetFeedback: '',
    whenToStart: 'ASAP', venuePreference: 'Online',
    source: 'Direct',
  });
  if (!open) return null;

  const update = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const toggleSubject = (s) => update('subjects', form.subjects.includes(s)
    ? form.subjects.filter(x => x !== s) : [...form.subjects, s]);

  const handleSubmit = () => {
    if (!form.name.trim()) return;
    // Emit a RAW lead — lands in the Leads inbox to be qualified into Contact + Deal.
    const whoMap = { 'Myself': 'Myself', 'My Son': 'My Son', 'My Daughter': 'My Daughter', 'Someone Else': 'Someone Else' };
    // Try to auto-match an existing contact by phone
    const phone = form.phone.trim();
    const match = (window.__contactsForMatch || []).find(c => c.phone && phone && c.phone.replace(/\s/g,'') === phone.replace(/\s/g,''));
    const rawLead = {
      id: 'l-' + Date.now(),
      name: form.name.trim(),
      email: form.email.trim() || '—',
      phone: phone,
      submittedAt: new Date().toISOString(),
      source: form.source,
      campaign: 'Manual entry',
      formAnswers: {
        whoNeedsTutoring: whoMap[form.whoNeedsTutoring] || 'Myself',
        studentName: form.whoNeedsTutoring === 'Myself' ? null : (form.studentName || null),
        segment: form.segment, gradeOrYear: form.gradeOrYear,
        subjects: form.subjects.length ? form.subjects : ['Mathematics'],
        struggle: form.struggleSubjectDetail || 'Needs personalized tutoring support.',
        budgetWilling: form.budgetWilling, whenToStart: form.whenToStart,
      },
      matchedContactId: match ? match.id : null,
    };
    onCreate(rawLead);
    onClose();
  };

  const Field = ({ label, children, full }) => (
    <div className={full ? 'col-span-2' : ''}>
      <label className="text-[11px] text-slate-500 font-medium uppercase tracking-wider mb-1 block">{label}</label>
      {children}
    </div>
  );
  const inputCls = "w-full h-9 px-3 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900";

  return (
    <Modal open={open} onClose={onClose} width="max-w-xl">
      <div className="px-6 py-4 border-b border-slate-200 flex items-center justify-between">
        <div>
          <div className="text-base font-semibold text-slate-900">New lead</div>
          <div className="text-xs text-slate-500">Capture an inbound enquiry — it lands in your Leads inbox to qualify</div>
        </div>
        <IconButton icon={<Icon.X size={16}/>} onClick={onClose} title="Close"/>
      </div>

      <div className="p-6 overflow-y-auto">
        <div className="grid grid-cols-2 gap-4">
          <Field label="Contact name" full>
            <input className={inputCls} value={form.name} onChange={e => update('name', e.target.value)} placeholder="Full name"/>
          </Field>
          <Field label="Phone">
            <input className={inputCls} value={form.phone} onChange={e => update('phone', e.target.value)} placeholder="+27 …"/>
          </Field>
          <Field label="Email">
            <input className={inputCls} value={form.email} onChange={e => update('email', e.target.value)} placeholder="name@email.com"/>
          </Field>

          <Field label="Who needs tutoring" full>
            <div className="flex gap-1.5">
              {['Myself','My Son','My Daughter','Someone Else'].map(o => (
                <button key={o} onClick={() => update('whoNeedsTutoring', o)}
                  className={`flex-1 h-8 px-2 text-xs rounded-md border transition-colors ${
                    form.whoNeedsTutoring === o
                      ? 'bg-slate-900 text-white border-slate-900'
                      : 'bg-white text-slate-700 border-slate-200 hover:bg-slate-50'
                  }`}>{o}</button>
              ))}
            </div>
          </Field>

          {form.whoNeedsTutoring !== 'Myself' && (
            <Field label="Student name" full>
              <input className={inputCls} value={form.studentName} onChange={e => update('studentName', e.target.value)} placeholder="Student full name"/>
            </Field>
          )}

          <Field label="Level">
            <select className={inputCls} value={form.segment} onChange={e => {
              const seg = e.target.value;
              const grp = seg === 'University' ? 'University' : 'High School';
              const firstGrade = (window.GRADE_OPTIONS?.[grp] || [])[0] || '';
              setForm(f => ({ ...f, segment: seg, gradeOrYear: firstGrade, subjects: [] }));
            }}>
              <option value="HighSchool">High School</option>
              <option value="University">University/College</option>
            </select>
          </Field>
          <Field label={form.segment === 'University' ? 'Year of study' : 'Grade'}>
            <select className={inputCls} value={form.gradeOrYear} onChange={e => update('gradeOrYear', e.target.value)}>
              {(window.GRADE_OPTIONS?.[form.segment === 'University' ? 'University' : 'High School'] || []).map(g => (
                <option key={g} value={g}>{g}</option>
              ))}
            </select>
          </Field>

          <Field label={form.segment === 'University' ? 'Modules' : 'Subjects'} full>
            {(() => {
              const available = (subjectCatalog || []).filter(s => !s.archived && (s.grades || []).includes(form.gradeOrYear));
              if (available.length === 0) {
                return <div className="text-[12px] text-slate-400 italic">No subjects offered for {form.gradeOrYear}. Add one in Settings → Subjects / Modules.</div>;
              }
              return (
                <div className="flex flex-wrap gap-1.5">
                  {available.map(s => {
                    const on = form.subjects.includes(s.name);
                    return (
                      <button key={s.id} onClick={() => toggleSubject(s.name)}
                        className={`h-8 px-3 text-xs rounded-md border transition-colors ${
                          on ? 'bg-indigo-50 text-indigo-700 border-indigo-200' : 'bg-white text-slate-700 border-slate-200 hover:bg-slate-50'
                        }`}>{s.name}</button>
                    );
                  })}
                </div>
              );
            })()}
          </Field>

          <Field label="What's the struggle?" full>
            <textarea rows={2} className={inputCls + ' h-auto py-2'} value={form.struggleSubjectDetail}
              onChange={e => update('struggleSubjectDetail', e.target.value)}
              placeholder="In their words — what they wrote on the form"/>
          </Field>

          <Field label="Budget signal">
            <select className={inputCls} value={form.budgetWilling} onChange={e => update('budgetWilling', e.target.value)}>
              <option value="Yes">Confirmed</option>
              <option value="Unsure">Unsure</option>
              <option value="No">No budget</option>
            </select>
          </Field>
          <Field label="When to start">
            <select className={inputCls} value={form.whenToStart} onChange={e => update('whenToStart', e.target.value)}>
              <option>ASAP</option><option>Next Week</option><option>Next Month</option><option>Flexible</option>
            </select>
          </Field>

          <Field label="Format">
            <select className={inputCls} value={form.venuePreference} onChange={e => update('venuePreference', e.target.value)}>
              <option>Online</option><option>In-person</option><option>Unknown</option>
            </select>
          </Field>
          <Field label="Source">
            <select className={inputCls} value={form.source} onChange={e => update('source', e.target.value)}>
              {(leadSources || []).filter(s => !s.archived).map(s => <option key={s.id}>{s.name}</option>)}
            </select>
          </Field>
        </div>
      </div>

      <div className="px-6 py-3.5 border-t border-slate-200 flex items-center justify-end gap-2 bg-slate-50">
        <Button variant="secondary" onClick={onClose}>Cancel</Button>
        <Button variant="brand" onClick={handleSubmit} disabled={!form.name.trim()}>Create lead</Button>
      </div>
    </Modal>
  );
}
window.NewLeadModal = NewLeadModal;

// ---------- Reports view ----------
function ReportsView({ deals, contacts }) {
  // Revenue by package
  const pkgRevenue = {};
  deals.filter(l => l.stage === 'FulfillmentReady').forEach(l => {
    pkgRevenue[l.selectedPackage || 'Other'] = (pkgRevenue[l.selectedPackage || 'Other'] || 0) + (l.customPackagePrice || 0);
  });

  // Funnel conversion
  const funnel = STAGES.filter(s => s.id !== 'LostDisqualified' && !s.archived).map(s => ({
    ...s, count: deals.filter(l => l.stage === s.id || STAGE_INDEX[l.stage] > STAGE_INDEX[s.id]).length
  }));
  const top = funnel[0]?.count || 1;

  // Top customers by lifetime value
  const topCustomers = (contacts || []).map(c => ({
    c, ltv: lifetimeValue(deals, c.id), referrals: referralsFor(contacts, c.id).length,
  })).filter(x => x.ltv > 0).sort((a,b) => b.ltv - a.ltv).slice(0, 5);
  const ltvMax = Math.max(...topCustomers.map(x => x.ltv), 1);

  return (
    <div className="px-7 py-6 space-y-5 max-w-[1400px] mx-auto">
      <div className="grid grid-cols-1 lg:grid-cols-2 gap-4">
        <div className="bg-white border border-slate-200 rounded-xl p-5">
          <h3 className="text-sm font-semibold text-slate-900 mb-1">Funnel conversion</h3>
          <p className="text-xs text-slate-500 mb-4">Cumulative deals that reached each stage</p>
          <div className="space-y-2.5">
            {funnel.map(s => {
              const tok = STAGE_TOKENS[s.color];
              const pct = (s.count / top) * 100;
              const conv = top ? Math.round((s.count / top) * 100) : 0;
              return (
                <div key={s.id} className="flex items-center gap-3">
                  <div className="w-32 shrink-0"><StageChip stageId={s.id}/></div>
                  <div className="flex-1 h-6 bg-slate-50 rounded-md overflow-hidden">
                    <div className="h-full rounded-md" style={{ width: pct + '%', background: tok.dot, opacity: 0.85 }}/>
                  </div>
                  <div className="w-16 text-right text-sm font-semibold text-slate-900 tabular-nums">{s.count}</div>
                  <div className="w-12 text-right text-xs text-slate-500 tabular-nums">{conv}%</div>
                </div>
              );
            })}
          </div>
        </div>

        <div className="bg-white border border-slate-200 rounded-xl p-5">
          <h3 className="text-sm font-semibold text-slate-900 mb-1">Won revenue by package</h3>
          <p className="text-xs text-slate-500 mb-4">Monthly recurring per tier</p>
          {Object.keys(pkgRevenue).length === 0 ? (
            <Empty title="No wins yet" hint="Closed deals will appear here." icon={<Icon.Money size={18}/>}/>
          ) : (
            <div className="space-y-3">
              {Object.entries(pkgRevenue).sort((a,b)=>b[1]-a[1]).map(([pkg, rev]) => {
                const max = Math.max(...Object.values(pkgRevenue));
                return (
                  <div key={pkg}>
                    <div className="flex items-center justify-between mb-1">
                      <span className="text-[13px] font-medium text-slate-700">{pkg}</span>
                      <span className="text-[13px] font-semibold text-slate-900 tabular-nums">{fmtZAR(rev)}/mo</span>
                    </div>
                    <div className="h-2 bg-slate-100 rounded-full overflow-hidden">
                      <div className="h-full bg-emerald-500 rounded-full" style={{ width: (rev/max)*100 + '%' }}/>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      </div>

      {/* Top customers by lifetime value */}
      <div className="bg-white border border-slate-200 rounded-xl p-5">
        <h3 className="text-sm font-semibold text-slate-900 mb-1">Top customers by lifetime value</h3>
        <p className="text-xs text-slate-500 mb-4">Won monthly revenue per contact — the payoff of the Contacts model</p>
        {topCustomers.length === 0 ? (
          <Empty title="No paying customers yet" hint="Won deals roll up into contact lifetime value here." icon={<Icon.Users size={18}/>}/>
        ) : (
          <div className="space-y-3">
            {topCustomers.map(({ c, ltv, referrals }) => (
              <div key={c.id} className="flex items-center gap-3">
                <Avatar name={contactFullName(c)} size={30}/>
                <div className="w-40 shrink-0">
                  <div className="text-[13px] font-medium text-slate-900 truncate">{contactFullName(c)}</div>
                  <div className="text-[11px] text-slate-500">{c.type}{referrals > 0 ? ` · ${referrals} referral${referrals>1?'s':''}` : ''}</div>
                </div>
                <div className="flex-1 h-5 bg-slate-50 rounded-md overflow-hidden">
                  <div className="h-full bg-emerald-500 rounded-md" style={{ width: (ltv/ltvMax)*100 + '%' }}/>
                </div>
                <div className="w-20 text-right text-[13px] font-semibold text-slate-900 tabular-nums">{fmtZAR(ltv)}<span className="text-[10px] text-slate-400 font-normal">/mo</span></div>
              </div>
            ))}
          </div>
        )}
      </div>

      {/* Owner leaderboard */}
      <div className="bg-white border border-slate-200 rounded-xl p-5">
        <h3 className="text-sm font-semibold text-slate-900 mb-1">Owner leaderboard</h3>
        <p className="text-xs text-slate-500 mb-4">Active deals + won revenue per teammate</p>
        <div className="grid grid-cols-1 md:grid-cols-3 gap-3">
          {OWNERS.filter(o => o.id !== 'system').map(o => {
            const owned = deals.filter(l => l.owner === o.id);
            const won = owned.filter(l => l.stage === 'FulfillmentReady');
            const wonRev = won.reduce((s,l) => s + (l.customPackagePrice || 0), 0);
            return (
              <div key={o.id} className="bg-slate-50 border border-slate-200 rounded-lg p-4">
                <div className="flex items-center gap-2.5 mb-3">
                  <Avatar name={o.name} color={o.color} size={32}/>
                  <div className="text-sm font-semibold text-slate-900">{o.name}</div>
                </div>
                <div className="grid grid-cols-3 gap-2">
                  <div>
                    <div className="text-lg font-semibold text-slate-900 tabular-nums">{owned.length}</div>
                    <div className="text-[10px] text-slate-500 uppercase tracking-wider">Active</div>
                  </div>
                  <div>
                    <div className="text-lg font-semibold text-slate-900 tabular-nums">{won.length}</div>
                    <div className="text-[10px] text-slate-500 uppercase tracking-wider">Wins</div>
                  </div>
                  <div>
                    <div className="text-lg font-semibold text-emerald-700 tabular-nums">{fmtZARShort(wonRev)}</div>
                    <div className="text-[10px] text-slate-500 uppercase tracking-wider">Rev/mo</div>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}
window.ReportsView = ReportsView;

// ---------- Playbook reference + editor view ----------
function PlaybookView({ leads, playbooks, setPlaybooks, stages }) {
  const [editing, setEditing] = useState(null); // playbook id being edited (or 'new' for create mode)
  const [draft, setDraft] = useState({ stageId: '', title: '', instructions: '', actions: [], template: '' });
  const [ConfirmEl, confirm] = useConfirm();

  const activeStages = stages.filter(s => !s.archived);

  // Stages without a playbook yet
  const linkedStageIds = new Set(playbooks.map(p => p.stageId));
  const orphanStages = activeStages.filter(s => !linkedStageIds.has(s.id));

  const startCreate = () => {
    const target = orphanStages[0] || activeStages[0];
    setDraft({
      stageId: target ? target.id : '',
      title: '',
      instructions: '',
      actions: [''],
      template: '',
    });
    setEditing('new');
  };
  const startEdit = (pb) => {
    setDraft({ ...pb, actions: pb.actions.length ? [...pb.actions] : [''] });
    setEditing(pb.id);
  };
  const cancelEdit = () => { setEditing(null); setDraft({ stageId: '', title: '', instructions: '', actions: [], template: '' }); };

  const saveEdit = () => {
    const clean = {
      stageId: draft.stageId,
      title: draft.title.trim() || 'Untitled playbook',
      instructions: draft.instructions.trim(),
      actions: draft.actions.map(a => a.trim()).filter(Boolean),
      template: draft.template.trim(),
    };
    if (editing === 'new') {
      // Prevent duplicate stage links
      if (playbooks.some(p => p.stageId === clean.stageId)) {
        confirm({ title: 'Stage already has a playbook', body: 'Each pipeline stage can have at most one playbook. Edit the existing one instead.', confirmLabel: 'OK', cancelLabel: 'Close', tone: 'info', onConfirm: () => {} });
        return;
      }
      const id = 'pb-' + Date.now();
      setPlaybooks([...playbooks, { id, ...clean }]);
    } else {
      // If user changes the stageId, make sure it doesn't collide
      if (playbooks.some(p => p.id !== editing && p.stageId === clean.stageId)) {
        confirm({ title: 'Stage already has a playbook', body: 'Another playbook is already linked to that stage. Unlink it first.', confirmLabel: 'OK', cancelLabel: 'Close', tone: 'info', onConfirm: () => {} });
        return;
      }
      setPlaybooks(playbooks.map(p => p.id === editing ? { ...p, ...clean } : p));
    }
    cancelEdit();
  };

  const askDelete = (pb) => {
    const linkedStage = stages.find(s => s.id === pb.stageId);
    confirm({
      title: 'Delete playbook?',
      body: <span>Are you sure you want to delete the playbook <strong>“{pb.title}”</strong>{linkedStage && <> linked to <strong>{linkedStage.label}</strong></>}? This cannot be undone.</span>,
      confirmLabel: 'Delete permanently',
      tone: 'danger',
      onConfirm: () => setPlaybooks(playbooks.filter(p => p.id !== pb.id)),
    });
  };

  // Sort playbooks by their stage order
  const orderedPlaybooks = [...playbooks].sort((a,b) => {
    const ai = stages.findIndex(s => s.id === a.stageId);
    const bi = stages.findIndex(s => s.id === b.stageId);
    return (ai === -1 ? 999 : ai) - (bi === -1 ? 999 : bi);
  });

  return (
    <div className="px-7 py-6 max-w-[1000px] mx-auto">
      {ConfirmEl}

      {/* Header */}
      <div className="flex items-end justify-between mb-5">
        <div>
          <h2 className="text-lg font-semibold text-slate-900">Playbooks</h2>
          <p className="text-xs text-slate-500 mt-0.5">Scripts and next actions linked to each pipeline stage. Use <span className="font-mono text-slate-700">{'{placeholders}'}</span> in templates to auto-fill lead data.</p>
        </div>
        <Button variant="brand" size="md" icon={<Icon.Plus size={14}/>} onClick={startCreate}>
          New playbook
        </Button>
      </div>

      {/* Editor for "new" mode */}
      {editing === 'new' && (
        <div className="mb-4">
          <PlaybookEditor draft={draft} setDraft={setDraft} stages={activeStages} playbooks={playbooks}
            isNew onSave={saveEdit} onCancel={cancelEdit}/>
        </div>
      )}

      {/* List */}
      <div className="space-y-3">
        {orderedPlaybooks.length === 0 && editing !== 'new' && (
          <div className="bg-white border border-dashed border-slate-200 rounded-xl p-10 text-center text-sm text-slate-500">
            No playbooks yet. Click "New playbook" to create one and link it to a stage.
          </div>
        )}
        {orderedPlaybooks.map(pb => {
          if (editing === pb.id) {
            return <PlaybookEditor key={pb.id} draft={draft} setDraft={setDraft} stages={activeStages} playbooks={playbooks}
              editingId={pb.id} onSave={saveEdit} onCancel={cancelEdit} onDelete={() => askDelete(pb)}/>;
          }
          return <PlaybookCard key={pb.id} playbook={pb} stages={stages} leads={leads}
            onEdit={() => startEdit(pb)} onDelete={() => askDelete(pb)}/>;
        })}
      </div>

      {/* Orphan stages prompt */}
      {orphanStages.length > 0 && editing !== 'new' && (
        <div className="mt-5 bg-amber-50/60 border border-amber-200 rounded-xl p-4">
          <div className="flex items-start gap-2.5">
            <span className="text-amber-600 mt-0.5"><Icon.Alert size={14}/></span>
            <div className="flex-1">
              <div className="text-sm font-semibold text-amber-900">
                {orphanStages.length} stage{orphanStages.length > 1 ? 's are' : ' is'} missing a playbook
              </div>
              <div className="text-[12px] text-amber-800 mt-0.5">
                {orphanStages.map(s => s.label).join(', ')} — sales reps won't see guidance for {orphanStages.length > 1 ? 'these stages' : 'this stage'} when reviewing a lead.
              </div>
              <button onClick={startCreate} className="text-[12px] font-semibold text-amber-900 hover:underline mt-2">
                Create playbook →
              </button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}
window.PlaybookView = PlaybookView;

function PlaybookCard({ playbook, stages, leads, onEdit, onDelete }) {
  const stage = stages.find(s => s.id === playbook.stageId);
  const tok = stage ? STAGE_TOKENS[stage.color] : null;
  const leadCount = leads.filter(l => l.stage === playbook.stageId).length;

  return (
    <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
      <div className="px-5 py-4 flex items-start justify-between gap-3 border-b border-slate-100">
        <div className="flex items-start gap-3 min-w-0 flex-1">
          {tok && <span className="w-2.5 h-2.5 rounded-full mt-1.5 shrink-0" style={{ background: tok.dot }}/>}
          <div className="min-w-0 flex-1">
            <div className="flex items-center gap-2 flex-wrap">
              <span className="text-sm font-semibold text-slate-900">{playbook.title}</span>
              {stage ? (
                <span className="inline-flex items-center gap-1 text-[11px] font-medium text-slate-600">
                  <span className="text-slate-400">linked to</span>
                  <StageChip stageId={stage.id}/>
                </span>
              ) : (
                <span className="text-[11px] px-1.5 py-0.5 rounded font-medium bg-rose-50 text-rose-700">Unlinked stage</span>
              )}
              {leadCount > 0 && (
                <span className="text-[11px] text-slate-500 tabular-nums">{leadCount} active lead{leadCount > 1 ? 's' : ''}</span>
              )}
            </div>
            <p className="text-[12.5px] text-slate-600 mt-1 leading-relaxed">{playbook.instructions || <span className="italic text-slate-400">No instructions</span>}</p>
          </div>
        </div>
        <div className="flex items-center gap-1 shrink-0">
          <button onClick={onEdit}
            className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded">
            <Icon.Settings size={12}/> Edit
          </button>
          <button onClick={onDelete} title="Delete"
            className="h-7 w-7 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded">
            <Icon.Trash size={12}/>
          </button>
        </div>
      </div>
      <div className="px-5 py-3.5 grid grid-cols-1 md:grid-cols-2 gap-4 bg-slate-50/40">
        <div>
          <div className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider mb-1.5">Next actions</div>
          {playbook.actions.length === 0 ? (
            <div className="text-[12px] text-slate-400 italic">No actions</div>
          ) : (
            <ul className="space-y-1">
              {playbook.actions.map((a, i) => (
                <li key={i} className="flex items-start gap-2 text-[12.5px] text-slate-700">
                  <span className="mt-1.5 w-1 h-1 rounded-full bg-slate-400 shrink-0"/>
                  <span>{a}</span>
                </li>
              ))}
            </ul>
          )}
        </div>
        <div>
          <div className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider mb-1.5">WhatsApp template</div>
          {playbook.template ? (
            <div className="bg-white border border-slate-200 rounded-md p-2.5 text-[12.5px] text-slate-700 whitespace-pre-wrap leading-relaxed">
              {playbook.template}
            </div>
          ) : (
            <div className="text-[12px] text-slate-400 italic">No template</div>
          )}
        </div>
      </div>
    </div>
  );
}

function PlaybookEditor({ draft, setDraft, stages, playbooks, isNew, editingId, onSave, onCancel, onDelete }) {
  const inputCls = "w-full h-9 px-3 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900 placeholder:text-slate-400";

  const setField = (k, v) => setDraft({ ...draft, [k]: v });
  const setAction = (i, v) => {
    const next = [...draft.actions]; next[i] = v; setDraft({ ...draft, actions: next });
  };
  const addAction = () => setDraft({ ...draft, actions: [...draft.actions, ''] });
  const removeAction = (i) => {
    const next = [...draft.actions]; next.splice(i,1);
    setDraft({ ...draft, actions: next.length ? next : [''] });
  };

  // Stage options — show current draft.stageId plus active stages not yet linked (excluding this playbook)
  const availableStages = stages.filter(s => {
    const linked = playbooks.find(p => p.stageId === s.id);
    if (!linked) return true;
    if (editingId && linked.id === editingId) return true;
    return false;
  });

  const insertToken = (token) => {
    setDraft({ ...draft, template: (draft.template || '') + token });
  };

  return (
    <div className="bg-white border border-indigo-300 ring-2 ring-indigo-100 rounded-xl overflow-hidden">
      <div className="px-5 py-3.5 border-b border-slate-200 bg-indigo-50/40 flex items-center justify-between">
        <div className="text-sm font-semibold text-indigo-900">{isNew ? 'New playbook' : 'Edit playbook'}</div>
      </div>

      <div className="p-5 space-y-4">
        <div className="grid grid-cols-1 md:grid-cols-[200px_minmax(0,1fr)] gap-4">
          <div>
            <label className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider block mb-1">Linked stage</label>
            <select className={inputCls} value={draft.stageId} onChange={e => setField('stageId', e.target.value)}>
              {availableStages.length === 0 && <option value="">No stages available</option>}
              {availableStages.map(s => <option key={s.id} value={s.id}>{s.label}</option>)}
            </select>
            <p className="text-[11px] text-slate-500 mt-1">Each stage can have one playbook.</p>
          </div>
          <div>
            <label className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider block mb-1">Title</label>
            <input className={inputCls} value={draft.title} onChange={e => setField('title', e.target.value)} placeholder="e.g. Run the clarity call"/>
          </div>
        </div>

        <div>
          <label className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider block mb-1">Instructions</label>
          <textarea rows={3} className={inputCls + ' h-auto py-2 resize-y'}
            value={draft.instructions} onChange={e => setField('instructions', e.target.value)}
            placeholder="What to do at this stage in plain language."/>
        </div>

        <div>
          <div className="flex items-center justify-between mb-1.5">
            <label className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider">Next actions</label>
            <button onClick={addAction} className="text-[11px] font-semibold text-indigo-600 hover:text-indigo-700 inline-flex items-center gap-1">
              <Icon.Plus size={12}/> Add action
            </button>
          </div>
          <div className="space-y-1.5">
            {draft.actions.map((a, i) => (
              <div key={i} className="flex items-center gap-1.5">
                <input className={inputCls} value={a} onChange={e => setAction(i, e.target.value)}
                  placeholder={`Action ${i+1}`}/>
                <button onClick={() => removeAction(i)} title="Remove action"
                  className="h-9 w-9 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded">
                  <Icon.X size={13}/>
                </button>
              </div>
            ))}
          </div>
        </div>

        <div>
          <label className="text-[10px] text-slate-500 font-semibold uppercase tracking-wider block mb-1">WhatsApp template</label>
          <textarea rows={4} className={inputCls + ' h-auto py-2 resize-y font-mono text-[12.5px]'}
            value={draft.template} onChange={e => setField('template', e.target.value)}
            placeholder="Hi {name}, …"/>
          <div className="mt-2">
            <div className="text-[10px] text-slate-500 font-medium mb-1.5">Insert placeholder:</div>
            <div className="flex flex-wrap gap-1.5">
              {PLAYBOOK_TOKENS.map(t => (
                <button key={t.key} type="button" onClick={() => insertToken(t.key)} title={t.desc}
                  className="text-[11px] font-mono px-1.5 py-0.5 bg-slate-100 hover:bg-indigo-50 hover:text-indigo-700 text-slate-700 rounded">
                  {t.key}
                </button>
              ))}
            </div>
          </div>
        </div>
      </div>

      <div className="px-5 py-3.5 border-t border-slate-200 bg-slate-50 flex items-center justify-between">
        {!isNew && onDelete ? (
          <Button size="sm" variant="ghost" icon={<Icon.Trash size={12}/>} onClick={onDelete} className="text-rose-600 hover:bg-rose-50">
            Delete playbook
          </Button>
        ) : <span/>}
        <div className="flex items-center gap-2">
          <Button size="sm" variant="secondary" onClick={onCancel}>Cancel</Button>
          <Button size="sm" variant="brand" icon={<Icon.Check size={13}/>} onClick={onSave}
            disabled={!draft.stageId || !draft.title.trim()}>
            {isNew ? 'Create playbook' : 'Save changes'}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ---------- Settings view ----------
function SettingsView({ leadSources, setLeadSources, stages, setStages, leads, setLeads, team, setTeam }) {
  const [tab, setTab] = useState('sources');
  const [ConfirmEl, confirm] = useConfirm();
  return (
    <div className="px-7 py-6 max-w-[1200px] mx-auto">
      {ConfirmEl}
      {/* Header */}
      <div className="mb-5 flex items-end justify-between">
        <div>
          <h2 className="text-lg font-semibold text-slate-900">System settings</h2>
          <p className="text-xs text-slate-500 mt-0.5">Configure how your sales pipeline runs</p>
        </div>
        <Button variant="danger" size="sm" icon={<Icon.Refresh size={13}/>}
          onClick={() => confirm({
            title: 'Reset to defaults?',
            body: 'This will wipe ALL leads, lead sources, pipeline stages and notes, restoring the factory state. This action cannot be undone.',
            confirmLabel: 'Reset everything',
            tone: 'danger',
            onConfirm: () => {
              localStorage.removeItem('INLEARN_CRM_V2');
              localStorage.removeItem('INLEARN_CRM_SOURCES_V2');
              localStorage.removeItem('INLEARN_CRM_STAGES_V2');
              localStorage.removeItem('INLEARN_CRM_PLAYBOOKS_V2');
              location.reload();
            },
          })}>
          Reset to defaults
        </Button>
      </div>

      {/* Tabs */}
      <div className="border-b border-slate-200 mb-5">
        <div className="flex gap-1">
          {[
            { id: 'sources', label: 'Lead Sources', icon: <Icon.Inbox size={14}/> },
            { id: 'stages',  label: 'Pipeline Stages', icon: <Icon.Layers size={14}/> },
            { id: 'team',    label: 'Team', icon: <Icon.Users size={14}/> },
          ].map(t => (
            <button key={t.id} onClick={() => setTab(t.id)}
              className={`inline-flex items-center gap-2 px-3.5 py-2.5 text-[13px] font-medium -mb-px border-b-2 transition-colors ${
                tab === t.id ? 'border-slate-900 text-slate-900' : 'border-transparent text-slate-500 hover:text-slate-700'
              }`}>
              {t.icon} {t.label}
            </button>
          ))}
        </div>
      </div>

      {tab === 'sources' && <LeadSourcesManager leadSources={leadSources} setLeadSources={setLeadSources}/>}
      {tab === 'stages'  && <PipelineStagesManager stages={stages} setStages={setStages} leads={leads} setLeads={setLeads}/>}
      {tab === 'team'    && <TeamPanel team={team} setTeam={setTeam} deals={leads}/>}
    </div>
  );
}
window.SettingsView = SettingsView;

// ---------- Lead Sources Manager ----------
function LeadSourcesManager({ leadSources, setLeadSources }) {
  const [name, setName] = useState('');
  const [description, setDescription] = useState('');
  const [editing, setEditing] = useState(null); // id being edited
  const [editForm, setEditForm] = useState({ name: '', description: '' });
  const [ConfirmEl, confirm] = useConfirm();

  const active = leadSources.filter(s => !s.archived);
  const archived = leadSources.filter(s => s.archived);
  const [listView, setListView] = useState('active');

  const addSource = () => {
    const trimmed = name.trim();
    if (!trimmed) return;
    if (leadSources.some(s => s.name.toLowerCase() === trimmed.toLowerCase())) {
      confirm({ title: 'Source already exists', body: `A source called “${trimmed}” already exists. Pick a different name.`, confirmLabel: 'OK', cancelLabel: 'Close', tone: 'info', onConfirm: () => {} });
      return;
    }
    const id = 'src-' + Date.now();
    setLeadSources([...leadSources, { id, name: trimmed, description: description.trim(), isSystem: false, archived: false }]);
    setName(''); setDescription('');
  };

  const startEdit = (s) => { setEditing(s.id); setEditForm({ name: s.name, description: s.description || '' }); };
  const saveEdit = () => {
    const trimmed = editForm.name.trim();
    if (!trimmed) return;
    setLeadSources(leadSources.map(s => s.id === editing ? { ...s, name: trimmed, description: editForm.description.trim() } : s));
    setEditing(null);
  };

  const askArchive = (s) => {
    confirm({
      title: 'Archive lead source?',
      body: <span>Are you sure you want to archive <strong>“{s.name}”</strong>? This will hide it from the New Lead form and reports. You can restore it any time.</span>,
      confirmLabel: 'Yes, archive',
      tone: 'warning',
      onConfirm: () => setLeadSources(leadSources.map(x => x.id === s.id ? { ...x, archived: true } : x)),
    });
  };
  const restoreSource = (id) => setLeadSources(leadSources.map(s => s.id === id ? { ...s, archived: false } : s));

  const askDelete = (s) => {
    confirm({
      title: 'Permanently delete channel?',
      body: <span>Are you sure you want to permanently delete the lead source <strong>“{s.name}”</strong>? This action cannot be undone, and will remove this campaign attribution channel.</span>,
      confirmLabel: 'Delete permanently',
      tone: 'danger',
      onConfirm: () => setLeadSources(leadSources.filter(x => x.id !== s.id)),
    });
  };

  const inputCls = "w-full h-9 px-3 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900 placeholder:text-slate-400";

  return (
    <div className="grid grid-cols-1 lg:grid-cols-[320px_minmax(0,1fr)] gap-5">
      {ConfirmEl}
      {/* Left: create form */}
      <div className="bg-white border border-slate-200 rounded-xl p-5 h-fit lg:sticky lg:top-20">
        <div className="text-[11px] text-slate-500 font-semibold uppercase tracking-wider mb-3">Create lead source</div>

        <label className="text-[11px] text-slate-500 font-medium block mb-1">Name <span className="text-rose-500">*</span></label>
        <input className={inputCls} value={name} onChange={e => setName(e.target.value)}
          placeholder="e.g. LinkedIn, Flyers Campaign"/>

        <label className="text-[11px] text-slate-500 font-medium block mt-3 mb-1">Description <span className="text-slate-400">(optional)</span></label>
        <textarea rows={3} className={inputCls + ' h-auto py-2 resize-none'}
          value={description} onChange={e => setDescription(e.target.value)}
          placeholder="Where these inquiries come from and how to handle them"/>

        <Button variant="brand" size="md" className="w-full mt-4" icon={<Icon.Plus size={14}/>}
          onClick={addSource} disabled={!name.trim()}>
          Add lead source
        </Button>

        <div className="mt-4 p-3 bg-indigo-50/50 border border-indigo-100 rounded-md">
          <div className="flex items-start gap-2">
            <span className="text-indigo-500 mt-0.5"><Icon.Sparkles size={13}/></span>
            <p className="text-[11.5px] text-indigo-900 leading-relaxed">
              New sources appear instantly as options in the <strong>New Lead</strong> form and in lead-source reports.
            </p>
          </div>
        </div>
      </div>

      {/* Right: list */}
      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <SegmentedTabs value={listView} onChange={setListView}
            tabs={[
              { id: 'active',   label: 'Active',   count: active.length,   dot: '#10B981' },
              { id: 'archived', label: 'Archived', count: archived.length, dot: '#94A3B8' },
            ]}/>
        </div>

        {listView === 'active' && (
          active.length === 0 ? (
            <div className="bg-white border border-dashed border-slate-200 rounded-xl p-10 text-center text-sm text-slate-500">
              No active sources. Add one on the left.
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {active.map(s => (
                <LeadSourceCard key={s.id} source={s}
                  isEditing={editing === s.id}
                  editForm={editForm} setEditForm={setEditForm}
                  onStartEdit={() => startEdit(s)}
                  onCancelEdit={() => setEditing(null)}
                  onSaveEdit={saveEdit}
                  onArchive={() => askArchive(s)}
                  onDelete={() => askDelete(s)}
                />
              ))}
            </div>
          )
        )}

        {listView === 'archived' && (
          archived.length === 0 ? (
            <div className="bg-white border border-dashed border-slate-200 rounded-xl p-10 text-center text-sm text-slate-500">
              No archived channels. Keep inactive campaigns clean by archiving them here.
            </div>
          ) : (
            <div className="grid grid-cols-1 md:grid-cols-2 gap-3">
              {archived.map(s => (
                <div key={s.id} className="bg-slate-50 border border-slate-200 rounded-xl p-4 opacity-80">
                  <div className="flex items-start justify-between gap-2 mb-1">
                    <div className="flex items-center gap-2 min-w-0">
                      <span className="w-1.5 h-1.5 rounded-sm bg-slate-400"/>
                      <span className="text-sm font-semibold text-slate-700 truncate">{s.name}</span>
                      <span className="text-[10px] px-1.5 py-0.5 bg-slate-200 text-slate-600 rounded font-medium uppercase tracking-wider">Archived</span>
                    </div>
                  </div>
                  <p className="text-[12px] text-slate-500 line-clamp-2 mb-3">{s.description || '—'}</p>
                  <div className="flex items-center gap-1.5 border-t border-slate-200 pt-2">
                    <Button size="sm" variant="secondary" icon={<Icon.Refresh size={12}/>} onClick={() => restoreSource(s.id)}>
                      Restore
                    </Button>
                    <Button size="sm" variant="ghost" icon={<Icon.Trash size={12}/>} onClick={() => askDelete(s)}
                      className="text-rose-600 hover:bg-rose-50">
                      Delete
                    </Button>
                  </div>
                </div>
              ))}
            </div>
          )
        )}
      </div>
    </div>
  );
}

function LeadSourceCard({ source, isEditing, editForm, setEditForm, onStartEdit, onCancelEdit, onSaveEdit, onArchive, onDelete }) {
  const inputCls = "w-full h-8 px-2.5 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900";

  if (isEditing) {
    return (
      <div className="bg-white border border-indigo-300 ring-2 ring-indigo-100 rounded-xl p-4">
        <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1">Name</label>
        <input className={inputCls} value={editForm.name} onChange={e => setEditForm({ ...editForm, name: e.target.value })} autoFocus/>
        <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mt-2.5 mb-1">Description</label>
        <textarea rows={2} className={inputCls + ' h-auto py-1.5 resize-none'} value={editForm.description}
          onChange={e => setEditForm({ ...editForm, description: e.target.value })}/>
        <div className="flex items-center justify-end gap-1.5 mt-3 border-t border-slate-100 pt-2.5">
          <Button size="sm" variant="ghost" onClick={onCancelEdit}>Cancel</Button>
          <Button size="sm" variant="brand" icon={<Icon.Check size={12}/>} onClick={onSaveEdit} disabled={!editForm.name.trim()}>Save</Button>
        </div>
      </div>
    );
  }

  return (
    <div className="bg-white border border-slate-200 rounded-xl p-4 hover:border-slate-300 transition-colors group">
      <div className="flex items-start justify-between gap-2 mb-1">
        <div className="flex items-center gap-2 min-w-0">
          <span className="w-1.5 h-1.5 rounded-sm bg-slate-900"/>
          <span className="text-sm font-semibold text-slate-900 truncate">{source.name}</span>
          {source.isSystem && (
            <span className="text-[9px] px-1.5 py-0.5 bg-slate-100 text-slate-600 rounded font-medium uppercase tracking-wider">Default</span>
          )}
        </div>
      </div>
      <p className="text-[12px] text-slate-500 line-clamp-2 min-h-[32px]">
        {source.description || <span className="italic text-slate-400">No description</span>}
      </p>
      <div className="flex items-center gap-1 border-t border-slate-100 pt-2.5 mt-3">
        <button onClick={onStartEdit}
          className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded">
          <Icon.Settings size={12}/> Edit
        </button>
        <button onClick={onArchive}
          className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded">
          <Icon.Inbox size={12}/> Archive
        </button>
        <div className="flex-1"/>
        <button onClick={onDelete} title="Delete permanently"
          className="h-7 w-7 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded">
          <Icon.Trash size={12}/>
        </button>
      </div>
    </div>
  );
}

// ---------- Pipeline Stages manager ----------
function PipelineStagesManager({ stages, setStages, leads, setLeads }) {
  const [name, setName] = useState('');
  const [hint, setHint] = useState('');
  const [color, setColor] = useState('indigo');
  const [editing, setEditing] = useState(null);
  const [editForm, setEditForm] = useState({ label: '', hint: '', color: 'indigo' });
  const [ConfirmEl, confirm] = useConfirm();

  const colorOptions = Object.keys(STAGE_TOKENS);
  const active = stages.filter(s => !s.archived);
  const archived = stages.filter(s => s.archived);
  const [listView, setListView] = useState('active');

  const addStage = () => {
    const trimmed = name.trim();
    if (!trimmed) return;
    if (stages.some(s => s.label.toLowerCase() === trimmed.toLowerCase())) {
      confirm({ title: 'Stage already exists', body: `A stage called “${trimmed}” already exists. Pick a different name.`, confirmLabel: 'OK', cancelLabel: 'Close', tone: 'info', onConfirm: () => {} });
      return;
    }
    const id = 'stage-' + Date.now();
    const newStage = { id, label: trimmed, short: trimmed, hint: hint.trim() || 'Custom pipeline stage', color, archived: false };
    const lostIdx = stages.findIndex(s => s.id === 'LostDisqualified');
    const next = [...stages];
    if (lostIdx >= 0) next.splice(lostIdx, 0, newStage); else next.push(newStage);
    setStages(next);
    setName(''); setHint(''); setColor('indigo');
  };

  const startEdit = (s) => { setEditing(s.id); setEditForm({ label: s.label, hint: s.hint || '', color: s.color }); };
  const saveEdit = () => {
    const trimmed = editForm.label.trim();
    if (!trimmed) return;
    setStages(stages.map(s => s.id === editing
      ? { ...s, label: trimmed, short: trimmed.length > 14 ? trimmed.slice(0,12)+'…' : trimmed, hint: editForm.hint.trim() || s.hint, color: editForm.color }
      : s));
    setEditing(null);
  };

  const askArchive = (s) => {
    const inStage = leads.filter(l => l.stage === s.id).length;
    confirm({
      title: 'Archive pipeline stage?',
      body: <span>
        Are you sure you want to archive <strong>“{s.label}”</strong>? This will hide the column from the pipeline and reports.
        {inStage > 0 && <> <strong>{inStage} lead{inStage>1?'s':''}</strong> currently in this stage will be hidden until you restore it.</>}
      </span>,
      confirmLabel: 'Yes, archive',
      tone: 'warning',
      onConfirm: () => setStages(stages.map(x => x.id === s.id ? { ...x, archived: true } : x)),
    });
  };

  const restoreStage = (id) => setStages(stages.map(s => s.id === id ? { ...s, archived: false } : s));

  const askDelete = (s) => {
    if (stages.filter(x => !x.archived).length <= 1 && !s.archived) {
      confirm({ title: 'Cannot delete', body: 'You need at least one active stage in the pipeline.', confirmLabel: 'OK', cancelLabel: 'Close', tone: 'info', onConfirm: () => {} });
      return;
    }
    const inStage = leads.filter(l => l.stage === s.id);
    const fallback = stages.find(x => x.id !== s.id && !x.archived && x.id !== 'LostDisqualified') || stages.find(x => x.id !== s.id);

    confirm({
      title: 'Permanently delete stage?',
      body: <span>
        Are you sure you want to permanently delete <strong>“{s.label}”</strong>? This action cannot be undone.
        {inStage.length > 0 && fallback && <><br/><br/><strong>{inStage.length} lead{inStage.length>1?'s':''}</strong> in this stage will be moved to <strong>“{fallback.label}”</strong>.</>}
      </span>,
      confirmLabel: 'Delete permanently',
      tone: 'danger',
      onConfirm: () => {
        if (inStage.length > 0 && fallback) {
          setLeads(leads.map(l => l.stage === s.id ? { ...l, stage: fallback.id } : l));
        }
        setStages(stages.filter(x => x.id !== s.id));
      },
    });
  };

  const moveStage = (id, dir) => {
    const idx = stages.findIndex(s => s.id === id);
    const target = idx + dir;
    if (target < 0 || target >= stages.length) return;
    const next = [...stages];
    [next[idx], next[target]] = [next[target], next[idx]];
    setStages(next);
  };

  const inputCls = "w-full h-9 px-3 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900 placeholder:text-slate-400";

  return (
    <div className="grid grid-cols-1 lg:grid-cols-[320px_minmax(0,1fr)] gap-5">
      {ConfirmEl}
      {/* Left: create form */}
      <div className="bg-white border border-slate-200 rounded-xl p-5 h-fit lg:sticky lg:top-20">
        <div className="text-[11px] text-slate-500 font-semibold uppercase tracking-wider mb-3">Create pipeline stage</div>

        <label className="text-[11px] text-slate-500 font-medium block mb-1">Name <span className="text-rose-500">*</span></label>
        <input className={inputCls} value={name} onChange={e => setName(e.target.value)}
          placeholder="e.g. Demo Booked, Trial Period"/>

        <label className="text-[11px] text-slate-500 font-medium block mt-3 mb-1">Description</label>
        <textarea rows={2} className={inputCls + ' h-auto py-2 resize-none'}
          value={hint} onChange={e => setHint(e.target.value)}
          placeholder="What happens at this stage?"/>

        <label className="text-[11px] text-slate-500 font-medium block mt-3 mb-1.5">Color</label>
        <ColorPicker value={color} onChange={setColor} options={colorOptions}/>

        <Button variant="brand" size="md" className="w-full mt-4" icon={<Icon.Plus size={14}/>}
          onClick={addStage} disabled={!name.trim()}>
          Add stage
        </Button>

        <div className="mt-4 p-3 bg-indigo-50/50 border border-indigo-100 rounded-md">
          <div className="flex items-start gap-2">
            <span className="text-indigo-500 mt-0.5"><Icon.Sparkles size={13}/></span>
            <p className="text-[11.5px] text-indigo-900 leading-relaxed">
              New stages appear instantly as columns in the pipeline kanban and as options in lead movement.
            </p>
          </div>
        </div>
      </div>

      {/* Right: list */}
      <div className="space-y-3">
        <div className="flex items-center justify-between">
          <SegmentedTabs value={listView} onChange={setListView}
            tabs={[
              { id: 'active',   label: 'Active',   count: active.length,   dot: '#10B981' },
              { id: 'archived', label: 'Archived', count: archived.length, dot: '#94A3B8' },
            ]}/>
        </div>

        {listView === 'active' && (
          active.length === 0 ? (
            <div className="bg-white border border-dashed border-slate-200 rounded-xl p-10 text-center text-sm text-slate-500">
              No active stages. Add one on the left.
            </div>
          ) : (
            <div className="space-y-2">
              {active.map((s, i) => (
                <StageCard key={s.id} stage={s} index={i} total={active.length}
                  leadCount={leads.filter(l => l.stage === s.id).length}
                  isEditing={editing === s.id}
                  editForm={editForm} setEditForm={setEditForm}
                  colorOptions={colorOptions}
                  onStartEdit={() => startEdit(s)}
                  onCancelEdit={() => setEditing(null)}
                  onSaveEdit={saveEdit}
                  onArchive={() => askArchive(s)}
                  onDelete={() => askDelete(s)}
                  onMoveUp={() => moveStage(s.id, -1)}
                  onMoveDown={() => moveStage(s.id, 1)}
                />
              ))}
            </div>
          )
        )}

        {listView === 'archived' && (
          archived.length === 0 ? (
            <div className="bg-white border border-dashed border-slate-200 rounded-xl p-10 text-center text-sm text-slate-500">
              No archived stages. Archive a stage to hide its column without losing the leads inside.
            </div>
          ) : (
            <div className="space-y-2">
              {archived.map(s => {
                const tok = STAGE_TOKENS[s.color];
                const inStage = leads.filter(l => l.stage === s.id).length;
                return (
                  <div key={s.id} className="bg-slate-50 border border-slate-200 rounded-xl p-3.5 flex items-center gap-3 opacity-90">
                    <span className="w-2.5 h-2.5 rounded-full" style={{ background: tok.dot }}/>
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span className="text-sm font-semibold text-slate-700">{s.label}</span>
                        <span className="text-[10px] px-1.5 py-0.5 bg-slate-200 text-slate-600 rounded font-medium uppercase tracking-wider">Archived</span>
                        {inStage > 0 && <span className="text-[11px] text-amber-700">{inStage} lead{inStage>1?'s':''} hidden</span>}
                      </div>
                      <div className="text-[11.5px] text-slate-500 truncate">{s.hint}</div>
                    </div>
                    <Button size="sm" variant="secondary" icon={<Icon.Refresh size={12}/>} onClick={() => restoreStage(s.id)}>Restore</Button>
                    <button onClick={() => askDelete(s)} title="Delete permanently"
                      className="h-7 w-7 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded">
                      <Icon.Trash size={12}/>
                    </button>
                  </div>
                );
              })}
            </div>
          )
        )}
      </div>
    </div>
  );
}

function StageCard({ stage, index, total, leadCount, isEditing, editForm, setEditForm, colorOptions, onStartEdit, onCancelEdit, onSaveEdit, onArchive, onDelete, onMoveUp, onMoveDown }) {
  const tok = STAGE_TOKENS[stage.color];
  const inputCls = "w-full h-8 px-2.5 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900";

  if (isEditing) {
    return (
      <div className="bg-white border border-indigo-300 ring-2 ring-indigo-100 rounded-xl p-4">
        <div className="grid grid-cols-[1fr_auto] gap-3 items-end mb-3">
          <div>
            <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1">Stage name</label>
            <input className={inputCls} value={editForm.label} onChange={e => setEditForm({ ...editForm, label: e.target.value })} autoFocus/>
          </div>
        </div>
        <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1">Description</label>
        <textarea rows={2} className={inputCls + ' h-auto py-1.5 resize-none mb-3'} value={editForm.hint}
          onChange={e => setEditForm({ ...editForm, hint: e.target.value })}/>
        <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1.5">Color</label>
        <ColorPicker value={editForm.color} onChange={(c) => setEditForm({ ...editForm, color: c })} options={colorOptions}/>
        <div className="flex items-center justify-end gap-1.5 mt-3 border-t border-slate-100 pt-2.5">
          <Button size="sm" variant="ghost" onClick={onCancelEdit}>Cancel</Button>
          <Button size="sm" variant="brand" icon={<Icon.Check size={12}/>} onClick={onSaveEdit} disabled={!editForm.label.trim()}>Save</Button>
        </div>
      </div>
    );
  }

  return (
    <div className="bg-white border border-slate-200 rounded-xl p-3.5 hover:border-slate-300 transition-colors flex items-center gap-3">
      {/* Reorder */}
      <div className="flex flex-col">
        <button onClick={onMoveUp} disabled={index === 0} title="Move up"
          className="h-4 w-5 inline-flex items-center justify-center text-slate-400 hover:text-slate-700 disabled:opacity-30 disabled:cursor-not-allowed">
          <Icon.ArrowUp size={10}/>
        </button>
        <button onClick={onMoveDown} disabled={index === total - 1} title="Move down"
          className="h-4 w-5 inline-flex items-center justify-center text-slate-400 hover:text-slate-700 disabled:opacity-30 disabled:cursor-not-allowed">
          <Icon.ArrowDown size={10}/>
        </button>
      </div>

      {/* Position number */}
      <span className="text-[11px] text-slate-400 font-mono w-5 tabular-nums">{String(index+1).padStart(2,'0')}</span>

      {/* Dot + label */}
      <span className="w-2.5 h-2.5 rounded-full shrink-0" style={{ background: tok.dot }}/>
      <div className="flex-1 min-w-0">
        <div className="flex items-center gap-2">
          <span className="text-sm font-semibold text-slate-900">{stage.label}</span>
          {leadCount > 0 && (
            <span className="text-[10px] px-1.5 py-0.5 rounded font-medium tabular-nums"
              style={{ background: tok.soft, color: tok.text }}>
              {leadCount} lead{leadCount > 1 ? 's' : ''}
            </span>
          )}
        </div>
        <div className="text-[11.5px] text-slate-500 truncate">{stage.hint}</div>
      </div>

      {/* Actions */}
      <div className="flex items-center gap-1">
        <button onClick={onStartEdit}
          className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded">
          <Icon.Settings size={12}/> Edit
        </button>
        <button onClick={onArchive}
          className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded">
          <Icon.Inbox size={12}/> Archive
        </button>
        <button onClick={onDelete} title="Delete permanently"
          className="h-7 w-7 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded">
          <Icon.Trash size={12}/>
        </button>
      </div>
    </div>
  );
}

function ColorPicker({ value, onChange, options }) {
  return (
    <div className="flex flex-wrap gap-1.5">
      {options.map(c => {
        const tok = STAGE_TOKENS[c];
        const active = c === value;
        return (
          <button key={c} type="button" onClick={() => onChange(c)} title={c}
            className={`h-7 w-7 rounded-md border-2 flex items-center justify-center transition-all ${
              active ? 'border-slate-900 shadow-sm scale-105' : 'border-transparent hover:border-slate-200'
            }`}
            style={{ background: tok.soft }}>
            <span className="w-3 h-3 rounded-full" style={{ background: tok.dot }}/>
          </button>
        );
      })}
    </div>
  );
}

// ---------- Team panel ----------
function TeamPanel({ team, setTeam, deals }) {
  const [ConfirmEl, confirm] = useConfirm();
  const [name, setName] = useState('');
  const [role, setRole] = useState('Sales Coordinator');
  const [editing, setEditing] = useState(null);
  const [editForm, setEditForm] = useState({ name: '', role: '' });

  const palette = ['#4F46E5','#059669','#D97706','#DB2777','#0891B2','#7C3AED','#B45309','#0EA5E9'];
  const members = (team || []).filter(o => o.id !== 'system');
  const inputCls = "w-full h-9 px-3 text-sm bg-white border border-slate-200 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-100 focus:border-slate-300 text-slate-900 placeholder:text-slate-400";

  const initialsOf = (n) => n.split(' ').filter(Boolean).slice(0,2).map(s => s[0]).join('').toUpperCase();

  const add = () => {
    const trimmed = name.trim(); if (!trimmed) return;
    const id = 'm-' + Date.now();
    const color = palette[members.length % palette.length];
    setTeam([...(team || []), { id, name: trimmed, initials: initialsOf(trimmed), color, role: role.trim() || 'Member' }]);
    setName(''); setRole('Sales Coordinator');
  };
  const startEdit = (m) => { setEditing(m.id); setEditForm({ name: m.name, role: m.role || 'Member' }); };
  const saveEdit = () => {
    const trimmed = editForm.name.trim(); if (!trimmed) return;
    setTeam(team.map(m => m.id === editing ? { ...m, name: trimmed, initials: initialsOf(trimmed), role: editForm.role.trim() || 'Member' } : m));
    setEditing(null);
  };
  const remove = (m) => {
    const count = (deals || []).filter(d => d.owner === m.id).length;
    confirm({
      title: 'Remove team member?',
      body: <span>Are you sure you want to remove <strong>{m.name}</strong> from the team?{count > 0 && <> Their <strong>{count}</strong> assigned lead{count>1?'s':''} will become unassigned.</>} This cannot be undone.</span>,
      confirmLabel: 'Remove member', tone: 'danger',
      onConfirm: () => setTeam(team.filter(x => x.id !== m.id)),
    });
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-[320px_minmax(0,1fr)] gap-5">
      {ConfirmEl}
      {/* Add member */}
      <div className="bg-white border border-slate-200 rounded-xl p-5 h-fit lg:sticky lg:top-20">
        <div className="text-[11px] text-slate-500 font-semibold uppercase tracking-wider mb-3">Add team member</div>
        <label className="text-[11px] text-slate-500 font-medium block mb-1">Full name</label>
        <input className={inputCls} value={name} onChange={e => setName(e.target.value)} placeholder="e.g. Lebo Dlamini"
          onKeyDown={e => { if (e.key === 'Enter') add(); }}/>
        <label className="text-[11px] text-slate-500 font-medium block mt-3 mb-1">Role</label>
        <input className={inputCls} value={role} onChange={e => setRole(e.target.value)} placeholder="Sales Coordinator"/>
        <Button variant="brand" size="md" className="w-full mt-4" icon={<Icon.Plus size={14}/>} onClick={add} disabled={!name.trim()}>Add member</Button>
        <div className="mt-4 p-3 bg-indigo-50/50 border border-indigo-100 rounded-md">
          <div className="flex items-start gap-2">
            <span className="text-indigo-500 mt-0.5"><Icon.Sparkles size={13}/></span>
            <p className="text-[11.5px] text-indigo-900 leading-relaxed">New members appear instantly in the <strong>Assign</strong> picker on every lead and as deal owners.</p>
          </div>
        </div>
      </div>

      {/* List */}
      <div>
        <div className="flex items-center gap-2 mb-3">
          <h3 className="text-sm font-semibold text-slate-900">Team members</h3>
          <span className="text-xs text-slate-500 tabular-nums">({members.length})</span>
        </div>
        <div className="space-y-2">
          {members.length === 0 && (
            <div className="bg-white border border-dashed border-slate-200 rounded-xl p-8 text-center text-sm text-slate-500">No team members yet. Add one on the left.</div>
          )}
          {members.map(m => {
            const count = (deals || []).filter(d => d.owner === m.id).length;
            return editing === m.id ? (
              <div key={m.id} className="bg-white border border-indigo-300 ring-2 ring-indigo-100 rounded-xl p-4">
                <div className="grid grid-cols-2 gap-3">
                  <div>
                    <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1">Name</label>
                    <input className={inputCls} value={editForm.name} onChange={e => setEditForm({...editForm, name: e.target.value})} autoFocus/>
                  </div>
                  <div>
                    <label className="text-[10px] text-slate-500 font-medium uppercase tracking-wider block mb-1">Role</label>
                    <input className={inputCls} value={editForm.role} onChange={e => setEditForm({...editForm, role: e.target.value})}/>
                  </div>
                </div>
                <div className="flex items-center justify-end gap-1.5 mt-3 border-t border-slate-100 pt-2.5">
                  <Button size="sm" variant="ghost" onClick={() => setEditing(null)}>Cancel</Button>
                  <Button size="sm" variant="brand" icon={<Icon.Check size={12}/>} onClick={saveEdit} disabled={!editForm.name.trim()}>Save</Button>
                </div>
              </div>
            ) : (
              <div key={m.id} className="bg-white border border-slate-200 rounded-xl p-3.5 flex items-center gap-3 hover:border-slate-300 transition-colors">
                <Avatar name={m.name} color={m.color} size={36}/>
                <div className="flex-1 min-w-0">
                  <div className="text-sm font-medium text-slate-900 truncate">{m.name}</div>
                  <div className="text-[11px] text-slate-500">{m.role || 'Member'}{count > 0 ? ` · ${count} lead${count>1?'s':''} assigned` : ''}</div>
                </div>
                <button onClick={() => startEdit(m)} className="h-7 px-2 inline-flex items-center gap-1.5 text-[11px] font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 rounded"><Icon.Settings size={12}/> Edit</button>
                <button onClick={() => remove(m)} title="Remove" className="h-7 w-7 inline-flex items-center justify-center text-slate-400 hover:text-rose-600 hover:bg-rose-50 rounded"><Icon.Trash size={12}/></button>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}
