/* AAU CRM — Sales shared: MAKE THE MOVE drawer, qualify gate, priority helpers.
   Reused by Work Queue, Kanban, and 360 profile. */

// ---- session lead store (moves persist across Sales screens) ----
const LeadStore = (function () {
  let data = AAU.leads.map(l => ({ ...l, qualify: { ...l.qualify }, history: [] }));
  const subs = new Set();
  const emit = () => subs.forEach(f => f());
  return {
    all: () => data,
    byId: (id) => data.find(l => l.id === id),
    add: (lead) => {
      const maxN = data.reduce((m, l) => Math.max(m, parseInt(String(l.id).replace(/\D/g, ''), 10) || 0), 0);
      const id = 'L' + (maxN + 1);
      const today = new Date().toISOString().slice(0, 10);
      const full = {
        id, name: '', company: '', role: '', phone: '', fb: '', email: '',
        bizModel: '', industry: 'F&B', chainSize: '', revenue: 0, region: '',
        painpoints: [], courseInterest: '', source: 'direct', channel: 'zalo',
        stage: 's_raw', branch: null, grade: 'C', dealValue: 0,
        sla: 'ok', slaLeft: '24h', hot: false, signal: null, daysInStage: 0,
        nextAction: '', objection: null,
        qualify: { bizModel: false, painpoint: false, courseMap: false, budget: false },
        assignedTo: '', createdAt: today,
        ...lead,
      };
      const st = AAU.stageById(full.stage);
      if (st) full.branch = st.branch;
      full.history = [{ from: '—', to: st ? st.code : '1.0', reason: 'Tạo mới (nhập tay)', trigger: 'manual', at: 'vừa xong' }];
      data = [full, ...data];
      emit();
      return id;
    },
    move: (id, toCode, reason, trigger) => {
      const s = AAU.stageByCode(toCode); if (!s) return;
      data = data.map(l => {
        if (l.id !== id) return l;
        const from = AAU.stageById(l.stage);
        return { ...l, stage: s.id, daysInStage: 0, history: [{ from: from ? from.code : '?', to: s.code, reason, trigger, at: 'vừa xong' }, ...(l.history || [])] };
      });
      emit();
    },
    toggleQualify: (id, k) => { data = data.map(l => l.id === id ? { ...l, qualify: { ...l.qualify, [k]: !l.qualify[k] } } : l); emit(); },
    note: (id, text) => { if (!text || !text.trim()) return; data = data.map(l => l.id === id ? { ...l, history: [{ note: true, reason: text.trim(), at: 'vừa xong' }, ...(l.history || [])] } : l); emit(); },
    update: (id, patch) => { data = data.map(l => l.id === id ? { ...l, ...patch } : l); emit(); },
    assign: (id, userId) => { data = data.map(l => l.id === id ? { ...l, assignedTo: userId } : l); emit(); },
    sub: (f) => { subs.add(f); return () => subs.delete(f); },
    // re-seed from window.AAU.leads (used after backend hydration in live mode)
    reload: () => { data = AAU.leads.map(l => ({ ...l, qualify: { ...l.qualify }, history: l.history || [] })); emit(); },
  };
})();
function useLeads() {
  const [, bump] = useState(0);
  useEffect(() => LeadStore.sub(() => bump(x => x + 1)), []);
  return LeadStore.all();
}

// ---- Sales access control (viewer scope + permissions) ----
const AccessStore = (function () {
  let viewerId = localStorage.getItem('sales_viewer') || AAU.currentUser.id;
  if (!AAU.users.find(u => u.id === viewerId)) viewerId = AAU.currentUser.id;
  const subs = new Set();
  // Resolve to a REAL user, never undefined: viewerId may point at a user that
  // was deleted (or that only existed in the mock seed before live hydrate
  // replaced AAU.users). Falling back to currentUser → first user keeps every
  // screen that reads viewer.id from crashing.
  const resolve = () => AAU.users.find(u => u.id === viewerId)
    || AAU.users.find(u => u.id === (AAU.currentUser && AAU.currentUser.id))
    || AAU.users[0];
  return {
    get: resolve,
    set: (id) => { viewerId = id; localStorage.setItem('sales_viewer', id); subs.forEach(f => f()); },
    sub: (f) => { subs.add(f); return () => subs.delete(f); },
  };
})();
function useViewer() {
  const [, bump] = useState(0);
  useEffect(() => AccessStore.sub(() => bump(x => x + 1)), []);
  return AccessStore.get();
}
const SalesAccess = {
  buOf: (lead) => (AAU.courseById(lead.courseInterest) || {}).group,
  canSee: (lead, v) => {
    if (!v) return true;
    if (v.buScope === 'all') return true;
    return (v.buScope || []).includes(lead.courseInterest) || lead.assignedTo === v.id;
  },
  scoped: (leads, v) => leads.filter(l => SalesAccess.canSee(l, v)),
  canEdit: (v) => v && (v.access === 'edit' || v.access === 'manage'),
  canManage: (v) => v && v.access === 'manage',
  // members phụ trách đúng KHÓA của lead (+ leader/manager)
  eligibleAssignees: (lead) => {
    return AAU.users.filter(u => u.salesRole === 'member' && (u.buScope === 'all' || (u.buScope || []).includes(lead.courseInterest)));
  },
  members: () => AAU.users.filter(u => u.salesRole === 'member'),
  accessMeta: { view: { label: 'Chỉ xem', tone: 'neutral', icon: 'eye' }, edit: { label: 'Sửa & move', tone: 'info', icon: 'edit' }, manage: { label: 'Toàn quyền', tone: 'success', icon: 'shield' } },
};

