/* AAU CRM — QC Engine › QC Review
   Hàng đợi hội thoại do AI quét tự động (chat đa kênh) + chi tiết chấm điểm theo tiêu chí + bằng chứng trích dẫn. */

const QC_RS = AAU.qcRulesets.find(r => r.id === 'qc1'); // Chuẩn chat tư vấn — 5 tiêu chí
const QC_CRIT = QC_RS.criteria; // [Chào hỏi 15, Hỏi nhu cầu 25, Báo giá 30, CTA 20, Chính tả 10]

function qcColor(v) { return v >= 8 ? '#0e7c4a' : v >= 6.5 ? '#b06a00' : '#c4320a'; }

// ---- mock: hội thoại đã quét ----
const QC_ITEMS = [
  { id: 'q1', leadId: 'L1', ch: 'fb', agent: 'u9', score: 9.2, verdict: 'pass', status: 'reviewed', sev: false, at: '8 phút trước',
    crit: [9, 9, 9, 10, 9], summary: 'Hội thoại mẫu mực: qualify đủ 4 điều kiện trước khi báo giá, chốt CTA gửi payment link rõ ràng.',
    tx: [
      { w: 'c', t: 'Em ơi cho anh hỏi khóa vận hành chuỗi học phí bao nhiêu?' },
      { w: 'a', t: 'Dạ em chào anh Khoa ạ 🌿 Trước khi báo giá em xin hỏi nhanh để tư vấn đúng nhất — bên anh đang có mấy chi nhánh và pain chính là gì ạ?' },
      { w: 'c', t: '6 chi nhánh, khổ nhất là chi phí nhân sự với chưa chuẩn SOP.' },
      { w: 'a', t: 'Dạ chuẩn rồi ạ. Với quy mô 6 CN thì khóa Vận hành Chuỗi (18.9tr) sẽ tối ưu phần SOP + định biên nhân sự. Anh muốn em gửi proposal chi tiết + lock slot khóa T6 không ạ?' },
      { w: 'c', t: 'Ok em gửi đi.' },
      { w: 'a', t: 'Dạ em gửi payment link + proposal ngay trong hôm nay, anh xem rồi mình confirm slot nhé ạ 🙌', flag: { tone: 'ok', crit: 'Chốt bước tiếp theo (CTA)', note: 'CTA rõ ràng: gửi payment link + lock slot, có khung thời gian.' } },
    ] },
  { id: 'q2', leadId: 'L3', ch: 'fb', agent: 'u4', score: 5.8, verdict: 'fail', status: 'disputed', sev: true, at: '34 phút trước',
    crit: [7, 5, 4, 6, 8], summary: 'Báo giá ngay khi khách vừa hỏi, chưa khai thác nhu cầu/ngân sách. Vi phạm nghiêm trọng quy trình qualify.',
    tx: [
      { w: 'c', t: 'Khóa marketing giá nhiêu em?' },
      { w: 'a', t: '11.9tr chị nhé.', flag: { tone: 'critical', crit: 'Báo giá & xử lý phản đối', note: 'Báo giá ngay khi chưa qualify nhu cầu, quy mô, ngân sách — sai bước bắt buộc.' } },
      { w: 'c', t: 'Mắc vậy, thôi để chị suy nghĩ thêm.' },
      { w: 'a', t: 'Dạ chị cân nhắc nha.', flag: { tone: 'warning', crit: 'Chốt bước tiếp theo (CTA)', note: 'Không đặt lịch follow-up, không xử lý phản đối về giá — để hội thoại trôi.' } },
    ] },
  { id: 'q3', leadId: 'L8', ch: 'zalo', agent: 'u5', score: 5.2, verdict: 'fail', status: 'ai', sev: true, at: '52 phút trước',
    crit: [6, 5, 4, 5, 7], summary: 'Hứa cam kết sai chính sách ("đảm bảo tăng doanh thu 2 lần") — rủi ro pháp lý & uy tín. Cần manager review gấp.',
    tx: [
      { w: 'c', t: 'Học khóa này có hiệu quả thật không em?' },
      { w: 'a', t: 'Anh yên tâm, học xong đảm bảo doanh thu tăng gấp đôi trong 3 tháng ạ!', flag: { tone: 'critical', crit: 'Báo giá & xử lý phản đối', note: 'Cam kết kết quả tuyệt đối không có trong chính sách — rủi ro pháp lý, vi phạm nghiêm trọng.' } },
      { w: 'c', t: 'Gấp đôi luôn hả, vậy chốt đi.' },
      { w: 'a', t: 'Dạ vâng để em gửi thông tin.' },
    ] },
  { id: 'q4', leadId: 'L6', ch: 'fb', agent: 'u9', score: 6.4, verdict: 'fail', status: 'ai', sev: false, at: '1 giờ trước',
    crit: [8, 6, 6, 4, 8], summary: 'Tư vấn ổn nhưng kết thúc lửng — không có lời kêu gọi hành động, bỏ lỡ cơ hội lấy số / hẹn gọi.',
    tx: [
      { w: 'c', t: 'Anh đang muốn nhượng quyền mảng pizza.' },
      { w: 'a', t: 'Dạ vậy khóa Nhượng quyền & SOP sẽ hợp với anh ạ, nội dung gồm chuẩn hóa quy trình + tài chính franchise.' },
      { w: 'c', t: 'Ừ nghe cũng hay.' },
      { w: 'a', t: 'Dạ ạ.', flag: { tone: 'warning', crit: 'Chốt bước tiếp theo (CTA)', note: 'Khách đang có tín hiệu quan tâm nhưng agent không chốt bước tiếp theo (xin SĐT / hẹn gọi).' } },
    ] },
  { id: 'q5', leadId: 'L2', ch: 'zalo', agent: 'u4', score: 8.6, verdict: 'pass', status: 'ai', sev: false, at: '2 giờ trước',
    crit: [9, 8, 9, 8, 9], summary: 'Qualify tốt, xử lý phản đối ngân sách bằng option trả góp, chốt gửi proposal cá nhân hóa.',
    tx: [
      { w: 'c', t: 'Bên chị có 3 khách sạn, mảng F&B đang lỗ.' },
      { w: 'a', t: 'Dạ em hiểu ạ. Vậy mục tiêu chính của chị là cải thiện lãi gộp F&B hay chuẩn hóa vận hành trước ạ?' },
      { w: 'c', t: 'Cả hai nhưng F&B lỗ là gấp nhất.' },
      { w: 'a', t: 'Dạ vậy em đề xuất khóa P&L & Vận hành (14.9tr). Nếu ngân sách cần linh hoạt mình có trả góp 3 kỳ ạ. Em gửi proposal riêng cho nhóm KS của chị nhé?' },
      { w: 'c', t: 'Ừ em gửi.' },
    ] },
  { id: 'q6', leadId: 'L5', ch: 'instagram', agent: 'u9', score: 7.4, verdict: 'pass', status: 'ai', sev: false, at: '3 giờ trước',
    crit: [8, 7, 7, 7, 9], summary: 'Đạt chuẩn, qualify cơ bản tốt; phần xử lý timeline ("muốn làm Q3") có thể khai thác sâu hơn.',
    tx: [
      { w: 'c', t: 'Shop trà sữa mình có 4 chi nhánh, đang lộn xộn vụ nhượng quyền.' },
      { w: 'a', t: 'Dạ em chào chị Ngọc 🌿 4 CN mà nhượng quyền chưa chuẩn thì đúng là rủi ro chất lượng ạ. Chị dự định mở rộng tiếp trong năm nay chứ ạ?' },
      { w: 'c', t: 'Ừ tầm Q3 muốn làm bài bản.' },
      { w: 'a', t: 'Dạ vậy mình còn thời gian chuẩn bị tốt. Em gửi lộ trình khóa Nhượng quyền nhé, mình set 1 buổi tư vấn sâu trước Q3 ạ.' },
    ] },
  { id: 'q7', leadId: 'L16', ch: 'fb', agent: 'u9', score: 8.1, verdict: 'pass', status: 'reviewed', sev: false, at: '4 giờ trước',
    crit: [9, 8, 8, 8, 8], summary: 'Tận dụng tốt context webinar khách đã xem, dẫn dắt sang call qualify tự nhiên.',
    tx: [
      { w: 'c', t: 'Chị xem webinar nhượng quyền của bên em rồi.' },
      { w: 'a', t: 'Dạ em cảm ơn chị Hương đã theo dõi ạ 🙏 Sau webinar chị thấy phần SOP hay phần tài chính franchise cần làm rõ thêm ạ?' },
      { w: 'c', t: 'Phần tài chính, chị chưa rõ vốn cần bao nhiêu.' },
      { w: 'a', t: 'Dạ phần đó em xin 10 phút gọi để tính nhanh theo mô hình bún bò của chị nhé, chiều nay 3h được không ạ?' },
    ] },
  { id: 'q8', leadId: 'L12', ch: 'fb', agent: 'u4', score: 6.9, verdict: 'fail', status: 'ai', sev: false, at: '5 giờ trước',
    crit: [8, 7, 6, 6, 8], summary: 'Sát ngưỡng PASS (7.0). Hỏi nhu cầu ổn nhưng chưa chốt lấy SĐT / chuyển Zalo để nuôi tiếp.',
    tx: [
      { w: 'c', t: 'Mình có 3 chi nhánh chè, muốn mở rộng thêm.' },
      { w: 'a', t: 'Dạ chị muốn mở rộng theo hướng tự mở hay nhượng quyền ạ?' },
      { w: 'c', t: 'Chưa rõ, đang tìm hiểu.' },
      { w: 'a', t: 'Dạ vậy em gửi tài liệu so sánh 2 hướng cho chị tham khảo nhé.', flag: { tone: 'warning', crit: 'Chốt bước tiếp theo (CTA)', note: 'Nên xin SĐT / add Zalo để nuôi tiếp thay vì chỉ gửi tài liệu rồi để ngỏ.' } },
    ] },
];

