// Deals — pipeline (kanban) + deal drawer. Three-entity model.

// ---------- FilterPill (shared; lives here now) ----------
function FilterPill({ label, value, options, render, onChange }) {
  const [open, setOpen] = useState(false);
  return (
    <div className="relative">
      <button onClick={() => setOpen(o=>!o)} onBlur={() => setTimeout(()=>setOpen(false),150)}
        className="h-8 px-2.5 inline-flex items-center gap-1.5 text-xs font-medium text-slate-700 bg-white border border-slate-200 rounded-md hover:bg-slate-50">
        <span className="text-slate-500">{label}:</span>
        <span>{render ? render(value) : value}</span>
        <Icon.ChevronDown size={12}/>
      </button>
      {open && (
        <div className="absolute top-9 left-0 w-44 bg-white border border-slate-200 rounded-lg shadow-lg p-1 z-30 max-h-72 overflow-y-auto">
          {options.map(opt => (
            <button key={opt} onMouseDown={(e) => { e.preventDefault(); onChange(opt); setOpen(false); }}
              className={`w-full text-left px-2 py-1.5 rounded-md text-xs hover:bg-slate-50 ${value === opt ? 'bg-slate-50 text-slate-900 font-semibold' : 'text-slate-700'}`}>
              {render ? render(opt) : opt}
            </button>
          ))}
        </div>
      )}
    </div>
  );
}
window.FilterPill = FilterPill;

// ============================================================
// DEAL CARD
// ============================================================
function DealCard({ deal, contacts, onSelect, onSelectContact, onDragStart, onDragEnd, dragging }) {
  const owner = OWNERS.find(o => o.id === deal.owner);
  const stage = STAGE_BY_ID[deal.stage];
  const tok = STAGE_TOKENS[stage.color];
  const student = getContact(contacts, deal.studentId);
  const payer = getContact(contacts, deal.payerId);
  const differentPayer = student && payer && student.id !== payer.id;

  const signals = [];
  if (deal.stage === 'CallScheduled' && deal.clarityCallTime) signals.push({ k:'call', label: deal.clarityCallTime, tone:'indigo' });
  if (deal.stage === 'InvoiceSent') signals.push({ k:'inv', label: deal.invoiceNumber || 'Invoiced', tone:'amber' });
  if (deal.stage === 'FulfillmentReady') signals.push({ k:'won', label:'Paid', tone:'emerald' });
  if (deal.followUpCount >= 2 && isActiveStage(deal.stage)) signals.push({ k:'fu', label:`${deal.followUpCount} follow-ups`, tone:'slate' });
  const toneClass = {
    rose:'bg-rose-50 text-rose-700', indigo:'bg-indigo-50 text-indigo-700', amber:'bg-amber-50 text-amber-700',
    emerald:'bg-emerald-50 text-emerald-700', slate:'bg-slate-100 text-slate-700',
  };

  return (
    <div draggable={true}
      onDragStart={(e) => { e.dataTransfer.setData('text/plain', deal.id); e.dataTransfer.effectAllowed='move'; onDragStart(deal.id); }}
      onDragEnd={onDragEnd}
      onClick={() => onSelect(deal)}
      className={`group bg-white border rounded-lg p-3 cursor-pointer transition-all ${
        dragging ? 'opacity-30 border-dashed border-slate-300' : 'border-slate-200 hover:border-slate-300 hover:shadow-sm'
      }`}
      style={{ borderLeft: `3px solid ${tok.dot}` }}>
      <div className="flex items-start justify-between gap-2 mb-2">
        <div className="text-sm font-semibold text-slate-900 leading-snug min-w-0 flex-1">{deal.title}</div>
        {owner && <Avatar name={owner.name} color={owner.color} size={22}/>}
      </div>

      {/* Contact pills */}
      <div className="flex items-center gap-1.5 flex-wrap mb-2">
        {student && (
          <button onClick={(e) => { e.stopPropagation(); onSelectContact(student); }}
            className="flex items-center gap-1 px-1.5 py-0.5 bg-sky-50 hover:bg-sky-100 rounded">
            <Avatar name={contactFullName(student)} size={15}/>
            <span className="text-[10.5px] font-medium text-sky-800">{student.firstName}</span>
            <span className="text-[9px] text-sky-600 uppercase font-semibold tracking-wide">student</span>
          </button>
        )}
        {differentPayer && (
          <button onClick={(e) => { e.stopPropagation(); onSelectContact(payer); }}
            className="flex items-center gap-1 px-1.5 py-0.5 bg-violet-50 hover:bg-violet-100 rounded">
            <Avatar name={contactFullName(payer)} size={15}/>
            <span className="text-[10.5px] font-medium text-violet-800">{payer.firstName}</span>
            <span className="text-[9px] text-violet-600 uppercase font-semibold tracking-wide">payer</span>
          </button>
        )}
      </div>

      <div className="flex flex-wrap items-center gap-1 mb-2">
        <SegmentPill segment={deal.segment}/>
        <span className="text-[11px] text-slate-500 font-medium">{deal.gradeOrYear}</span>
        <span className="text-slate-300">·</span>
        {(deal.subjects||[]).map(s => <SubjectChip key={s} subject={s}/>)}
      </div>

      <div className="flex items-center justify-between gap-2">
        <div className="flex flex-wrap gap-1">
          {signals.map(s => <span key={s.k} className={`text-[10px] px-1.5 py-0.5 rounded font-medium ${toneClass[s.tone]}`}>{s.label}</span>)}
          {(deal.utmSource||'').startsWith('Referral') && (
            <span className="text-[10px] px-1.5 py-0.5 rounded font-medium bg-emerald-50 text-emerald-700 inline-flex items-center gap-1"><Icon.Sparkles size={9}/> Referral</span>
          )}
          {signals.length === 0 && !(deal.utmSource||'').startsWith('Referral') && <span className="text-[10px] text-slate-400">{fmtTimeAgo(deal.addedTime)}</span>}
        </div>
        {deal.customPackagePrice ? (
          <div className="text-[11px] font-semibold text-slate-900 tabular-nums">{fmtZARShort(deal.customPackagePrice)}<span className="text-[10px] text-slate-400 font-normal">/mo</span></div>
        ) : null}
      </div>
    </div>
  );
}
window.DealCard = DealCard;