// Áp lại phân quyền khóa đã lưu (per-course scope) cho toàn app
(function applySavedScope() {
  try {
    const saved = JSON.parse(localStorage.getItem('aau.salesScope.v1') || '{}');
    AAU.users.forEach(u => { if (saved[u.id] !== undefined) u.buScope = saved[u.id]; });
  } catch (e) { /* ignore */ }
})();

// Áp lại stage đã chỉnh (thêm/xóa) cho toàn app — Kanban, bảng, config đều dùng chung
(function applySavedStages() {
  try {
    const sv = JSON.parse(localStorage.getItem('aau.stages.v1') || '{}');
    (sv.added || []).forEach(s => { if (!AAU.stages.find(x => x.id === s.id)) AAU.stages.push(s); });
    (sv.removed || []).forEach(id => { const i = AAU.stages.findIndex(x => x.id === id); if (i >= 0) AAU.stages.splice(i, 1); });
  } catch (e) { /* ignore */ }
})();

function AccessNote({ viewer }) {
  const m = SalesAccess.accessMeta[viewer.access] || {};
  const scopeTxt = viewer.buScope === 'all' ? 'tất cả khóa' : (viewer.buScope || []).map(id => (AAU.courseById(id) || {}).code).filter(Boolean).join(' · ');
  return (
    <div className="access-note">
      <Avatar name={viewer.name} color={viewer.color} size={26} />
      <div className="f1" style={{ minWidth: 0 }}>
        <div className="t12 fw7 row aic g6">{viewer.name} <span className="t11 subtle fw5">· {viewer.title}</span></div>
        <div className="t11 subtle ellip">Phạm vi: {scopeTxt}</div>
      </div>
      <span className={'badge ' + (m.tone || 'neutral')}><Icon name={m.icon} size={12} />{m.label}</span>
    </div>
  );
}

function AssignDrawer({ lead, onClose }) {
  const cur = AAU.users.find(u => u.id === lead.assignedTo);
  const g = SalesAccess.buOf(lead);
  const eligible = SalesAccess.eligibleAssignees(lead);
  const course = AAU.courseById(lead.courseInterest);
  const [pick, setPick] = useState(lead.assignedTo || '');
  return (
    <Drawer title="Phân công lead" onClose={onClose} width={460}
      footer={<><Button onClick={onClose}>Hủy</Button><Button variant="primary" icon="check" disabled={!pick || pick === lead.assignedTo} onClick={() => { LeadStore.assign(lead.id, pick); onClose(); }}>Lưu phân công</Button></>}>
      <div className="col g16">
        <div className="mtm-hero"><div className="t14 fw7">{lead.company}</div><div className="t12 muted mt2">{lead.name} · {lead.bizModel}</div></div>
        <div>
          <div className="mtm-k mb4">Khóa quan tâm (quyết định ai phụ trách)</div>
          <div className="row aic g8"><span className="badge info">{course ? course.code + ' · ' + course.name : '—'}</span></div>
          <div className="t11 subtle mt6">Chỉ Sales BU được gán khóa này (hoặc Leader) mới được phân công.</div>
        </div>
        <div>
          <div className="mtm-k mb6">Phân cho Sales BU</div>
          <div className="col g8">
            {eligible.map(u => (
              <div key={u.id} className={'assign-opt' + (pick === u.id ? ' on' : '')} onClick={() => setPick(u.id)}>
                <Avatar name={u.name} color={u.color} size={30} />
                <div className="f1"><div className="t13 fw6">{u.name}</div><div className="t11 subtle">{u.title}</div></div>
                {pick === u.id && <Icon name="check" size={16} color="#0e7c4a" />}
              </div>
            ))}
            {eligible.length === 0 && <div className="t12 subtle">Chưa có Sales BU nào được gán khóa này.</div>}
          </div>
        </div>
        {cur && <div className="t11 subtle">Hiện tại: {cur.name}</div>}
      </div>
    </Drawer>
  );
}