function QcChannelBadge({ ch }) {
  const c = AAU.channels[ch] || { short: ch, color: '#888' };
  return <span className="row aic g6 t12"><span style={{ width: 8, height: 8, borderRadius: 2, background: c.color }} /><span>{c.label || c.short}</span></span>;
}

function QCReview() {
  const [open, setOpen] = useState(null);
  const [fCh, setFCh] = useState('all');
  const [fVerdict, setFVerdict] = useState('all');
  const [fStatus, setFStatus] = useState('all');
  const live = !!(window.API && window.API.enabled);
  const [scan, setScan] = useState(null);
  const [qcCfg, setQcCfg] = useState(null);
  const [aiCfg, setAiCfg] = useState(null);
  const [scanning, setScanning] = useState(false);
  const [scCh, setScCh] = useState('all');
  const [scFrom, setScFrom] = useState('');
  const [scTo, setScTo] = useState('');
  useEffect(() => {
    if (!live) return;
    if (window.API.qcScan) window.API.qcScan().then(setScan).catch(() => { });
    if (window.API.qcGetConfig) window.API.qcGetConfig().then(setQcCfg).catch(() => { });
    if (window.API.aiConfig) window.API.aiConfig().then(setAiCfg).catch(() => { });
  }, [live]);
  const SRC = (scan && scan.items) || QC_ITEMS;
  const sum = scan && scan.summary;
  const engineOn = !!(qcCfg && qcCfg.autoScan && qcCfg.autoScan.enabled);
  const QC_MODELS = { claude: [{ value: 'claude-opus-4-8', label: 'Claude Opus 4.8' }, { value: 'claude-sonnet-4-6', label: 'Claude Sonnet 4.6' }, { value: 'claude-haiku-4-5', label: 'Claude Haiku 4.5' }], gemini: [{ value: 'gemini-2.5-pro', label: 'Gemini 2.5 Pro' }, { value: 'gemini-2.5-flash', label: 'Gemini 2.5 Flash' }] };
  const runScan = () => {
    if (!live || scanning) return;
    setScanning(true);
    const qs = [];
    if (scFrom) qs.push('from=' + scFrom);
    if (scTo) qs.push('to=' + scTo);
    if (scCh !== 'all') qs.push('channel=' + scCh);
    window.API.qcRun(qs.join('&')).then(r => { setScan(r); setScanning(false); if (window.API.qcGetConfig) window.API.qcGetConfig().then(setQcCfg); }).catch(() => setScanning(false));
  };
  const saveAi = patch => { setAiCfg(c => ({ ...c, ...patch })); if (window.API.saveAiConfig) window.API.saveAiConfig(patch).then(setAiCfg).catch(() => { }); };
  const saveQc = patch => { setQcCfg(c => ({ ...c, ...patch })); if (window.API.qcSaveConfig) window.API.qcSaveConfig(patch).then(setQcCfg).catch(() => { }); };

  const enrich = q => { const u = AAU.users.find(x => x.id === q.agent); return { ...q, lead: AAU.leadById(q.leadId) || { name: q.name || 'Khách', company: '' }, agentName: (u && u.name) || q.agentName || 'AI Bot', agentColor: (u && u.color) || '#8a8f98' }; };
  const rows = SRC.map(enrich).filter(q =>
    (fCh === 'all' || q.ch === fCh) &&
    (fVerdict === 'all' || q.verdict === fVerdict) &&
    (fStatus === 'all' || q.status === fStatus));

  const statusMeta = { ai: { l: 'AI tự động', tone: 'neutral' }, reviewed: { l: 'Đã duyệt', tone: 'success' }, disputed: { l: 'Kháng nghị', tone: 'critical' } };
  const cur = open ? enrich(open) : null;

  return (
    <div className="page wide">
      <PageHead title="QC Review" subtitle="Hàng đợi hội thoại do AI quét tự động — mở từng hội thoại để xem điểm theo tiêu chí & bằng chứng trích dẫn"
        actions={<><Button icon="settings" onClick={() => navigate('/qc/rulesets')}>Bộ tiêu chí</Button><Button icon="download">Xuất</Button></>} />

      {/* Bảng điều khiển QC */}
      <Card className="mb16" title="Bảng điều khiển QC" subtitle={'Ruleset “' + QC_RS.name + '” · ngưỡng PASS ≥ 7.0 · chọn phạm vi, quét ngay hoặc đặt lịch tự động'}>
        <div className="row aic g10 wrap mb12">
          <span className="t12 fw6">Phạm vi:</span>
          <Select value={scCh} onChange={setScCh} options={[{ value: 'all', label: 'Mọi kênh' }, { value: 'fb', label: 'Facebook' }, { value: 'zalo', label: 'Zalo' }, { value: 'instagram', label: 'Instagram' }, { value: 'tiktok', label: 'TikTok' }]} style={{ width: 130 }} />
          <input type="date" className="input" value={scFrom} onChange={e => setScFrom(e.target.value)} style={{ height: 32, fontSize: 12.5 }} />
          <span className="subtle t12">→</span>
          <input type="date" className="input" value={scTo} onChange={e => setScTo(e.target.value)} style={{ height: 32, fontSize: 12.5 }} />
          <Button variant="primary" icon="sparkles" onClick={runScan} disabled={!live || scanning}>{scanning ? 'Đang quét…' : 'Quét ngay'}</Button>
          {qcCfg && qcCfg.lastScanAt && <span className="t11 subtle">Quét gần nhất: {fmtTime(qcCfg.lastScanAt)}</span>}
        </div>
        <div className="row aic g10 wrap" style={{ borderTop: '1px solid var(--p-border-secondary)', paddingTop: 12 }}>
          <span className="t12 fw6">Kiểu chấm:</span>
          {aiCfg
            ? <Seg value={aiCfg.qcEngine} onChange={v => saveAi({ qcEngine: v })} options={[{ value: 'rule', label: 'Rule (miễn phí)' }, { value: 'ai', label: 'AI' }]} />
            : <span className="t12 subtle">…</span>}
          {aiCfg && aiCfg.qcEngine === 'ai' && <Select value={aiCfg.model} onChange={v => saveAi({ model: v })} options={QC_MODELS[aiCfg.provider] || QC_MODELS.claude} style={{ width: 180 }} />}
          <span className="t12 fw6 mla">Lịch tự động:</span>
          {qcCfg && <Switch on={engineOn} onChange={v => saveQc({ autoScan: { ...(qcCfg.autoScan || {}), enabled: v } })} />}
          {qcCfg && <Select value={String((qcCfg.autoScan || {}).intervalMin || 60)} onChange={v => saveQc({ autoScan: { ...(qcCfg.autoScan || {}), enabled: engineOn, intervalMin: parseInt(v, 10) } })} options={[{ value: '15', label: 'mỗi 15 phút' }, { value: '30', label: 'mỗi 30 phút' }, { value: '60', label: 'mỗi giờ' }, { value: '180', label: 'mỗi 3 giờ' }, { value: '1440', label: 'mỗi ngày' }]} style={{ width: 138 }} />}
        </div>
        {aiCfg && aiCfg.qcEngine === 'ai' && <div className="t11 subtle mt8" style={{ lineHeight: 1.5 }}>⚠ Chế độ AI dùng <b>{aiCfg.model}</b> — cần API key (chưa cắm → vẫn chạy rule-based). <span className="linkish" onClick={() => navigate('/system/ai-settings')}>Cấu hình AI →</span></div>}
      </Card>

      <div className="grid gc4 mb16">
        <KPI label="Đã quét" value={sum ? AAU.fmtNum(sum.scanned) : '42'} sub="hội thoại" icon="sparkles" />
        <KPI label="FAIL cần xem" value={sum ? AAU.fmtNum(sum.fail) : '6'} sub="dưới ngưỡng 7.0" icon="inbox" />
        <KPI label="Tỷ lệ PASS" value={sum ? Math.round(sum.passRate) + '%' : '79%'} sub={sum ? 'điểm TB ' + sum.avgScore.toFixed(1) : 'thang điểm 10'} icon="target" />
        <KPI label="Cảnh báo nghiêm trọng" value={sum ? AAU.fmtNum(sum.severe) : '2'} sub="khách hỏi giá chưa đáp" icon="alert" />
      </div>

      <div className="row aic g8 wrap mb12">
        <Select value={fCh} onChange={setFCh} options={[{ value: 'all', label: 'Mọi kênh' }, { value: 'fb', label: 'Messenger' }, { value: 'zalo', label: 'Zalo OA' }, { value: 'instagram', label: 'Instagram' }]} style={{ width: 140 }} />
        <Select value={fVerdict} onChange={setFVerdict} options={[{ value: 'all', label: 'PASS + FAIL' }, { value: 'pass', label: 'Chỉ PASS' }, { value: 'fail', label: 'Chỉ FAIL' }]} style={{ width: 132 }} />
        <Select value={fStatus} onChange={setFStatus} options={[{ value: 'all', label: 'Mọi trạng thái' }, { value: 'ai', label: 'AI tự động' }, { value: 'reviewed', label: 'Đã duyệt' }, { value: 'disputed', label: 'Kháng nghị' }]} style={{ width: 150 }} />
        <span className="t12 subtle mla">{rows.length} hội thoại</span>
      </div>

      <Card pad={false}>
        <table className="tbl">
          <thead><tr><th>Khách hàng</th><th>Kênh</th><th>Agent</th><th className="num">Điểm</th><th>Verdict</th><th>Trạng thái</th><th>Quét lúc</th><th></th></tr></thead>
          <tbody>
            {rows.map(q => (
              <tr key={q.id} style={{ cursor: 'pointer' }} onClick={() => setOpen(q)}>
                <td><span className="row aic g8"><Avatar name={q.lead.name} color={q.agentColor} size={26} /><span><span className="fw6">{q.lead.name}</span>{q.sev && <span className="badge critical" style={{ fontSize: 9, marginLeft: 6, padding: '0 5px' }}>NGHIÊM TRỌNG</span>}<div className="t11 subtle">{q.lead.company}</div></span></span></td>
                <td><QcChannelBadge ch={q.ch} /></td>
                <td className="t12">{q.agentName}</td>
                <td className="num fw7" style={{ color: qcColor(q.score) }}>{q.score.toFixed(1)}</td>
                <td><Badge tone={q.verdict === 'pass' ? 'success' : 'critical'}>{q.verdict.toUpperCase()}</Badge></td>
                <td><Badge tone={statusMeta[q.status].tone} dot>{statusMeta[q.status].l}</Badge></td>
                <td className="t12 subtle">{q.at}</td>
                <td><Button size="sm" variant="plain" icon="externalLink" onClick={e => { e.stopPropagation(); setOpen(q); }}>Xem</Button></td>
              </tr>
            ))}
          </tbody>
        </table>
      </Card>

      {cur && (
        <Drawer width={600} title="Chi tiết QC hội thoại" onClose={() => setOpen(null)}
          footer={<>
            <Button onClick={() => setOpen(null)}>Đóng</Button>
            <Button icon="edit" onClick={() => setOpen(null)}>Kháng nghị điểm</Button>
            <Button variant="primary" icon="check" onClick={() => setOpen(null)}>Duyệt kết quả</Button>
          </>}>
          <div className="row aic g10 mb14">
            <Avatar name={cur.lead.name} size={42} color={cur.agentColor} />
            <div className="f1">
              <div className="t15 fw7 linkish" onClick={() => navigate('/leads/' + cur.leadId)}>{cur.lead.name}</div>
              <div className="t12 muted row aic g6">{cur.lead.company} · {cur.agentName} · <QcChannelBadge ch={cur.ch} /></div>
            </div>
            <Badge tone={cur.verdict === 'pass' ? 'success' : 'critical'}>{cur.verdict.toUpperCase()}</Badge>
          </div>

          {cur.sev && (
            <div className="row aic g8 mb14" style={{ padding: '10px 12px', borderRadius: 10, background: 'var(--p-critical-bg)', color: '#8e1f0b' }}>
              <Icon name="alert" size={16} /><span className="t12 fw6">Vi phạm nghiêm trọng — đã gửi cảnh báo cho Sales Manager qua Telegram.</span>
            </div>
          )}

          <div className="row g10 mb16">
            <div className="f1 center col g4" style={{ padding: 12, borderRadius: 12, background: 'var(--p-magic-bg)' }}>
              <span className="t11 fw6" style={{ color: '#573b8a' }}>AI chấm</span>
              <span className="fw7" style={{ fontSize: 26, color: qcColor(cur.score) }}>{cur.score.toFixed(1)}</span>
              <span className="t11 subtle">ngưỡng PASS ≥ 7.0</span>
            </div>
            <div className="f2" style={{ flex: 2 }}>
              <div className="t11 fw7 subtle mb8">ĐIỂM THEO TIÊU CHÍ</div>
              <div className="col g8">
                {QC_CRIT.map((c, i) => (
                  <div key={i}>
                    <div className="row jcsb t12 mb4"><span>{c.name} <span className="subtle">· {c.weight}%</span></span><span className="fw7" style={{ color: qcColor(cur.crit[i]) }}>{cur.crit[i]}/10</span></div>
                    <Progress value={cur.crit[i]} max={10} color={qcColor(cur.crit[i])} />
                  </div>
                ))}
              </div>
            </div>
          </div>

          <div className="row aic g8 mb14" style={{ padding: '11px 13px', borderRadius: 10, background: 'var(--p-bg-surface-tertiary)' }}>
            <Icon name="sparkles" size={15} color="#573b8a" />
            <span className="t12"><b>Nhận xét AI:</b> {cur.summary}</span>
          </div>

          <div className="t11 fw7 subtle mb8">TRANSCRIPT · BẰNG CHỨNG AI</div>
          <div className="col g10">
            {cur.tx.map((m, i) => {
              const isAgent = m.w === 'a';
              const flagColor = m.flag ? (m.flag.tone === 'critical' ? '#c4320a' : m.flag.tone === 'warning' ? '#b06a00' : '#0e7c4a') : null;
              return (
                <div key={i} className="col g4" style={{ alignItems: isAgent ? 'flex-end' : 'flex-start' }}>
                  <div style={{ maxWidth: '82%', padding: '9px 12px', borderRadius: 12, fontSize: 13, lineHeight: 1.45,
                    background: isAgent ? '#eef3ff' : 'var(--p-bg-surface-secondary)',
                    border: m.flag ? ('1.5px solid ' + flagColor) : '1px solid var(--p-border)',
                    borderBottomRightRadius: isAgent ? 3 : 12, borderBottomLeftRadius: isAgent ? 12 : 3 }}>
                    <div className="t10 fw7 subtle mb2" style={{ textTransform: 'uppercase', letterSpacing: 0.3 }}>{isAgent ? cur.agentName : cur.lead.name}</div>
                    {m.t}
                  </div>
                  {m.flag && (
                    <div className="row g6" style={{ maxWidth: '82%', padding: '7px 10px', borderRadius: 9, background: m.flag.tone === 'ok' ? 'var(--p-success-bg)' : m.flag.tone === 'critical' ? 'var(--p-critical-bg)' : 'var(--p-warning-bg)' }}>
                      <Icon name={m.flag.tone === 'ok' ? 'check' : 'alert'} size={13} color={flagColor} />
                      <span className="t11" style={{ color: flagColor }}><b>{m.flag.crit}:</b> {m.flag.note}</span>
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        </Drawer>
      )}
    </div>
  );
}

Object.assign(window, { QCReview });