// ============================================================
// DEALS PIPELINE
// ============================================================
function DealsView({ deals, contacts, onSelectDeal, onSelectContact, onMoveDeal, search }) {
  const [draggingId, setDraggingId] = useState(null);
  const [dragOver, setDragOver] = useState(null);
  const [segmentFilter, setSegmentFilter] = useState('All');
  const [ownerFilter, setOwnerFilter] = useState('All');

  const filtered = deals.filter(d => {
    if (segmentFilter !== 'All' && d.segment !== segmentFilter) return false;
    if (ownerFilter !== 'All' && d.owner !== ownerFilter) return false;
    if (search) {
      const q = search.toLowerCase();
      const student = getContact(contacts, d.studentId);
      const payer = getContact(contacts, d.payerId);
      if (!d.title.toLowerCase().includes(q) &&
          !(student && contactFullName(student).toLowerCase().includes(q)) &&
          !(payer && contactFullName(payer).toLowerCase().includes(q)) &&
          !(d.subjects||[]).some(s => s.toLowerCase().includes(q))) return false;
    }
    return true;
  });

  const columns = STAGES.filter(s => s.id !== 'LostDisqualified' && !s.archived);

  return (
    <div className="px-7 pt-4 pb-6">
      <div className="flex flex-wrap items-center gap-2 mb-4">
        <FilterPill label="Segment" value={segmentFilter} options={['All','HighSchool','University']}
          render={(v) => v === 'HighSchool' ? 'High School' : v} onChange={setSegmentFilter}/>
        <FilterPill label="Owner" value={ownerFilter} options={['All', ...OWNERS.map(o => o.id)]}
          render={(v) => v === 'All' ? 'All' : OWNERS.find(o => o.id === v)?.name || v} onChange={setOwnerFilter}/>
        <div className="flex-1"/>
        <div className="text-xs text-slate-500">{filtered.length} of {deals.length} deals</div>
      </div>

      <div className="flex gap-3 overflow-x-auto pb-2 -mx-7 px-7" style={{ scrollSnapType: 'x proximity' }}>
        {columns.map(stage => {
          const items = filtered.filter(d => d.stage === stage.id);
          const tok = STAGE_TOKENS[stage.color];
          const isOver = dragOver === stage.id;
          const colTotal = items.reduce((s,d) => s + (d.customPackagePrice || 0), 0);
          return (
            <div key={stage.id}
              onDragOver={(e) => { e.preventDefault(); if (dragOver !== stage.id) setDragOver(stage.id); }}
              onDragLeave={() => setDragOver(null)}
              onDrop={(e) => { e.preventDefault(); const id = e.dataTransfer.getData('text/plain'); if (id) onMoveDeal(id, stage.id); setDragOver(null); setDraggingId(null); }}
              className={`w-[290px] shrink-0 rounded-xl flex flex-col border transition-colors ${isOver ? 'border-indigo-300 bg-indigo-50/50' : 'border-slate-200 bg-slate-50/60'}`}
              style={{ scrollSnapAlign: 'start' }}>
              <div className="px-3.5 py-3 flex items-center justify-between border-b border-slate-200 bg-white rounded-t-xl">
                <div className="flex items-center gap-2 min-w-0">
                  <span className="w-2 h-2 rounded-full" style={{ background: tok.dot }}/>
                  <span className="text-sm font-semibold text-slate-900 truncate">{stage.label}</span>
                  <span className="text-xs text-slate-500 tabular-nums">{items.length}</span>
                </div>
                {colTotal > 0 && <span className="text-[11px] text-slate-500 tabular-nums font-medium">{fmtZARShort(colTotal)}/mo</span>}
              </div>
              <div className="p-2.5 flex-1 space-y-2 min-h-[120px]">
                {items.length === 0 && <div className="text-[11px] text-slate-400 text-center py-6 italic">{stage.hint}</div>}
                {items.map(d => (
                  <DealCard key={d.id} deal={d} contacts={contacts}
                    onSelect={onSelectDeal} onSelectContact={onSelectContact}
                    onDragStart={(id) => setDraggingId(id)}
                    onDragEnd={() => { setDraggingId(null); setDragOver(null); }}
                    dragging={draggingId === d.id}/>
                ))}
              </div>
            </div>
          );
        })}

        {/* Lost column */}
        <div onDragOver={(e) => { e.preventDefault(); setDragOver('LostDisqualified'); }}
          onDrop={(e) => { e.preventDefault(); const id = e.dataTransfer.getData('text/plain'); if (id) onMoveDeal(id, 'LostDisqualified'); setDragOver(null); setDraggingId(null); }}
          className={`w-[290px] shrink-0 rounded-xl flex flex-col border transition-colors ${dragOver === 'LostDisqualified' ? 'border-rose-200 bg-rose-50/50' : 'border-slate-200 bg-slate-50/60'}`}>
          <div className="px-3.5 py-3 flex items-center justify-between border-b border-slate-200 bg-white rounded-t-xl">
            <div className="flex items-center gap-2">
              <span className="w-2 h-2 rounded-full" style={{ background: '#F43F5E' }}/>
              <span className="text-sm font-semibold text-slate-900">Lost</span>
              <span className="text-xs text-slate-500 tabular-nums">{filtered.filter(d => d.stage === 'LostDisqualified').length}</span>
            </div>
          </div>
          <div className="p-2.5 flex-1 space-y-2 min-h-[120px]">
            {filtered.filter(d => d.stage === 'LostDisqualified').length === 0 && <div className="text-[11px] text-slate-400 text-center py-6 italic">Drag here to mark lost</div>}
            {filtered.filter(d => d.stage === 'LostDisqualified').map(d => (
              <button key={d.id} onClick={() => onSelectDeal(d)} className="w-full text-left bg-white border border-slate-200 rounded-lg p-3 hover:border-slate-300">
                <div className="text-sm font-medium text-slate-700">{d.title}</div>
                <div className="text-[11px] text-slate-500 mt-0.5">{d.disqualifiedReason || 'Closed lost'}</div>
              </button>
            ))}
          </div>
        </div>
      </div>
    </div>
  );
}
window.DealsView = DealsView;