// ---- priority scoring (Data Priority Flow) ----
const DATA_PRIORITY_RANK = {
  // deal hot first, then qualify-fresh, then nurture, then lead-side hot
  '3.5': 100, '3.6': 92, '3.7': 86, '1.6': 84, '3.1': 80, '1.4': 78,
  '3.8': 60, '3.2': 58, '2.3': 56, '3.3': 50, '2.1': 48, '3.4': 44,
  '1.2': 40, '3.0': 38, '2.2': 34, '1.5': 30, '1.0': 20, '1.3': 0,
  '4.0': 70, '4.1': 40, '4.2': 40, '4.3': 24, '4.6': 96, '5.0': 52, '5.1': 30, '5.2': 22, '5.3': 12,
};
function leadPriority(lead) {
  const st = AAU.stageById(lead.stage); if (!st) return 0;
  let score = DATA_PRIORITY_RANK[st.code] || 10;
  if (lead.hot) score += 14;
  if (lead.signal) score += { HIGH: 12, MED: 6, LOW: 1 }[lead.signal.level] || 0;
  if (lead.sla === 'bad') score += 16; else if (lead.sla === 'warn') score += 8;
  if (lead.dealValue) score += Math.min(8, lead.dealValue / 30000000);
  return Math.round(score);
}
function priorityTier(lead) {
  const st = AAU.stageById(lead.stage);
  if (lead.sla === 'bad') return { key: 'now', label: 'Quá hạn — xử lý NGAY', color: '#c4320a' };
  if (st && st.flags.includes('hotlane')) return { key: 'now', label: 'Hot lane — close mode', color: '#ea580c' };
  if (lead.signal && lead.signal.level === 'HIGH') return { key: 'now', label: 'Hot signal HIGH', color: '#ea580c' };
  if (st && ['1.6', '3.1', '1.4'].includes(st.code)) return { key: 'next', label: 'Critical window', color: '#9a6700' };
  if (lead.sla === 'warn') return { key: 'next', label: 'Sắp tới hạn SLA', color: '#9a6700' };
  return { key: 'later', label: 'Nurture / theo dõi', color: '#5a6472' };
}

