/* AAU CRM — Marketing Hub part 2: Ad Tracking, Campaign Optimizer,
   Content Analytics, Source Performance */

// Cổng kết nối Facebook Ads — gắn 1 lần (token + ad account), test với Graph API rồi lưu.
function FbAdsConnectModal({ conn, onClose, onSaved }) {
  const [token, setToken] = useState('');
  const [acct, setAcct] = useState((conn && conn.adAccount) || '');
  const [ver, setVer] = useState((conn && conn.apiVersion) || 'v21.0');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState(null);
  const connected = conn && conn.connected;
  const save = async () => {
    if (!token.trim() || !acct.trim() || busy) return;
    setBusy(true); setErr(null);
    try { const r = await window.API.adsConnect({ token: token.trim(), adAccount: acct.trim(), apiVersion: ver.trim() }); onSaved(r); onClose(); }
    catch (e) { setErr((e && e.message) || 'Không kết nối được'); }
    finally { setBusy(false); }
  };
  const disconnect = async () => {
    if (!window.confirm('Gỡ cổng FB Ads đã lưu?') || busy) return;
    setBusy(true);
    try { await window.API.adsDisconnect(); onSaved(null); onClose(); } finally { setBusy(false); }
  };
  return (
    <Modal title="Kết nối Facebook Ads" width={560} onClose={onClose}
      footer={<>
        {connected && <Button variant="plain" onClick={disconnect} disabled={busy}>Gỡ kết nối</Button>}
        <Button variant="plain" onClick={onClose}>Hủy</Button>
        <Button variant="primary" icon="lock" onClick={save} disabled={busy || !token.trim() || !acct.trim()}>{busy ? 'Đang kiểm tra…' : 'Test & Lưu'}</Button>
      </>}>
      {connected && <div className="row aic g8 mb12 t12" style={{ padding: '8px 11px', borderRadius: 9, background: 'var(--p-success-bg)' }}><Icon name="checkCircle" size={14} color="#0a7d4f" /><span>Đang nối: <b>{conn.accountName || conn.adAccount}</b>{conn.tokenMask ? ' · token ' + conn.tokenMask : ''}</span></div>}
      <Field label="Access Token (quyền ads_read)"><Input value={token} onChange={setToken} type="password" placeholder={conn && conn.hasToken ? 'Đã có token — dán token mới để thay' : 'EAAB… token ads_read'} autoFocus /></Field>
      <Field label="Ad Account ID"><Input value={acct} onChange={setAcct} placeholder="act_1234567890 (hoặc 1234567890)" /></Field>
      <Field label="Graph API version"><Input value={ver} onChange={setVer} placeholder="v21.0" /></Field>
      {err && <div className="row aic g8 t12" style={{ padding: '8px 11px', borderRadius: 9, background: 'var(--p-critical-bg)' }}><Icon name="alert" size={14} color="#c4320a" /><span style={{ lineHeight: 1.5 }}>{err}</span></div>}
      <div className="t11 subtle mt8" style={{ lineHeight: 1.5 }}>Bấm <b>Test & Lưu</b>: app gọi Facebook xác thực rồi <b>lưu 1 lần</b> (sống qua restart, không cần env). Pilot lưu token trong DB; production chuyển secret store.</div>
    </Modal>
  );
}