// ============================================================
// CALLS TODAY
// ============================================================
function CallsView({ deals, contacts, onSelectDeal }) {
  const items = deals.filter(d => d.stage === 'CallScheduled');
  return (
    <div className="px-7 py-5 max-w-[1100px] mx-auto">
      <div className="bg-white border border-slate-200 rounded-xl overflow-hidden">
        {items.length === 0 && <Empty title="No calls scheduled" hint="Book a clarity call from any New or Contacting deal." icon={<Icon.Calendar size={20}/>}/>}
        <ul className="divide-y divide-slate-100">
          {items.map(d => {
            const student = getContact(contacts, d.studentId);
            return (
              <li key={d.id}>
                <button onClick={() => onSelectDeal(d)} className="w-full flex items-center gap-4 px-5 py-4 hover:bg-slate-50 text-left">
                  <div className="text-right shrink-0 w-16">
                    <div className="text-sm font-semibold text-slate-900 tabular-nums">{d.clarityCallTime || '—'}</div>
                    <div className="text-[11px] text-slate-500">{fmtDate(d.clarityCallDate)}</div>
                  </div>
                  <Avatar name={student ? contactFullName(student) : d.title} size={36}/>
                  <div className="flex-1 min-w-0">
                    <div className="text-sm font-medium text-slate-900">{d.title}</div>
                    <div className="text-[11px] text-slate-500 truncate">{d.gradeOrYear} • {(d.subjects||[]).join(', ')}</div>
                  </div>
                  <div className="hidden md:block max-w-md text-[12px] text-slate-600 italic line-clamp-2">"{d.struggleSubjectDetail}"</div>
                </button>
              </li>
            );
          })}
        </ul>
      </div>
    </div>
  );
}
window.CallsView = CallsView;