function QualifyGate({ lead, editable, onToggle }) {
  const conds = (window.PLAYBOOK && PLAYBOOK.qualifyConditions) || [];
  const score = conds.filter(c => lead.qualify[c.key]).length;
  return (
    <div className="col g8">
      <div className="row jcsb aic">
        <span className="t12 fw7 subtle">4 ĐIỀU KIỆN QUALIFY</span>
        <span className={'badge ' + (score === 4 ? 'success' : score >= 2 ? 'warning' : 'neutral')}>{score}/4</span>
      </div>
      <div className="qgate">
        {conds.map(c => {
          const on = !!lead.qualify[c.key];
          return (
            <div key={c.key} className={'qgate-item' + (on ? ' on' : '')} onClick={editable ? () => onToggle(c.key) : undefined} style={{ cursor: editable ? 'pointer' : 'default' }}>
              <span className="qgate-ic"><Icon name={on ? 'check' : c.icon} size={14} /></span>
              <span className="t12 fw6">{c.label}</span>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function MakeTheMoveDrawer({ lead, onClose, onMove, onToggleQualify, readOnly }) {
  const st = AAU.stageById(lead.stage);
  const g = pbGuide(st.code) || {};
  const meta = (window.PLAYBOOK && PLAYBOOK.scriptTypeMeta[g.type]) || {};
  const [pending, setPending] = useState(null); // {toCode, trigger}
  const [reason, setReason] = useState('');
  const isLead = st.funnel === 'lead' || st.funnel === 'leadb';
  const qScore = Object.values(lead.qualify).filter(Boolean).length;
  const course = AAU.courseById(lead.courseInterest);
  const assignee = AAU.users.find(u => u.id === lead.assignedTo);
  const chLabel = (AAU.channels[lead.channel] || {}).label || lead.channel;
  const srcLabel = (AAU.sourceMeta[lead.source] || {}).label || lead.source;
  const [qedit, setQedit] = useState(false);
  const [draft, setDraft] = useState({});
  const [noteText, setNoteText] = useState('');
  const beginEdit = () => { setDraft({ phone: lead.phone || '', email: lead.email || '', dealValue: lead.dealValue || 0, grade: lead.grade || 'C', nextAction: lead.nextAction || '', objection: lead.objection || '' }); setQedit(true); };
  const saveEdit = () => { LeadStore.update(lead.id, { phone: draft.phone, email: draft.email, dealValue: Number(draft.dealValue) || 0, grade: draft.grade, nextAction: draft.nextAction, objection: draft.objection || null }); setQedit(false); };
  const addNote = () => { LeadStore.note(lead.id, noteText); setNoteText(''); };

  const startMove = (opt) => { setPending({ toCode: opt.code, trigger: opt.trigger }); setReason(opt.trigger ? '' : ''); };
  const confirm = () => {
    if (!reason.trim()) return;
    onMove(lead.id, pending.toCode, reason.trim(), pending.trigger);
    setPending(null);
  };

  return (
    <Drawer title={<span className="row aic g8">{lead.name} <span className="t12 subtle fw5">· MAKE THE MOVE</span></span>} onClose={onClose} width={560}
      footer={<><Button onClick={onClose}>Đóng</Button><Button variant="primary" icon="user" onClick={() => navigate('/leads/' + lead.id)}>Mở hồ sơ 360°</Button></>}>
      <div className="col g18">
        {/* identity + stage */}
        <div className="mtm-hero">
          <div className="row jcsb ais">
            <div>
              <div className="row aic g8"><span className="t15 fw7">{lead.company}</span><GradeBadge grade={lead.grade} />{lead.hot && <HotIcon />}</div>
              <div className="t12 muted mt2">{lead.role} · {lead.bizModel} · {lead.chainSize} · {lead.region}</div>
            </div>
            <div className="col aie g4">
              <StageChip stageId={lead.stage} />
              <SLATag sla={lead.sla} left={lead.slaLeft} />
            </div>
          </div>
        </div>

        {/* ── 360 snapshot + sửa nhanh ── */}
        <div className="mtm-snap">
          <div className="row jcsb aic mb12">
            <span className="t12 fw7 subtle">THÔNG TIN 360° NHANH</span>
            {!readOnly && (qedit
              ? <span className="row g6"><Button size="sm" onClick={() => setQedit(false)}>Hủy</Button><Button size="sm" variant="primary" icon="check" onClick={saveEdit}>Lưu</Button></span>
              : <Button size="sm" icon="edit" onClick={beginEdit}>Sửa nhanh</Button>)}
          </div>
          <div className="mtm-info">
            <div><div className="mtm-k">SĐT</div>{qedit ? <input className="input" value={draft.phone} onChange={e => setDraft({ ...draft, phone: e.target.value })} /> : <div className="t12 fw6">{lead.phone || '—'}</div>}</div>
            <div><div className="mtm-k">Email</div>{qedit ? <input className="input" value={draft.email} onChange={e => setDraft({ ...draft, email: e.target.value })} /> : <div className="t12 fw6 ellip">{lead.email || '—'}</div>}</div>
            <div><div className="mtm-k">Kênh</div><div className="t12 fw6">{chLabel}</div></div>
            <div><div className="mtm-k">Nguồn</div><div className="t12 fw6">{srcLabel}</div></div>
            <div><div className="mtm-k">Ngành · Quy mô</div><div className="t12 fw6">{lead.industry} · {lead.chainSize}</div></div>
            <div><div className="mtm-k">Khu vực</div><div className="t12 fw6">{lead.region}</div></div>
            <div><div className="mtm-k">Doanh thu DN</div><div className="t12 fw6">{AAU.fmtVNDm(lead.revenue)}</div></div>
            <div><div className="mtm-k">Khóa quan tâm</div><div className="t12 fw6">{course ? course.code + ' · ' + course.name : '—'}</div></div>
            <div><div className="mtm-k">Giá trị deal</div>{qedit ? <input className="input" type="number" value={draft.dealValue} onChange={e => setDraft({ ...draft, dealValue: e.target.value })} /> : <div className="t12 fw6">{lead.dealValue ? AAU.fmtVNDm(lead.dealValue) : '—'}</div>}</div>
            <div><div className="mtm-k">Grade</div>{qedit ? <Select value={draft.grade} onChange={v => setDraft({ ...draft, grade: v })} options={['A', 'B', 'C', 'D'].map(x => ({ value: x, label: x }))} /> : <div className="t12 fw6">{lead.grade}</div>}</div>
            <div><div className="mtm-k">Phụ trách</div><div className="t12 fw6">{assignee ? assignee.name : 'Chưa gán'}</div></div>
            <div><div className="mtm-k">Tạo · trong stage</div><div className="t12 fw6">{AAU.fmtDate(lead.createdAt)} · {lead.daysInStage}d</div></div>
          </div>
          <div className="col g8" style={{ marginTop: 12 }}>
            <div><div className="mtm-k" style={{ marginBottom: 3 }}>Next action</div>{qedit ? <input className="input" value={draft.nextAction} onChange={e => setDraft({ ...draft, nextAction: e.target.value })} /> : <div className="t12">{lead.nextAction || '—'}</div>}</div>
            <div><div className="mtm-k" style={{ marginBottom: 3 }}>Objection</div>{qedit ? <input className="input" value={draft.objection} placeholder="—" onChange={e => setDraft({ ...draft, objection: e.target.value })} /> : <div className="t12">{lead.objection || '—'}</div>}</div>
            {lead.painpoints && lead.painpoints.length > 0 && <div><div className="mtm-k" style={{ marginBottom: 4 }}>Painpoints</div><div className="row g6 wrap">{lead.painpoints.map((p, i) => <span key={i} className="tag">{p}</span>)}</div></div>}
          </div>
        </div>

        {/* ── hoạt động gần đây + ghi chú nhanh ── */}
        <div className="col g8">
          <div className="t12 fw7 subtle">HOẠT ĐỘNG GẦN ĐÂY</div>
          {!readOnly && <div className="row g6"><input className="input f1" placeholder="Thêm ghi chú nhanh…" value={noteText} onChange={e => setNoteText(e.target.value)} onKeyDown={e => { if (e.key === 'Enter') addNote(); }} /><Button icon="plus" disabled={!noteText.trim()} onClick={addNote}>Ghi</Button></div>}
          <div className="col g6">
            {(lead.history || []).slice(0, 4).map((h, i) => (
              <div key={i} className="mtm-hist">
                <Icon name={h.note ? 'message' : 'arrowRight'} size={13} color={h.note ? '#7c3aed' : '#0e7c4a'} />
                <span className="t12 f1">{h.note ? h.reason : <span><b>{h.from} → {h.to}</b> · {h.reason}</span>}</span>
                <span className="t11 subtle" style={{ flexShrink: 0 }}>{h.at}</span>
              </div>
            ))}
            {(!lead.history || lead.history.length === 0) && <div className="t12 subtle">Chưa có hoạt động — thêm ghi chú hoặc chuyển stage để bắt đầu timeline.</div>}
          </div>
        </div>

        {/* signal */}
        {lead.signal && (
          <div className="mtm-signal">
            <div className="row aic g8"><Icon name="fire" size={15} color="#e8590c" /><span className="t12 fw7" style={{ color: '#c4320a' }}>HOT SIGNAL · {lead.signal.level}</span></div>
            <div className="t12 mt4" style={{ color: '#8a3a18' }}>{lead.signal.text}</div>
            {st.code !== '3.5' && !st.flags.includes('won') && !readOnly && (
              <Button size="sm" variant="critical" icon="bolt" style={{ marginTop: 8 }} onClick={() => startMove({ code: '3.5', trigger: 'Hot signal detected' })}>Đẩy lên Hot lane 3.5</Button>
            )}
          </div>
        )}

        {/* stage guide */}
        <div className="col g10">
          <div className="row aic g8"><ScriptTag type={g.type} /><span className="t13 fw7">{st.code} · {g.title || st.name}</span>{g.lane && <LaneTag lane={g.lane === 'Hot' ? 'hot' : g.lane === 'Nurture' ? 'nurture' : null} />}</div>
          {g.def && <div className="t12 muted">{g.def}</div>}
          <div className="mtm-grid">
            <div><div className="mtm-k">Mục tiêu stage</div><div className="t12">{g.objective}</div></div>
            <div><div className="mtm-k">Trạng thái KH</div><div className="t12">{g.state}</div></div>
          </div>
          <div className="row g8 wrap t11 subtle">
            {g.pic && <span className="mtm-meta"><Icon name="user" size={12} />PIC: {g.pic}</span>}
            {(g.timer || st.slaText) && <span className="mtm-meta"><Icon name="clock" size={12} />{g.timer || st.slaText}</span>}
            {g.kpi && <span className="mtm-meta"><Icon name="target" size={12} />{g.kpi}</span>}
          </div>
        </div>

        {/* script panel */}
        {(g.openings && g.openings.length > 0 || g.send && g.send.length > 0) && (
          <div className="mtm-script">
            <div className="row aic g8 mb8"><Icon name="message" size={15} color={meta.color} /><span className="t12 fw7">KỊCH BẢN — {meta.label}</span><span className="t11 subtle">{meta.desc}</span></div>
            {g.openings && g.openings.length > 0 && (
              <div className="col g6 mb10">
                {g.openings.map((o, i) => <div key={i} className="mtm-line">{o}</div>)}
              </div>
            )}
            {g.send && g.send.length > 0 && (
              <div>
                <div className="mtm-k mb4"><Icon name="paperclip" size={12} /> Tài liệu / hành động gửi</div>
                <div className="row g6 wrap">{g.send.map((s, i) => <span key={i} className="tag">{s}</span>)}</div>
              </div>
            )}
            {g.cadence && <div className="t11 subtle mt8"><Icon name="clock" size={11} /> Cadence: {g.cadence}</div>}
          </div>
        )}

        {/* qualify gate for lead funnel */}
        {isLead && st.code !== '1.0' && st.code !== '1.3' && (
          <div className="mtm-qualify">
            <QualifyGate lead={lead} editable={!readOnly && !!onToggleQualify} onToggle={k => onToggleQualify && onToggleQualify(lead.id, k)} />
            {qScore < 4 && <div className="t11 sla-warn mt6"><Icon name="alert" size={11} /> Chưa đủ 4 điều kiện — không nên move sang 3.1 Qualify.</div>}
          </div>
        )}

        {/* next stage / make the move */}
        <div className="col g8">
          <div className="t12 fw7 subtle">MAKE THE MOVE — chuyển stage</div>
          {readOnly && <div className="pb-note"><Icon name="lock" size={14} /><span>Vai trò chỉ-xem: bạn không có quyền chuyển stage lead này.</span></div>}
          {!readOnly && !pending && (
            <div className="col g6">
              {(g.next || []).map((opt, i) => {
                const ts = AAU.stageByCode(opt.code);
                return (
                  <div key={i} className="mtm-next" onClick={() => startMove(opt)}>
                    <div className="row aic g8">
                      {ts && <span className="stage-dot" style={{ background: ts.color }} />}
                      <span className="t12 fw6">{opt.code} {ts ? ts.name : ''}</span>
                    </div>
                    <span className="t11 muted f1" style={{ textAlign: 'right' }}>{opt.trigger}</span>
                    <Icon name="arrowRight" size={14} />
                  </div>
                );
              })}
            </div>
          )}
          {pending && (
            <div className="mtm-confirm">
              <div className="row aic g8 t13 mb10" style={{ padding: 10, borderRadius: 8, background: '#fff' }}>
                <StageChip stageId={lead.stage} /><Icon name="arrowRight" size={15} /><StageChip stageId={(AAU.stageByCode(pending.toCode) || {}).id} />
              </div>
              <Field label="Lý do chuyển (bắt buộc — PRE-MOVE CHECKLIST)">
                <textarea className="input" rows={2} placeholder="Signal nào trigger move này?" value={reason} onChange={e => setReason(e.target.value)} autoFocus />
              </Field>
              <div className="t11 subtle mt6">Trigger: <b>{pending.trigger || 'Thủ công'}</b></div>
              <div className="row g8 mt12 jce">
                <Button onClick={() => setPending(null)}>Hủy</Button>
                <Button variant="primary" disabled={!reason.trim()} onClick={confirm}>Xác nhận chuyển</Button>
              </div>
            </div>
          )}
        </div>
      </div>
    </Drawer>
  );
}

Object.assign(window, { leadPriority, priorityTier, QualifyGate, MakeTheMoveDrawer, DATA_PRIORITY_RANK, LeadStore, useLeads, AccessStore, useViewer, SalesAccess, AccessNote, AssignDrawer });

// ───────────── Báo cáo Sales: chất lượng data + mức độ tương tác ─────────────
function RepBar({ label, n, total, color, suffix }) {
  const p = total ? Math.round((n / total) * 100) : 0;
  return (
    <div style={{ marginBottom: 11 }}>
      <div className="row jcsb t12"><span>{label}</span><span className="fw6">{AAU.fmtNum(n)}{suffix || ''} · {p}%</span></div>
      <div style={{ height: 8, borderRadius: 5, background: 'var(--p-bg-surface-tertiary)', overflow: 'hidden', marginTop: 3 }}>
        <div style={{ width: p + '%', height: '100%', background: color || '#1a4fa3', transition: 'width .3s' }} />
      </div>
    </div>
  );
}

function SalesReport() {
  const live = !!(window.API && window.API.enabled);
  const [r, setR] = useState(null);
  const [sig, setSig] = useState(null);
  const [err, setErr] = useState(null);
  const [tick, setTick] = useState(0);
  useEffect(() => {
    if (!live || !window.API.salesReport) return;
    let alive = true; setErr(null);
    window.API.salesReport().then(d => { if (alive) setR(d); }).catch(e => { if (alive) setErr((e && e.message) || 'lỗi'); });
    if (window.API.buyingSignals) window.API.buyingSignals().then(d => { if (alive) setSig(d); }).catch(() => { });
    return () => { alive = false; };
  }, [live, tick]);
  const openChat = cid => { window.NavIntent = { inboxConv: cid }; navigate('/inbox'); };

  const head = <PageHead title="Báo cáo Sales" subtitle="Chất lượng data + mức độ tương tác — đang làm hiệu quả tới đâu, còn bỏ sót gì."
    actions={live ? <Button icon="refresh" onClick={() => setTick(t => t + 1)}>Làm mới</Button> : null} />;
  if (!live) return <div className="page wide">{head}<EmptyState icon="chart" title="Cần chế độ LIVE" desc="Mở ?api=http://localhost:8080 để xem báo cáo từ dữ liệu thật." /></div>;
  if (!r) return <div className="page wide">{head}<div className="muted t13" style={{ padding: 20 }}>{err ? 'Lỗi tải báo cáo: ' + err : 'Đang tải báo cáo…'}</div></div>;

  const q = r.dataQuality, i = r.interaction, e = r.effectiveness, total = r.totalLeads;
  const maxStage = Math.max(1, ...r.byStage.map(s => s.count));
  const sugg = [
    'Thời gian phản hồi đầu (SLA): khách nhắn → bao lâu sales trả lời.',
    'Tuổi lead trong stage: lead "kẹt" ở Raw Lead bao lâu (cần đẩy).',
    'Tỉ lệ qualify & chuyển stage theo nguồn/kênh (kênh nào ra lead chất).',
    'Khóa quan tâm suy từ chat → map khóa để phân bổ & RBAC đúng.',
    'Hiệu suất theo nhân sự: tải + tỉ lệ chốt từng sales.',
    'Lead "nóng" (hỏi giá/lịch khai giảng) chưa ai xử → ưu tiên gọi.',
    'Hội thoại nguội (>N ngày không tương tác) → nhắc/nurture.',
  ];

  return (
    <div className="page wide">
      {head}
      <div className="grid gc5 mb16">
        <KPI label="Tổng lead" value={AAU.fmtNum(total)} icon="users" />
        <KPI label="Có SĐT" value={AAU.fmtNum(q.withPhone)} sub={Math.round(q.phonePct) + '% tổng lead'} icon="phone" />
        <KPI label="Lead nóng (tín hiệu mua)" value={AAU.fmtNum(e.hotLeads || 0)} sub={(e.buyingUnhandled || 0) + ' chưa sales xử'} icon="bolt" />
        <KPI label="Sales đã trả lời" value={Math.round(i.salesReplyPct) + '%'} sub={i.salesReplied + '/' + i.totalConvs + ' hội thoại'} icon="message" />
        <KPI label="Bot/AI xử lý" value={Math.round(i.aiHandledPct) + '%'} sub={i.aiHandled + ' hội thoại'} icon="robot" />
      </div>

      {sig && sig.count > 0 && (
        <Card className="mb16" title={'🔥 Lead nóng cần gọi ngay (' + sig.count + ')'} subtitle="Khách hỏi giá / học phí / lịch khai giảng… mà SALES chưa trả lời — gọi để không bỏ phí">
          <table className="tbl">
            <thead><tr><th>Khách</th><th>SĐT</th><th>Khóa</th><th>Tín hiệu</th><th>Giao</th><th></th></tr></thead>
            <tbody>{sig.leads.slice(0, 12).map(l => (
              <tr key={l.id}>
                <td className="fw6">{l.name}</td>
                <td className="t12">{l.phone || <span className="subtle">—</span>}</td>
                <td className="t12">{l.courseInterest ? (AAU.courseById(l.courseInterest)?.name || l.courseInterest) : <span className="subtle">chưa rõ</span>}</td>
                <td><span className="badge critical" style={{ fontSize: 10 }}>{l.signal}</span></td>
                <td className="t12">{(AAU.users.find(u => u.id === l.assignedTo) || {}).name || l.assignedTo || '—'}</td>
                <td className="num"><div className="row g6 jce"><Button size="sm" variant="plain" icon="message" onClick={() => openChat(l.conversationId)}>Chat</Button><Button size="sm" variant="secondary" icon="user" onClick={() => navigate('/leads/' + l.id)}>360°</Button></div></td>
              </tr>
            ))}</tbody>
          </table>
        </Card>
      )}

      <div className="grid mb16" style={{ gridTemplateColumns: '1fr 1fr' }}>
        <Card title="Chất lượng dữ liệu" subtitle="Bao nhiêu lead có đủ trường thông tin">
          <RepBar label="Số điện thoại" n={q.withPhone} total={total} color="#0a9e6e" />
          <RepBar label="Email" n={q.withEmail} total={total} color="#1a4fa3" />
          <RepBar label="Tên thật (không phải 'Khách …')" n={q.withName} total={total} color="#6d28d9" />
          <RepBar label="Khóa quan tâm" n={q.withCourse} total={total} color="#f59e0b" />
          <RepBar label="Đã phân công sales" n={q.withAssignee} total={total} color="#0084ff" />
        </Card>

        <Card title="Mức độ tương tác" subtitle="Đã hỏi khách hay chưa — ai đang xử lý">
          <RepBar label="Khách có nhắn (inbound)" n={i.hasInbound} total={i.totalConvs} color="#0a9e6e" />
          <RepBar label="Sales (người) đã trả lời" n={i.salesReplied} total={i.totalConvs} color="#0084ff" />
          <RepBar label="Chỉ bot/AI xử lý — sales chưa đụng" n={i.botOnly} total={i.totalConvs} color="#9333ea" />
          <RepBar label="Chưa ai trả lời" n={i.neverOut} total={i.totalConvs} color="#c4320a" />
          <RepBar label="Khách phản hồi lại sau khi sales nhắn" n={i.customerEngaged} total={Math.max(1, i.salesReplied)} color="#0e7c4a" />
          <div className="t11 subtle mt6" style={{ lineHeight: 1.5 }}>Tin nhắn: khách <b>{AAU.fmtNum(i.inMsgs)}</b> · sales <b>{AAU.fmtNum(i.salesMsgs)}</b> · bot/AI <b>{AAU.fmtNum(i.aiMsgs)}</b>.</div>
        </Card>
      </div>

      {(r.byLifecycle || []).length > 0 && (() => {
        const lcColor = { 'Đang nóng': '#0a9e6e', 'Nguội dần': '#f59e0b', 'Có nguy cơ': '#ea580c', 'Ngủ đông': '#6b7280', 'Đã rời': '#c4320a', 'Chưa rõ': '#9aa0a6' };
        const maxLc = Math.max(1, ...r.byLifecycle.map(s => s.count));
        return (
          <Card title="Vòng đời lead — theo độ mới tương tác" subtitle="Tự phân tầng từ lần khách tương tác gần nhất · Sleeping/At-Risk = sắp nguội, chăm trước khi rớt" className="mb16">
            <div className="grid mb12" style={{ gridTemplateColumns: 'repeat(' + r.byLifecycle.length + ',1fr)', gap: 10 }}>
              {r.byLifecycle.map(s => (
                <div key={s.key} style={{ padding: 12, borderRadius: 10, background: (lcColor[s.label] || '#888') + '14', borderLeft: '3px solid ' + (lcColor[s.label] || '#888') }}>
                  <div className="t12 subtle">{s.label}</div>
                  <div className="kv tnum" style={{ fontSize: 22, color: lcColor[s.label] }}>{AAU.fmtNum(s.count)}</div>
                  <div className="t11 subtle">{Math.round(s.count / total * 100)}%</div>
                </div>
              ))}
            </div>
            {(e.followUp || 0) > 0 && (
              <div className="row aic g8" style={{ padding: 10, borderRadius: 10, background: 'var(--p-warning-bg)' }}>
                <Icon name="bolt" size={16} color="#7a4d00" />
                <div className="t12" style={{ color: '#7a4d00' }}><b>{AAU.fmtNum(e.followUp)}</b> lead đang <b>Nguội dần / Có nguy cơ</b> — follow-up ngay để không rớt về Ngủ đông/Đã rời.</div>
              </div>
            )}
          </Card>
        );
      })()}

      <Card title="Phân bố theo Stage (pipeline)" subtitle="Bao nhiêu lead đang ở mỗi bước" className="mb16">
        {r.byStage.filter(s => s.count > 0).map(s => (
          <div key={s.id} style={{ marginBottom: 9 }}>
            <div className="row jcsb t12"><span>{s.name}</span><span className="fw6">{AAU.fmtNum(s.count)}{s.value ? ' · ' + AAU.fmtVNDm(s.value) : ''}</span></div>
            <div style={{ height: 10, borderRadius: 5, background: 'var(--p-bg-surface-tertiary)', overflow: 'hidden', marginTop: 3 }}>
              <div style={{ width: Math.round((s.count / maxStage) * 100) + '%', height: '100%', background: '#1a4fa3' }} />
            </div>
          </div>
        ))}
        {!r.byStage.some(s => s.count > 0) && <div className="muted t12">Chưa có lead.</div>}
      </Card>

      <div className="grid mb16" style={{ gridTemplateColumns: '1fr 1fr 1fr' }}>
        <Card title="Theo kênh">
          {r.byChannel.map(s => <RepBar key={s.key} label={s.label || '(trống)'} n={s.count} total={total} color="#0084ff" />)}
        </Card>
        <Card title="Theo khóa quan tâm" subtitle="Suy từ nội dung chat">
          {(r.byCourse || []).length ? (r.byCourse || []).slice(0, 8).map(s => <RepBar key={s.key} label={s.label || s.key} n={s.count} total={total} color="#f59e0b" />) : <div className="muted t12">Chưa map được khóa.</div>}
        </Card>
        <Card title="Hiệu quả & cần đẩy">
          <RepBar label="Đã qua Raw Lead (được triage)" n={e.pastRawLead} total={total} color="#0a9e6e" />
          <RepBar label="Qualify đủ điều kiện" n={e.qualifyDone} total={total} color="#1a4fa3" />
          <div className="row aic g8 mt8" style={{ padding: 10, borderRadius: 10, background: 'var(--p-warning-bg)' }}>
            <Icon name="alert" size={16} color="#7a4d00" />
            <div className="t12" style={{ color: '#7a4d00' }}><b>{AAU.fmtNum(e.phoneUncontacted)}</b> lead có SĐT nhưng <b>chưa sales nào liên hệ</b> — ưu tiên gọi để không bỏ phí.</div>
          </div>
        </Card>
      </div>

      <Card title="Gợi ý phân tích sâu hơn" subtitle="Thêm các lát cắt này để biết tương tác đã hiệu quả chưa & nỗ lực thêm chỗ nào">
        <div className="col g8">
          {sugg.map((s, k) => <div key={k} className="row aic g8 t13"><Icon name="sparkles" size={14} color="#573b8a" /><span>{s}</span></div>)}
        </div>
      </Card>
    </div>
  );
}
window.SalesReport = SalesReport;