function AdTracking() {
  const t = useTimeRange('30d');
  const [platform, setPlatform] = useState('all');
  const [tick, setTick] = useState(0);
  const [rep, setRep] = useState(null);
  const [conn, setConn] = useState(null);
  const [showConn, setShowConn] = useState(false);
  const live = !!(window.API && window.API.enabled);

  useEffect(() => { if (live && window.API.adsConn) window.API.adsConn().then(setConn).catch(() => { }); }, [live, tick]);

  const iso = d => { const x = new Date(d); return x.getFullYear() + '-' + String(x.getMonth() + 1).padStart(2, '0') + '-' + String(x.getDate()).padStart(2, '0'); };
  const fromISO = iso(t.cur.from), toISO = iso(t.cur.to);
  const pfromISO = iso(t.prev.from), ptoISO = iso(t.prev.to);

  // L1: kéo báo cáo ads thật từ CQA theo khoảng + so sánh kỳ; phản ứng theo TimeControl.
  useEffect(() => {
    if (!live || !window.API.adsReport) { setRep(null); return; }
    const q = { from: fromISO, to: toISO, gran: 'day' };
    if (t.compare) { q.pfrom = pfromISO; q.pto = ptoISO; }
    let alive = true;
    window.API.adsReport(q).then(r => { if (alive) setRep(r); }).catch(() => { if (alive) setRep(null); });
    return () => { alive = false; };
  }, [live, fromISO, toISO, t.compare, pfromISO, ptoISO, tick]);

  // Nút "Đồng bộ Ads API": refresh read-model mktFacts (cho các dashboard khác) + báo cáo này.
  const syncAds = live ? async () => {
    await window.API.adsSync();
    if (window.API.hydrate) await window.API.hydrate();
    setTick(n => n + 1);
  } : null;

  // ---- nguồn dữ liệu: report thật nếu có, ngược lại mock ----
  const useLive = !!rep;
  let spend, msgs, leads, won, imp, reach, clicks, rows, prevT, spendSeries, seriesLabels;
  if (useLive) {
    const T = rep.current.totals;
    spend = T.spend; msgs = T.messages; leads = T.leads; imp = T.impressions; reach = T.reach; clicks = T.clicks; won = 0;
    rows = rep.current.campaigns.filter(c => platform === 'all' || c.platform === platform).map(c => ({ ...c, status: 'active', course: '', won: 0 }));
    prevT = rep.previous ? rep.previous.totals : null;
    const ser = rep.current.series;
    spendSeries = { cur: ser.map(s => s.spend / 1e6), prev: rep.previous ? ser.map((_, i) => (rep.previous.series[i] ? rep.previous.series[i].spend / 1e6 : 0)) : [] };
    seriesLabels = ser.map(s => s.bucket.slice(8) + '/' + s.bucket.slice(5, 7));
  } else {
    const cps = AAU.campaigns.filter(c => platform === 'all' || c.platform === platform);
    const sum = k => cps.reduce((s, c) => s + (c[k] || 0), 0);
    spend = sum('spend'); msgs = sum('messages'); leads = sum('leads'); won = sum('won'); imp = sum('impressions'); reach = sum('reach'); clicks = sum('clicks');
    rows = cps; prevT = null; spendSeries = AAU.mktTrend.spend; seriesLabels = AAU.mktTrend.labels;
  }
  const orgLeads = AAU.mktFacts.filter(f => !f.campaign).reduce((s, f) => s + (f.leadsOrg || 0), 0);

  // delta% so với kỳ trước (chỉ khi có report + compare). lowerBetter: chi phí giảm = tốt.
  const dl = (cur, prevVal, lowerBetter) => {
    if (prevVal == null || !prevVal) return null;
    const pct = Math.round((cur - prevVal) / prevVal * 100);
    return { d: Math.abs(pct), dd: (pct >= 0) === !lowerBetter ? 'up' : 'down', raw: pct };
  };
  const cpl = leads ? spend / leads : 0, ctr = imp ? clicks / imp * 100 : 0, cpm = imp ? spend / imp * 1000 : 0, cpMsg = msgs ? spend / msgs : 0;
  const kpis = [
    { l: 'Tổng chi (Spend)', v: AAU.fmtVNDm(spend), c: prevT && dl(spend, prevT.spend) },
    { l: 'Impressions', v: AAU.fmtNum(imp), c: prevT && dl(imp, prevT.impressions) },
    { l: 'Link Clicks', v: AAU.fmtNum(clicks), c: prevT && dl(clicks, prevT.clicks) },
    { l: 'Messages', v: AAU.fmtNum(msgs), c: prevT && dl(msgs, prevT.messages) },
    { l: 'CTR', v: imp ? ctr.toFixed(2) + '%' : '—', c: prevT && dl(ctr, prevT.ctr) },
    { l: 'CPM', v: imp ? AAU.fmtVND(cpm) : '—', c: prevT && dl(cpm, prevT.cpm, true) },
    { l: 'Cost/Message', v: msgs ? AAU.fmtVND(cpMsg) : '—', c: prevT && dl(cpMsg, prevT.costPerMsg, true) },
    { l: 'Cost/Lead', v: leads ? AAU.fmtVND(cpl) : '—', c: prevT && dl(cpl, prevT.cpl, true) },
    { l: 'CAC — Cost/Won (CRM)', v: won ? AAU.fmtVND(spend / won) : '—', crm: true },
    { l: 'ROAS (CRM)', v: (won && spend) ? (won * 14900000 / spend).toFixed(1) + '×' : '—', crm: true },
  ];
  const cols = [
    { key: 'name', label: 'Campaign', render: c => <div className="fw6">{c.name}<div className="t11 subtle">{AAU.courseById(c.course)?.name || (useLive ? 'chưa gắn khóa' : '')}</div></div>, csv: c => c.name },
    { key: 'platform', label: 'Nền tảng', render: c => <SourceBadge src={c.platform} /> },
    { key: 'spend', label: 'Spend', num: true, render: c => AAU.fmtVNDm(c.spend) },
    { key: 'impressions', label: 'Impr', num: true, render: c => AAU.fmtNum(c.impressions || 0) },
    { key: 'clicks', label: 'Clicks', num: true, render: c => AAU.fmtNum(c.clicks || 0) },
    { key: 'messages', label: 'Msg', num: true },
    { key: 'leads', label: 'Lead', num: true },
    { key: 'cpl', label: 'CPL', num: true, render: c => c.leads ? <span style={{ color: c.spend / c.leads > AAU.mktBudget.cplAlert ? '#c4320a' : undefined }}>{AAU.fmtVND(c.spend / c.leads)}</span> : '—' },
    { key: 'won', label: 'Won', num: true, render: c => <span className="fw6">{c.won || 0}</span> },
    { key: 'roas', label: 'ROAS', num: true, render: c => (c.won && c.spend) ? <span className="fw6 sla-ok">{(c.won * 14900000 / c.spend).toFixed(1)}×</span> : '—' },
  ];
  return (
    <div className="page wide">
      <PageHead title="Ad Tracking Dashboard" subtitle={useLive ? ('FB Ads thật từ CQA · ' + t.cur.label + (t.compare ? ' (so ' + t.prev.label + ')' : '') + ' · Cost/Lead = số thật') : 'Chỉ số ads kéo qua API. Cost/Lead & CAC lấy số thật từ CRM.'}
        actions={<>
          {live && (conn && conn.connected
            ? <Button size="sm" variant="plain" icon="checkCircle" onClick={() => setShowConn(true)} title={'FB Ads: ' + (conn.accountName || conn.adAccount)}>FB: {conn.accountName || conn.adAccount}</Button>
            : <Button size="sm" icon="lock" onClick={() => setShowConn(true)}>Kết nối FB Ads</Button>)}
          <SyncButton label="Đồng bộ Ads API" since={live ? 'bấm để kéo từ CQA' : '12 phút trước'} onSync={syncAds} />
          <Select value={platform} onChange={setPlatform} options={[{ value: 'all', label: 'Tất cả nền tảng' }, { value: 'facebook', label: 'Facebook' }, { value: 'google', label: 'Google' }, { value: 'tiktok', label: 'TikTok' }]} style={{ width: 160 }} />
          <TimeControl t={t} />
        </>} />
      {showConn && <FbAdsConnectModal conn={conn} onClose={() => setShowConn(false)} onSaved={() => setTick(n => n + 1)} />}
      <div className="grid mb16" style={{ gridTemplateColumns: 'repeat(5,1fr)' }}>{kpis.map((k, i) => (
        <div key={i} className="kpi"><div className="kl">{k.crm && <Icon name="kanban" size={12} color="#008060" />}{k.l}</div>
          <div className="kv tnum" style={{ fontSize: 20 }}>{k.v}</div>
          {k.c && <div className={'kd ' + k.c.dd}><Icon name={k.c.raw < 0 ? 'arrowDown' : 'arrowUp'} size={11} />{k.c.d}%</div>}</div>
      ))}</div>
      <div className="grid mb16" style={{ gridTemplateColumns: '1.7fr 1fr' }}>
        <Card title="Spend theo thời gian" subtitle={t.cur.label + (t.compare ? ' · ' + CMP_LABEL[t.cmpMode] : '')}>
          <CompareLineChart data={spendSeries} color="#0084ff" fmt={v => v.toFixed(1) + 'tr'} labels={seriesLabels} showB={t.compare} labelA={t.cur.label} labelB={t.prev.label} />
        </Card>
        <Card title="Phễu chuyển đổi" subtitle="Messages → Lead (Won gắn CRM ở bước sau)">
          <Funnel steps={[{ l: 'Impressions', v: imp, color: '#60a5fa' }, { l: 'Clicks', v: clicks, color: '#0084ff' }, { l: 'Messages', v: msgs, color: '#8b5cf6' }, { l: 'Lead (ads)', v: leads, color: '#10b981' }]} />
          {!useLive && <div className="callout-soft mt12"><Icon name="sparkles" size={14} /><span>Cùng kỳ, {orgLeads} lead organic về thêm không tốn chi phí ads.</span></div>}
        </Card>
      </div>
      <Card title="Campaigns" subtitle={useLive ? 'FB Ads thật theo kỳ đang chọn · CPL đỏ = vượt ngưỡng' : 'Bấm campaign để mở Optimizer · CPL đỏ = vượt ngưỡng'}>
        <DataTable columns={cols} rows={rows} getId={c => c.id} searchKeys={['name']} onRowClick={c => navigate('/marketing/ads/' + c.id)} exportName="campaigns" pageSize={8} />
      </Card>
    </div>
  );
}

// gộp text đối tượng từ targeting đã parse
function audienceText(tg) {
  if (!tg) return '—';
  const p = [];
  if (tg.ageMin || tg.ageMax) p.push((tg.ageMin || '?') + '–' + (tg.ageMax || '?') + 't');
  if (tg.genders && tg.genders.length) p.push(tg.genders.join('/'));
  if (tg.locations && tg.locations.length) p.push(tg.locations.slice(0, 3).join(', '));
  if (tg.interests && tg.interests.length) p.push(tg.interests.slice(0, 2).join(', '));
  return p.join(' · ') || '—';
}

function CampaignOptimizer({ campaignId }) {
  const live = !!(window.API && window.API.enabled);
  const t = useTimeRange('30d');
  const [tab, setTab] = useState('structure');
  const [expanded, setExpanded] = useState(null);
  const [drill, setDrill] = useState(null);
  const [err, setErr] = useState(null);
  const iso = d => { const x = new Date(d); return x.getFullYear() + '-' + String(x.getMonth() + 1).padStart(2, '0') + '-' + String(x.getDate()).padStart(2, '0'); };
  const fromISO = iso(t.cur.from), toISO = iso(t.cur.to);
  useEffect(() => {
    if (!live || !window.API.adsDrill) { setDrill(null); return; }
    let alive = true; setErr(null);
    window.API.adsDrill(campaignId, { from: fromISO, to: toISO }).then(r => { if (alive) setDrill(r); }).catch(e => { if (alive) { setDrill(null); setErr((e && e.message) || 'lỗi'); } });
    return () => { alive = false; };
  }, [live, campaignId, fromISO, toISO]);

  const useLiveDrill = !!(drill && drill.campaign);
  const cpMock = AAU.campaignById(campaignId);
  if (!live && !cpMock) return <div className="page"><EmptyState title="Không tìm thấy campaign" action={<Button variant="primary" onClick={() => navigate('/marketing/ads')}>Về Ad Tracking</Button>} /></div>;

  // chuẩn hóa adsets + ads (live drill ↔ mock) về 1 dạng
  let head, adsets, adIndex;
  if (useLiveDrill) {
    head = { name: drill.campaign.name, objective: drill.campaign.objective, course: '' };
    adsets = drill.adsets.map(as => ({ id: as.id, name: as.name, budget: as.dailyBudget, spend: as.spend, messages: as.messages, leads: as.leads, audience: audienceText(as.targeting), targeting: as.targeting }));
    adIndex = {};
    (drill.ads || []).forEach(ad => { const cr = ad.creative || {}; (adIndex[ad.adsetId] = adIndex[ad.adsetId] || []).push({ id: ad.id, name: ad.name, format: cr.type || '—', thumbnail: cr.thumbnail, spend: ad.spend, messages: ad.messages, leads: ad.leads, costPerMsg: ad.costPerMsg }); });
  } else {
    const cp = cpMock || {};
    head = { name: cp.name, objective: cp.objective, course: AAU.courseById(cp.course)?.name };
    adsets = (AAU.adsets[cp.id] || []).map(as => ({ id: as.id, name: as.name, budget: as.budget, spend: as.spend, messages: as.messages, leads: as.leads, audience: [as.interest, as.location, as.age].filter(Boolean).join(' · '), targeting: { locations: [as.location], interests: [as.interest], genders: [], ageMin: '', ageMax: '' } }));
    adIndex = {};
    Object.keys(AAU.ads || {}).forEach(k => { adIndex[k] = (AAU.ads[k] || []).map(ad => ({ id: ad.id, name: ad.name, format: ad.format, thumbnail: null, spend: ad.spend, messages: ad.messages, leads: ad.leads || 0, costPerMsg: ad.costPerMsg })); });
  }
  const totSpend = adsets.reduce((s, a) => s + (a.spend || 0), 0);
  const totMsg = adsets.reduce((s, a) => s + (a.messages || 0), 0);
  const totLead = adsets.reduce((s, a) => s + (a.leads || 0), 0);
  const allAds = Object.values(adIndex).flat();

  // đề xuất động khi có data thật
  let suggestions = [];
  if (useLiveDrill) {
    const asMsg = adsets.filter(a => a.messages > 0).sort((a, b) => (a.spend / a.messages) - (b.spend / b.messages));
    if (asMsg.length) {
      const best = asMsg[0], worst = asMsg[asMsg.length - 1];
      suggestions.push({ tone: 'success', t: 'AdSet "' + best.name + '" hiệu quả nhất', d: 'Cost/Msg ' + AAU.fmtVND(best.spend / best.messages) + ' — cân nhắc tăng ngân sách.' });
      if (worst !== best) suggestions.push({ tone: 'critical', t: 'AdSet "' + worst.name + '" Cost/Msg cao nhất', d: AAU.fmtVND(worst.spend / worst.messages) + ' — xem lại creative/đối tượng.' });
    }
    const adMsg = allAds.filter(a => a.messages > 0).sort((a, b) => (a.spend / a.messages) - (b.spend / b.messages));
    if (adMsg.length) suggestions.push({ tone: 'warning', t: 'Creative "' + adMsg[0].name + '" tốt nhất', d: 'Cost/Msg ' + AAU.fmtVND(adMsg[0].spend / adMsg[0].messages) + ' — nhân bản hướng creative này, làm mới các creative kém.' });
    if (!suggestions.length) suggestions.push({ tone: 'warning', t: 'Chưa đủ message trong kỳ', d: 'Mở rộng khoảng thời gian để có dữ liệu tối ưu.' });
  } else {
    suggestions = [
      { tone: 'critical', t: 'AdSet "Retarget xem video" CPL cao gấp 2,1× trung bình', d: 'CPL 1.286k vs TB 600k — cân nhắc tắt hoặc đổi creative.' },
      { tone: 'success', t: 'Ad "Video testimonial Khoa BBQ" là top performer', d: 'Cost/Message 95k thấp nhất — tăng ngân sách 20%.' },
    ];
  }

  return (
    <div className="page wide">
      <PageHead breadcrumb={[{ label: 'Marketing' }, { label: 'Ad Tracking', href: 1, onClick: () => navigate('/marketing/ads') }, { label: head.name || '…' }]}
        title={head.name || '…'} subtitle={'Mục tiêu: ' + (head.objective || '—') + (head.course ? ' · Khóa gắn: ' + head.course : (useLiveDrill ? ' · FB Ads thật' : ''))}
        actions={live ? <TimeControl t={t} /> : <Button variant="primary" icon="bolt">Áp dụng đề xuất</Button>} />
      {err && <div className="row aic g8 mb16 t12" style={{ padding: '10px 12px', borderRadius: 10, background: 'var(--p-critical-bg)' }}><Icon name="alert" size={16} color="#c4320a" /><span>Không tải được drill: {err}</span></div>}
      <div className="grid gc4 mb16">
        <KPI label="Tổng chi" value={AAU.fmtVNDm(totSpend)} icon="dollar" />
        <KPI label="Messages" value={AAU.fmtNum(totMsg)} icon="message" />
        <KPI label="Lead (form)" value={AAU.fmtNum(totLead)} icon="inbox" />
        <KPI label="AdSet · Ad" value={adsets.length + ' · ' + allAds.length} icon="layers" />
      </div>
      <Card pad={false} className="mb16">
        <div style={{ padding: '4px 8px' }}><Tabs value={tab} onChange={setTab} tabs={[{ value: 'structure', label: 'Cấu trúc AdSet → Ad' }, { value: 'audience', label: 'Đối tượng & Location' }, { value: 'creative', label: 'Creative' }]} /></div>
        <div className="card-body">
          {tab === 'structure' && (
            <table className="tbl"><thead><tr><th>AdSet / Ad</th><th>Đối tượng</th><th className="num">Ngân sách</th><th className="num">Spend</th><th className="num">Msg</th><th className="num">Cost/Msg</th></tr></thead>
              <tbody>{adsets.map(as => (
                <React.Fragment key={as.id}>
                  <tr className="clickable" onClick={() => setExpanded(expanded === as.id ? null : as.id)}>
                    <td><div className="row aic g6"><Icon name={expanded === as.id ? 'chevronDown' : 'chevronRight'} size={14} /><span className="fw6">{as.name}</span></div></td>
                    <td className="muted t12">{as.audience}</td>
                    <td className="num">{as.budget ? AAU.fmtVNDm(as.budget) + '/ngày' : '—'}</td>
                    <td className="num">{AAU.fmtVNDm(as.spend)}</td>
                    <td className="num">{as.messages}</td>
                    <td className="num">{as.messages ? AAU.fmtVND(as.spend / as.messages) : '—'}</td>
                  </tr>
                  {expanded === as.id && (adIndex[as.id] || []).map(ad => (
                    <tr key={ad.id} style={{ background: 'var(--p-bg-surface-secondary)' }}>
                      <td style={{ paddingLeft: 36 }}><div className="row aic g8">{ad.thumbnail ? <img src={ad.thumbnail} style={{ width: 34, height: 34, borderRadius: 6, objectFit: 'cover', flexShrink: 0 }} /> : <span style={{ width: 30, height: 30, borderRadius: 6, background: '#ddd', flexShrink: 0 }} className="center"><Icon name={/VIDEO/i.test(ad.format) ? 'play' : 'layers'} size={14} /></span>}<span className="t12">{ad.name}</span></div></td>
                      <td className="t12 muted">{ad.format}</td>
                      <td className="num t12">—</td>
                      <td className="num t12">{AAU.fmtVNDm(ad.spend)}</td>
                      <td className="num t12">{ad.messages}</td>
                      <td className="num t12">{ad.messages ? AAU.fmtVND(ad.spend / ad.messages) : '—'}</td>
                    </tr>
                  ))}
                </React.Fragment>
              ))}
              {!adsets.length && <tr><td colSpan={6} className="muted t12" style={{ padding: 16 }}>Không có adset trong kỳ.</td></tr>}
              </tbody></table>
          )}
          {tab === 'audience' && (
            <table className="tbl"><thead><tr><th>AdSet</th><th>Location</th><th>Tuổi · Giới</th><th>Sở thích</th><th className="num">Spend</th><th className="num">Msg</th><th className="num">Cost/Msg</th></tr></thead>
              <tbody>{adsets.map(as => { const tg = as.targeting || {}; return <tr key={as.id}><td className="fw6">{as.name}</td><td className="t12">{(tg.locations || []).join(', ') || '—'}</td><td className="t12">{(tg.ageMin || '?') + '–' + (tg.ageMax || '?') + 't'}{tg.genders && tg.genders.length ? ' · ' + tg.genders.join('/') : ''}</td><td className="t12 muted">{(tg.interests || []).slice(0, 4).join(', ') || '—'}</td><td className="num">{AAU.fmtVNDm(as.spend)}</td><td className="num">{as.messages}</td><td className="num">{as.messages ? AAU.fmtVND(as.spend / as.messages) : '—'}</td></tr>; })}</tbody></table>
          )}
          {tab === 'creative' && (
            <div className="grid gc3">{allAds.slice(0, 12).map((ad, i) => (
              <Card key={ad.id || i} pad>
                {ad.thumbnail
                  ? <div style={{ height: 140, borderRadius: 10, overflow: 'hidden', marginBottom: 10, background: '#000' }}><img src={ad.thumbnail} style={{ width: '100%', height: '100%', objectFit: 'cover' }} /></div>
                  : <div className="center" style={{ height: 140, borderRadius: 10, background: 'var(--p-bg-surface-tertiary)', marginBottom: 10 }}><Icon name={/VIDEO/i.test(ad.format) ? 'play' : 'layers'} size={32} color="#8a8a8a" /></div>}
                <div className="row jcsb aic"><span className="t13 fw6" style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{ad.name}</span><Badge tone="neutral">{ad.format}</Badge></div>
                <div className="t12 muted mt4">Spend {AAU.fmtVNDm(ad.spend)} · {ad.messages} msg · {ad.messages ? AAU.fmtVND(ad.spend / ad.messages) : '—'}/msg</div>
              </Card>
            ))}
            {!allAds.length && <div className="muted t12" style={{ padding: 16 }}>Không có creative trong kỳ.</div>}
            </div>
          )}
        </div>
      </Card>
      <Card title="Đề xuất tối ưu" subtitle={useLiveDrill ? 'Tự sinh từ dữ liệu thật trong kỳ' : 'Gợi ý mẫu'}>
        <div className="col g10">{suggestions.map((s, i) => (
          <div key={i} className="row g10 aic" style={{ padding: 12, borderRadius: 10, background: 'var(--p-' + s.tone + '-bg)' }}>
            <Icon name={s.tone === 'success' ? 'arrowUp' : s.tone === 'critical' ? 'alert' : 'refresh'} size={18} color={'var(--p-' + s.tone + '-text)'} />
            <div className="f1"><div className="t13 fw6">{s.t}</div><div className="t12 muted">{s.d}</div></div>
          </div>
        ))}</div>
      </Card>
    </div>
  );
}

function ContentAnalytics() {
  const t = useTimeRange('30d');
  const posts = AAU.contentPostsX;
  const channelsForMix = ['facebook', 'instagram', 'tiktok', 'youtube', 'threads'];
  const formats = [{ l: 'Image', v: 8, color: '#0084ff' }, { l: 'Video', v: 6, color: '#7c3aed' }, { l: 'Reel/Short', v: 7, color: '#d62976' }, { l: 'Carousel', v: 4, color: '#f59e0b' }, { l: 'Text/ZNS', v: 5, color: '#0a9e6e' }];
  const pillarsData = AAU.pillars.map((p, i) => ({ l: p, v: [9, 6, 5, 6][i], color: ['#0084ff', '#7c3aed', '#f59e0b', '#0a9e6e'][i] }));
  const totReach = posts.reduce((s, p) => s + p.reach, 0);
  const totMsg = posts.reduce((s, p) => s + p.messages, 0);
  const totLead = posts.reduce((s, p) => s + p.leads, 0);
  const cols = [
    { key: 'title', label: 'Bài đăng', render: p => <div className="fw6">{p.title} {p.best && <Badge tone="success">Tốt nhất</Badge>}{p.worst && <Badge tone="critical">Kém</Badge>}</div>, csv: p => p.title },
    { key: 'channel', label: 'Kênh', render: p => <SourceBadge src={p.channel} /> },
    { key: 'format', label: 'Format' },
    { key: 'pillar', label: 'Pillar', render: p => <Badge tone="neutral">{p.pillar}</Badge> },
    { key: 'date', label: 'Đăng lúc', render: p => <div>{AAU.fmtDate(p.date)}<div className="t11 subtle">{p.time}</div></div>, csv: p => p.date + ' ' + p.time },
    { key: 'reach', label: 'Reach', num: true, render: p => AAU.fmtNum(p.reach) },
    { key: 'engagement', label: 'Eng%', num: true, render: p => p.engagement + '%' },
    { key: 'messages', label: 'Msg', num: true },
    { key: 'leads', label: 'Lead', num: true, render: p => <span className="fw6">{p.leads}</span> },
  ];
  return (
    <div className="page wide">
      <PageHead title="Content & Post Analytics" subtitle="Bài đăng đa kênh — format, giờ đăng, và bài nào kéo về message/lead thật sự"
        actions={<><SyncButton label="Đồng bộ kênh" since="8 phút trước" /><TimeControl t={t} /></>} />
      <div className="grid mb16" style={{ gridTemplateColumns: 'repeat(5,1fr)' }}>
        <KPI label="Bài đăng" value={posts.length} sub="Mục tiêu 16/tuần" icon="fileText" />
        <KPI label="Tổng reach" value={AAU.fmtNum(totReach)} delta={11} icon="megaphone" />
        <KPI label="Engagement TB" value="5,9%" delta={3} icon="sparkles" />
        <KPI label="Messages từ post" value={totMsg} delta={16} icon="message" />
        <KPI label="Lead từ post (CRM)" value={totLead} delta={21} icon="inbox" />
      </div>
      <div className="grid mb16" style={{ gridTemplateColumns: '1.3fr 1fr' }}>
        <Card title="Giờ vàng đăng bài" subtitle="Chỉ số tương tác theo ngày × khung giờ — đậm hơn = nên đăng">
          <Heatmap days={AAU.heatDays} slots={AAU.heatSlots} grid={AAU.heatGrid} color="#0084ff" />
          <div className="callout-soft mt12"><Icon name="sparkles" size={14} /><span>Khung 18–21h T5–CN cho tương tác cao nhất. Tránh khung 6–9h ngày thường.</span></div>
        </Card>
        <Card title="Bài đăng theo kênh × tuần">
          <StackedBar data={AAU.postWeekly} keys={channelsForMix.map(c => ({ key: c, color: AAU.mktChannelById(c).color }))} height={210} />
          <div className="mt8"><Legend items={channelsForMix.map(c => ({ l: AAU.mktChannelById(c).label, color: AAU.mktChannelById(c).color }))} /></div>
        </Card>
      </div>
      <div className="grid gc2 mb16">
        <Card title="Theo format"><div className="center"><Donut data={formats} center={{ v: 30, l: 'bài' }} /></div><div className="mt12"><Legend items={formats.map(f => ({ l: f.l, color: f.color }))} /></div></Card>
        <Card title="Theo pillar" subtitle="Số bài theo trụ nội dung"><BarChart data={pillarsData} height={210} color="#7c3aed" /></Card>
      </div>
      <Card title="Tất cả bài đăng" subtitle="Sắp theo Lead để thấy nội dung nào ra đơn"><DataTable columns={cols} rows={posts} getId={p => p.id} searchKeys={['title']} exportName="content" pageSize={8} /></Card>
    </div>
  );
}

function SourcePerformance() {
  const t = useTimeRange('30d');
  const split = AAU.channelSplit;
  const paidLeads = split.reduce((s, c) => s + c.ads, 0);
  const orgLeads = split.reduce((s, c) => s + c.org, 0);
  const directLeads = 19;
  const totalCat = paidLeads + orgLeads + directLeads;
  const donut = [
    { l: 'Paid Ads', v: paidLeads, color: '#0084ff' },
    { l: 'Organic', v: orgLeads, color: '#0a9e6e' },
    { l: 'Direct/Hotline', v: directLeads, color: '#616161' },
  ];
  return (
    <div className="page wide">
      <PageHead title="Source Performance" subtitle="Phân bổ lead theo nguồn — tách Organic vs Ads từng kênh, so cả số lượng VÀ chất lượng (won-rate, CAC)"
        actions={<><SyncButton label="Đồng bộ nguồn" since="5 phút trước" /><TimeControl t={t} /></>} />
      <div className="grid mb16" style={{ gridTemplateColumns: '1fr 1.7fr' }}>
        <Card title="Paid · Organic · Direct"><div className="center"><Donut data={donut} center={{ v: totalCat, l: 'lead' }} /></div><div className="mt12"><Legend items={donut.map(d => ({ l: d.l, color: d.color }))} /></div></Card>
        <Card title="Ma trận kênh × Organic / Ads" subtitle="Lead, CPL và chất lượng (won-rate) theo từng kênh">
          <table className="tbl"><thead><tr><th>Kênh</th><th className="num">Organic</th><th className="num">Ads</th><th className="num">Σ Lead</th><th className="num">Won</th><th className="num">Won-rate</th><th className="num">CPL (ads)</th><th className="num">CAC</th></tr></thead>
            <tbody>{split.map(s => (
              <tr key={s.channel} className="clickable" onClick={() => navigate('/marketing/channel/' + s.channel)}><td><SourceBadge src={s.channel} showLabel /></td>
                <td className="num sla-ok">{s.org}</td>
                <td className="num" style={{ color: '#0084ff' }}>{s.ads || '—'}</td>
                <td className="num fw6">{s.leads}</td>
                <td className="num">{s.won}</td>
                <td className="num fw6" style={{ color: s.wonRate > 0.13 ? '#0e7c4a' : '#b06f00' }}>{(s.wonRate * 100).toFixed(1)}%</td>
                <td className="num" style={{ color: s.cpl && s.cpl > AAU.mktBudget.cplAlert ? '#c4320a' : undefined }}>{s.cpl ? AAU.fmtVND(s.cpl) : '—'}</td>
                <td className="num">{s.cac ? AAU.fmtVNDm(s.cac) : '—'}</td></tr>
            ))}</tbody></table>
          <div className="callout-line mt16" style={{ display: 'flex', gap: 10, padding: 12, borderRadius: 10, background: 'var(--p-info-bg)', color: 'var(--p-info-text)', fontSize: 13 }}>
            <Icon name="sparkles" size={16} /><div><b>Insight:</b> Paid mang nhiều lead nhất nhưng won-rate thấp và CAC cao. Organic (Website, YouTube, Zalo) ít lead hơn nhưng won-rate cao hơn và gần như miễn phí — nên tăng đầu tư content những kênh này.</div>
          </div>
        </Card>
      </div>
      <Card title="Phễu chuyển đổi đa kênh" subtitle="Impression → Click → Message → Lead → Won theo từng kênh — % cho thấy rò rỉ ở bước nào. Bấm tiêu đề kênh để xem chi tiết.">
        <div className="grid gc3">{AAU.channelFunnel.filter(f => f.impressions > 0 && f.messages > 0).map(f => (
          <div key={f.channel} className="chfunnel">
            <div className="row aic jcsb mb8 clickable" onClick={() => navigate('/marketing/channel/' + f.channel)}><SourceBadge src={f.channel} showLabel /><Icon name="chevronRight" size={14} color="#9ca3af" /></div>
            <Funnel steps={[{ l: 'Impressions', v: f.impressions, color: '#0084ff' }, { l: 'Clicks', v: f.clicks, color: '#3b82f6' }, { l: 'Messages', v: f.messages, color: '#8b5cf6' }, { l: 'Lead', v: f.leads, color: '#f59e0b' }, { l: 'Won', v: f.won, color: '#10b981' }]} />
          </div>
        ))}</div>
      </Card>
    </div>
  );
}

Object.assign(window, { AdTracking, CampaignOptimizer, ContentAnalytics, SourcePerformance });
