// CompareDetail — Mode B: multi-vendor horizontal comparison
const COMPARE_FALLBACK_COLORS = ['#2E75B6', '#8E44AD', '#27AE60', '#E67E22', '#C0392B'];

const normalizeCompareNumber = (value, fallback = 0) => {
  const n = Number(value);
  return Number.isFinite(n) ? n : fallback;
};

const parseCompareMoney = (value) => {
  if (typeof value === 'number') return value;
  const text = String(value || '').replace(/[,，]/g, '');
  const match = text.match(/-?\d+(?:\.\d+)?/);
  return match ? Number(match[0]) : 0;
};

const parseCompareMarket = (value) => {
  if (typeof value === 'number') return value;
  const nums = String(value || '').replace(/[,，]/g, '').match(/-?\d+(?:\.\d+)?/g);
  if (!nums || !nums.length) return 0;
  const values = nums.map(Number).filter(Number.isFinite);
  if (!values.length) return 0;
  return values.reduce((sum, n) => sum + n, 0) / values.length;
};

const parseCompareMarketBounds = (value, current = 0) => {
  const nums = String(value || '').replace(/[,，]/g, '').match(/-?\d+(?:\.\d+)?/g);
  const values = (nums || []).map(Number).filter(Number.isFinite);
  if (values.length >= 2) return { low: Math.min(values[0], values[1]), high: Math.max(values[0], values[1]) };
  const base = values[0] || current || 0;
  return { low: Math.round(base * 0.85), high: Math.round(base * 1.15) };
};

const normalizeCompareRisk = (risk) => {
  const text = String(risk || '').toLowerCase();
  if (text.includes('high') || text.includes('高')) return 'high';
  if (text.includes('mid') || text.includes('medium') || text.includes('中')) return 'mid';
  if (text.includes('low') || text.includes('低')) return 'low';
  return 'mid';
};

const splitCompareTactics = (text, fallbackTitle = '谈判建议') => {
  const clean = String(text || '').trim();
  if (!clean) return [];
  const parts = clean
    .split(/\n+|[；;]/)
    .map(s => s.replace(/^\s*[-•\d.、)）]+\s*/, '').trim())
    .filter(Boolean);
  return (parts.length ? parts : [clean]).slice(0, 6).map((body, index) => ({
    title: index === 0 ? fallbackTitle : `建议 ${index + 1}`,
    body,
  }));
};

const compareItemBucket = (item) => {
  const name = String(item && item.name || '').toLowerCase();
  const normalized = name.replace(/[^\w\u4e00-\u9fff]/g, '');
  const buckets = [
    ['套餐基价', ['套餐', '基础', '基价', '硬装']],
    ['管理费', ['管理费']],
    ['设计费', ['设计费']],
    ['全屋定制', ['全屋定制', '定制']],
    ['橱柜', ['橱柜']],
    ['乳胶漆', ['乳胶漆', '涂料']],
    ['防水', ['防水']],
    ['水电', ['水电', '强电', '弱电', '电箱', '空开']],
    ['墙面修复/找平', ['墙面', '抹灰', '找平', '修复']],
    ['地面/地枕', ['地面', '地枕', '找平']],
    ['窗帘箱', ['窗帘箱']],
    ['洁具/座厕', ['座厕', '马桶', '洁具']],
  ];
  const hit = buckets.find(([, keys]) => keys.some(key => normalized.includes(key)));
  return hit ? hit[0] : (item.name || '未命名项目');
};

const matrixHasCompanyValues = (matrix, companies) => (matrix || []).some(row => (
  companies.some(c => {
    const cell = row[c.id] || {};
    const display = String(cell.display || '').trim();
    return normalizeCompareNumber(cell.unit_price) > 0
      || normalizeCompareNumber(cell.total) > 0
      || (display && !['—', '未列项', '遗漏', '不明确'].includes(display));
  })
));

const buildMatrixFromCompanyItems = (companies) => {
  const groups = new Map();
  companies.forEach(c => {
    (c.items || []).forEach(item => {
      const name = compareItemBucket(item);
      const unit = item.unit || '';
      const key = `${name}::${unit}`;
      if (!groups.has(key)) {
        groups.set(key, { name, unit, market_label: item.marketRange || '', items: new Map() });
      }
      const group = groups.get(key);
      if (!group.market_label && item.marketRange) group.market_label = item.marketRange;
      const existing = group.items.get(c.id);
      if (!existing || normalizeCompareNumber(item.total) > normalizeCompareNumber(existing.total)) {
        group.items.set(c.id, item);
      }
    });
  });

  return Array.from(groups.values()).map(group => {
    const row = {
      name: group.name,
      unit: group.unit,
      market: parseCompareMarket(group.market_label),
      market_label: group.market_label,
      cause: group.items.size > 1 ? 'price' : 'scope',
      conclusion: '由各家公司深度明细自动生成，用于补足模型横向矩阵缺失；同类项目口径仍需结合原报价复核。',
    };
    companies.forEach(c => {
      const item = group.items.get(c.id);
      if (item) {
        const unitPrice = normalizeCompareNumber(item.unitPrice);
        const qty = normalizeCompareNumber(item.qty);
        const total = normalizeCompareNumber(item.total);
        row[c.id] = {
          unit_price: unitPrice,
          qty,
          total,
          display: unitPrice ? `¥${unitPrice.toLocaleString()}` : (total === 0 ? '¥0' : `¥${total.toLocaleString()}`),
          status: 'ok',
          source_page: item.sourcePage,
          source_section: item.sourceSection || '',
        };
      } else {
        row[c.id] = {
          unit_price: 0,
          qty: 0,
          total: 0,
          display: '未列项',
          status: 'missing',
          source_page: null,
          source_section: '',
        };
      }
    });
    return row;
  }).sort((a, b) => {
    const countA = companies.filter(c => (a[c.id] || {}).status !== 'missing').length;
    const countB = companies.filter(c => (b[c.id] || {}).status !== 'missing').length;
    return countB - countA || a.name.localeCompare(b.name, 'zh-CN');
  });
};

const compareDataFromViewModel = (vm) => {
  const report = vm.report || {};
  const project = report.project || {};
  const summary = vm.summary || {};
  const recommendation = vm.recommendation || {};
  const priceDiff = vm.priceDiffAnalysis || {};
  const companies = (vm.companies || []).map((c, index) => {
    const coverage = c.coverageCheck || {};
    const total = normalizeCompareNumber(c.normalizedTotalPrice || c.totalPrice || c.originalTotalPrice);
    return {
      id: c.id || String.fromCharCode(65 + index),
      name: c.name || `公司${index + 1}`,
      short: c.short || (c.name || `公司${index + 1}`).slice(0, 2),
      total,
      score: normalizeCompareNumber(c.score),
      color: c.color || COMPARE_FALLBACK_COLORS[index % COMPARE_FALLBACK_COLORS.length],
      quote_scope: c.quoteScope || '报价范围未标注',
      material_inclusion: c.materialInclusion || '主材包含情况未标注',
      scope_note: c.scopeAdjustmentNote || '口径调整说明未标注',
      coverage_check: coverage,
      coverage_summary: [
        `范围：${c.quoteScope || '未标注'}`,
        `主材：${c.materialInclusion || '未标注'}`,
        `调整：${c.scopeAdjustmentNote || '未标注'}`,
        coverage.coverageNote ? `覆盖：${coverage.coverageNote}` : '',
      ].filter(Boolean),
      items: c.items || [],
      topRisks: c.topRisks || [],
      missingItems: c.missingItems || [],
      negotiationItems: c.negotiationItems || [],
      contractClauses: c.contractClauses || [],
    };
  });
  let matrix = (vm.matrix || []).map((row) => {
    const next = {
      name: row.name || '未命名项目',
      unit: row.unit || '',
      market: parseCompareMarket(row.marketRange),
      market_label: row.marketRange || '',
      cause: (row.cause && row.cause.id) || 'scope',
      conclusion: row.conclusion || '',
    };
    companies.forEach(c => {
      const cell = (row.cells || []).find(x => x.companyId === c.id || x.company === c.name) || {};
      const unitPrice = normalizeCompareNumber(cell.unitPrice || parseCompareMoney(cell.display));
      const qty = normalizeCompareNumber(cell.qty);
      next[c.id] = {
        unit_price: unitPrice,
        qty,
        total: normalizeCompareNumber(cell.total, unitPrice * qty),
        display: cell.display || (unitPrice ? `¥${unitPrice}` : '—'),
        status: cell.status || 'unclear',
        source_page: cell.sourcePage,
        source_section: cell.sourceSection || '',
      };
    });
    return next;
  });
  if (companies.length && (matrix.length < 2 || !matrixHasCompanyValues(matrix, companies))) {
    matrix = buildMatrixFromCompanyItems(companies);
  }

  const coverageStatus = {};
  companies.forEach(c => {
    coverageStatus[c.id] = (c.coverage_check && c.coverage_check.coverageStatus) || 'partial';
  });

  let totalDiffPct = normalizeCompareNumber(summary.totalDiffPct || priceDiff.totalDiffPct);
  if (totalDiffPct > 1) totalDiffPct = totalDiffPct / 100;

  const mainCauses = (priceDiff.mainCauses || summary.mainCauses || []).map(c => ({
    id: c.id || 'scope',
    label: c.label || '口径差异',
    weight: normalizeCompareNumber(c.weight, 0.2),
  }));
  const fallbackCauses = matrix.length
    ? Array.from(new Set(matrix.map(r => r.cause))).map(id => ({ id, label: id, weight: 0.2 }))
    : [];

  const bestValue = recommendation.bestValue || {};
  const tactics = splitCompareTactics(recommendation.negotiationTactics, '报价谈判策略');
  if (!tactics.length && bestValue.reason) {
    tactics.push({ title: '围绕推荐公司谈判', body: bestValue.reason });
  }

  return {
    meta: {
      project: project.name || vm.projectName || '多家报价对比',
      city_tier: project.cityTier || vm.cityTier || '城市未标注',
      review_date: project.reviewDate || vm.reviewDate || '',
      reviewer: 'BitBuild AI',
      area: normalizeCompareNumber(project.area || vm.area),
      n_companies: companies.length,
    },
    companies,
    total_diff_pct: totalDiffPct,
    best_value: {
      company: bestValue.company || summary.bestValueCompany || '未给出',
      reason: bestValue.reason || '模型未给出推荐原因',
    },
    cautious: recommendation.cautious || [],
    main_causes: mainCauses.length ? mainCauses : fallbackCauses,
    compare_matrix: matrix,
    coverage_status: coverageStatus,
    compare_notes: (vm.compareNotes && vm.compareNotes.length ? vm.compareNotes : [
      (vm.matrixCoverageCheck || {}).coverageNote,
      (priceDiff || {}).detail,
    ].filter(Boolean)),
    negotiation_tactics: tactics,
  };
};

const RealCompareState = ({ title, message, onBack, canRetry, onRetry }) => (
  <>
    <DetailHead skill="compare" title={title} onBack={onBack} />
    <div className="content">
      <div className="detail-wrap">
        <div className="detail-panel" style={{ padding: 24 }}>
          <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start' }}>
            <Icon name={canRetry ? 'circle-alert' : 'loader-2'} size={18} className={canRetry ? '' : 'spinning'} style={{ color: canRetry ? 'var(--risk-high)' : 'var(--compare)', marginTop: 2 }} />
            <div>
              <div className="detail-panel-title">{title}</div>
              <div className="detail-panel-sub" style={{ marginTop: 6 }}>{message}</div>
              <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
                <button className="btn btn-ghost" onClick={onBack}>返回</button>
                {canRetry && onRetry && (
                  <button className="btn btn-primary" onClick={onRetry}>
                    <Icon name="refresh-cw" size={14} /> 重新对比
                  </button>
                )}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </>
);

const CompareDetail = ({ onBack, turn, onExport }) => {
  const [tab, setTab] = React.useState('matrix');
  const [matrixFilter, setMatrixFilter] = React.useState('all');
  const [matrixSort, setMatrixSort] = React.useState('default');
  const [companyTab, setCompanyTab] = React.useState('A');
  const [showNotes, setShowNotes] = React.useState(true);
  const isReal = turn && turn.source === 'real';
  const hasRealResult = isReal && turn.status === 'done' && turn.viewModel && !turn.viewModel.reportMissing;
  const d = hasRealResult ? compareDataFromViewModel(turn.viewModel) : window.BB_DATA.MOCK_REVIEW_B;
  const fileSources = hasRealResult
    ? ((turn.viewModel && turn.viewModel.files) || [])
    : window.BB_DATA.FILE_SOURCES.compare;
  const handleExport = (format) => {
    if (turn && turn.jobId && onExport) onExport(turn.jobId, format);
  };

  if (isReal && turn.status === 'error') {
    return (
      <RealCompareState
        title="多家报价对比失败"
        message={turn.error || '真实 API 返回失败，请回到聊天卡片重试。'}
        onBack={onBack}
      />
    );
  }
  if (isReal && (!hasRealResult || !d)) {
    return (
      <RealCompareState
        title={turn.viewModel && turn.viewModel.reportMissing ? '对比报告模型缺失' : '多家报价对比运行中'}
        message={turn.viewModel && turn.viewModel.reportMissing ? '当前结果缺少 quote_compare_report_v1，详情页不会回退 mock。可以下载旧报告或重新对比。' : '真实对比仍在生成，完成后会展示稳定 report 数据。'}
        onBack={onBack}
      />
    );
  }

  const TABS = [
    { id: 'matrix',    label: '对比矩阵',  icon: 'table-2' },
    { id: 'scores',    label: '得分对比',  icon: 'bar-chart-3' },
    { id: 'company',   label: '公司深度',  icon: 'layers' },
    { id: 'pricediff', label: '价差分析',  icon: 'split' },
    { id: 'tactics',   label: '谈判策略',  icon: 'message-square-text' },
    { id: 'sources',   label: '文件来源',  icon: 'paperclip', badge: fileSources.length },
  ];

  // ---------- helpers ----------
  const getRowPrices = (row) => d.companies
    .map(c => row[c.id] ? row[c.id].unit_price : 0)
    .filter(v => Number.isFinite(v) && v > 0);
  const getRowMin = (row) => {
    const prices = getRowPrices(row);
    return prices.length ? Math.min(...prices) : 0;
  };
  const getRowMax = (row) => {
    const prices = getRowPrices(row);
    return prices.length ? Math.max(...prices) : 0;
  };
  const biggestDiff = (row) => {
    const min = getRowMin(row);
    const max = getRowMax(row);
    return min > 0 ? ((max - min) / min) : 0;
  };

  let matrix = d.compare_matrix;
  if (matrixFilter !== 'all') matrix = matrix.filter(r => r.cause === matrixFilter);
  if (matrixSort === 'diff_desc') matrix = [...matrix].sort((a, b) => biggestDiff(b) - biggestDiff(a));

  // Pre-compute "best combo" total = sum of (min unit_price × min qty) across all rows
  const bestComboTotal = d.compare_matrix.reduce((sum, row) => {
    const validCells = d.companies
      .map(c => row[c.id])
      .filter(v => v && Number.isFinite(v.unit_price) && v.unit_price > 0 && Number.isFinite(v.qty) && v.qty > 0);
    if (!validCells.length) return sum;
    const min = Math.min(...validCells.map(v => v.unit_price));
    const qty = Math.min(...validCells.map(v => v.qty));
    return sum + min * qty;
  }, 0);

  // ---------- tab render ----------
  return (
    <>
      <DetailHead skill="compare" title={`${d.meta.n_companies} 家报价横向对比`} onBack={onBack} />
      <div className="content">
        <div className="detail-wrap">

          <DetailSummary
            skill="compare"
            title={`${d.meta.n_companies} 家报价横向对比`}
            metaItems={[
              { icon: 'folder', text: d.meta.project },
              { icon: 'map-pin', text: d.meta.city_tier },
              { icon: 'calendar', text: d.meta.review_date },
              { icon: 'user', text: d.meta.reviewer },
              { icon: 'building', text: `${d.meta.n_companies} 家公司` },
              { icon: 'maximize', text: `${d.meta.area} ㎡` },
            ]}
          >
            {/* Companies row */}
            <div className="company-row">
              {d.companies.map(c => (
                <div className="company-chip" key={c.id} style={{ borderColor: c.color }}>
                  <div className="company-logo" style={{ background: c.color }}>{c.short[0]}</div>
                  <div className="company-meta">
                    <div className="company-name">{c.name}</div>
                    <div className="company-total">{fmtMoney(c.total)}</div>
                  </div>
                  <div className="company-score" style={{ color: c.color }}>
                    <strong>{c.score}</strong><span style={{ fontSize: 10, color: 'var(--text-muted)' }}>/100</span>
                  </div>
                </div>
              ))}
            </div>

            {/* Recommendation row */}
            <div className="recommend-row">
              <div className="recommend-card best">
                <div className="recommend-emoji">🏆</div>
                <div>
                  <div className="recommend-label">推荐</div>
                  <div className="recommend-name">{d.best_value.company}</div>
                  <div className="recommend-reason">{d.best_value.reason}</div>
                </div>
              </div>
              {d.cautious.map((c, i) => (
                <div className="recommend-card cautious" key={i}>
                  <div className="recommend-emoji">⚠️</div>
                  <div>
                    <div className="recommend-label">谨慎</div>
                    <div className="recommend-name">{c.company}</div>
                    <div className="recommend-reason">{c.reason}</div>
                  </div>
                </div>
              ))}
              <div className="recommend-card kpi">
                <div className="recommend-label">总价差异率</div>
                <div className="recommend-name big">{(d.total_diff_pct * 100).toFixed(1)}%</div>
                <div className="recommend-causes">
                  主因：
                  {d.main_causes.slice(0, 3).map((m, i) => (
                    <span key={i} className="cause-mini">{m.label}</span>
                  ))}
                </div>
              </div>
            </div>
          </DetailSummary>

          {/* Notes alert */}
          {showNotes && (
            <div className="compare-notes-alert">
              <Icon name="info" size={14} style={{ color: '#87530B', flexShrink: 0, marginTop: 2 }} />
              <div style={{ flex: 1 }}>
                <div style={{ fontWeight: 600, marginBottom: 4 }}>口径说明（{d.compare_notes.length}）</div>
                <ul style={{ margin: 0, paddingLeft: 20, lineHeight: 1.7 }}>
                  {d.compare_notes.map((n, i) => <li key={i}>{n}</li>)}
                </ul>
              </div>
              <button className="topbar-btn" style={{ width: 24, height: 24 }} onClick={() => setShowNotes(false)}>
                <Icon name="x" size={12} />
              </button>
            </div>
          )}

          <TabBar tabs={TABS} value={tab} onChange={setTab} />

          {tab === 'matrix' && (
            <div className="detail-panel">
              <div className="detail-panel-head" style={{ flexDirection: 'column', alignItems: 'stretch', gap: 12 }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                  <div>
                    <div className="detail-panel-title">分项对比矩阵</div>
                    <div className="detail-panel-sub">同一行内最高价标红、最低价标绿</div>
                  </div>
                  <div style={{ display: 'flex', gap: 6 }}>
                    <button
                      className={`btn ${matrixSort === 'default' ? 'btn-subtle' : 'btn-ghost'} btn-sm`}
                      onClick={() => setMatrixSort('default')}
                    >默认排序</button>
                    <button
                      className={`btn ${matrixSort === 'diff_desc' ? 'btn-subtle' : 'btn-ghost'} btn-sm`}
                      onClick={() => setMatrixSort('diff_desc')}
                    ><Icon name="arrow-down-wide-narrow" size={12} /> 按差异率</button>
                  </div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap' }}>
                  <span style={{ fontSize: 12, color: 'var(--text-secondary)' }}>按主因筛选：</span>
                  <button
                    className={`filter-pill ${matrixFilter === 'all' ? 'active' : ''}`}
                    onClick={() => setMatrixFilter('all')}
                  >全部 {d.compare_matrix.length}</button>
                  {d.main_causes.map(c => (
                    <button
                      key={c.id}
                      className={`filter-pill ${matrixFilter === c.id ? 'active' : ''}`}
                      onClick={() => setMatrixFilter(c.id)}
                    >{c.label}</button>
                  ))}
                </div>
              </div>

              <div className="matrix-scroll">
                <table className="data-table matrix-table">
                  <thead>
                    <tr>
                      <th style={{ position: 'sticky', left: 0, background: 'var(--bg-page)', zIndex: 2 }}>项目</th>
                      <th>单位</th>
                      <th style={{ textAlign: 'right' }}>市场价</th>
                      {d.companies.map(c => (
                        <th key={c.id} style={{ borderLeft: `2px solid ${c.color}` }}>
                          <div className="matrix-th">
                            <span className="matrix-th-dot" style={{ background: c.color }} />
                            {c.short}
                          </div>
                        </th>
                      ))}
                      <th style={{ textAlign: 'right' }}>最大差异</th>
                      <th>结论</th>
                    </tr>
                  </thead>
                  <tbody>
                    {matrix.map((row, i) => {
                      const min = getRowMin(row);
                      const max = getRowMax(row);
                      const bd = biggestDiff(row);
                      return (
                        <tr key={i}>
                          <td style={{ fontWeight: 500, position: 'sticky', left: 0, background: 'white', zIndex: 1 }}>{row.name}</td>
                          <td style={{ color: 'var(--text-secondary)' }}>{row.unit}</td>
                          <td style={{ textAlign: 'right', color: 'var(--text-muted)' }}>{row.market_label || `¥${row.market.toLocaleString()}`}</td>
                          {d.companies.map(c => {
                            const v = row[c.id];
                            const isMin = min > 0 && v.unit_price === min;
                            const isMax = max > 0 && v.unit_price === max && min !== max;
                            return (
                              <td key={c.id} className={`matrix-cell ${isMin ? 'min' : ''} ${isMax ? 'max' : ''}`}>
                                <div className="matrix-cell-price">{v.unit_price ? `¥${v.unit_price.toLocaleString()}` : (v.display || '—')}</div>
                                <div className="matrix-cell-qty">{v.qty ? `${v.qty} ${row.unit}` : v.status}</div>
                              </td>
                            );
                          })}
                          <td style={{ textAlign: 'right' }}>
                            <span className="diff-pill">+{(bd * 100).toFixed(0)}%</span>
                          </td>
                          <td style={{ color: 'var(--text-secondary)', fontSize: 12 }}>{row.conclusion}</td>
                        </tr>
                      );
                    })}
                  </tbody>
                </table>
              </div>

              <div className="matrix-legend">
                <span className="legend-dot legend-min" /> 行内最低价
                <span className="legend-dot legend-max" /> 行内最高价
                <span style={{ marginLeft: 'auto', color: 'var(--text-muted)' }}>{matrix.length} / {d.compare_matrix.length} 项</span>
              </div>
            </div>
          )}

          {tab === 'scores' && (
            <>
              <div className="detail-panel" style={{ marginBottom: 16 }}>
                <div className="detail-panel-head">
                  <div className="detail-panel-title">四维度得分对比</div>
                  <div className="detail-panel-sub">价格 / 工程量 / 条款 / 完整性</div>
                </div>
                <div style={{ padding: '20px 24px' }}>
                  <CompareScoreChart companies={d.companies} />
                </div>
              </div>

              <div className="detail-panel">
                <div className="detail-panel-head">
                  <div className="detail-panel-title">分项总览</div>
                </div>
                <table className="data-table">
                  <thead>
                    <tr>
                      <th>公司</th>
                      <th style={{ textAlign: 'right' }}>总价</th>
                      <th style={{ textAlign: 'right' }}>总分</th>
                      <th>覆盖度</th>
                      <th>核心评价</th>
                    </tr>
                  </thead>
                  <tbody>
                    {d.companies.map(c => (
                      <tr key={c.id}>
                        <td>
                          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                            <span className="company-logo" style={{ background: c.color, width: 24, height: 24 }}>{c.short[0]}</span>
                            <strong>{c.name}</strong>
                          </div>
                        </td>
                        <td style={{ textAlign: 'right', fontWeight: 600 }}>{fmtMoney(c.total)}</td>
                        <td style={{ textAlign: 'right' }}>
                          <span className="score-pill" style={{ background: c.color + '20', color: c.color }}>{c.score}</span>
                        </td>
                        <td>
                          <CoveragePill status={d.coverage_status[c.id]} />
                        </td>
                        <td style={{ color: 'var(--text-secondary)', fontSize: 12 }}>
                          {c.scope_note || c.quote_scope || c.material_inclusion || (
                            <>
                              {c.id === 'A' && '价格中位、阳台防水漏报'}
                              {c.id === 'B' && '总价偏高、吊顶/墙砖虚报严重'}
                              {c.id === 'C' && '工程量准确、单价友好、覆盖完整'}
                            </>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>
            </>
          )}

          {tab === 'company' && (
            <div className="detail-panel">
              <div className="detail-panel-head" style={{ paddingBottom: 0, borderBottom: 'none' }}>
                <div className="detail-panel-title">公司深度审核</div>
              </div>
              <div className="company-tabs">
                {d.companies.map(c => (
                  <button
                    key={c.id}
                    className={`company-tab ${companyTab === c.id ? 'active' : ''}`}
                    style={companyTab === c.id ? { borderColor: c.color, color: c.color } : {}}
                    onClick={() => setCompanyTab(c.id)}
                  >
                    <span className="company-logo" style={{ background: c.color, width: 22, height: 22 }}>{c.short[0]}</span>
                    {c.name}
                  </button>
                ))}
              </div>
              <CompanyDeepDive
                company={d.companies.find(c => c.id === companyTab) || d.companies[0]}
                allCompanies={d.companies}
                matrix={d.compare_matrix}
              />
            </div>
          )}

          {tab === 'pricediff' && (
            <>
              <div className="detail-panel" style={{ marginBottom: 16 }}>
                <div className="detail-panel-head">
                  <div className="detail-panel-title">价差成因分析</div>
                  <div className="detail-panel-sub">总价差异 {(d.total_diff_pct * 100).toFixed(1)}% 由以下因素构成</div>
                </div>
                <div style={{ padding: '20px 24px' }}>
                  <div className="cause-bars">
                    {d.main_causes.map(c => (
                      <div className="cause-bar" key={c.id}>
                        <div className="cause-bar-label">
                          <span>{c.label}</span>
                          <span className="cause-bar-pct">{(c.weight * 100).toFixed(0)}%</span>
                        </div>
                        <div className="cause-bar-track">
                          <div className="cause-bar-fill" style={{ width: (c.weight / 0.34 * 100) + '%' }} />
                        </div>
                      </div>
                    ))}
                  </div>
                </div>
              </div>

              <div className="detail-panel">
                <div className="detail-panel-head">
                  <div className="detail-panel-title">范围 / 覆盖度对比</div>
                </div>
                <div className="coverage-grid">
                  {d.companies.map(c => (
                    <div className="coverage-card" key={c.id}>
                      <div className="coverage-card-head">
                        <span className="company-logo" style={{ background: c.color }}>{c.short[0]}</span>
                        <strong>{c.name}</strong>
                        <CoveragePill status={d.coverage_status[c.id]} />
                      </div>
                      <div className="coverage-card-body">
                        {c.coverage_summary ? c.coverage_summary.map((line, index) => (
                          <React.Fragment key={index}>{line}<br/></React.Fragment>
                        )) : (
                          <>
                            {c.id === 'A' && (<>缺：阳台防水<br/>不清：水电改造范围<br/>主材：未指定品牌</>)}
                            {c.id === 'B' && (<>完整：所有分项已覆盖<br/>主材：实木复合（高一档）<br/>木工：含工艺溢价</>)}
                            {c.id === 'C' && (<>完整：含阳台防水<br/>主材：指定品牌<br/>水电：明示点位+米数</>)}
                          </>
                        )}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            </>
          )}

          {tab === 'tactics' && (
            <>
              <div className="detail-panel" style={{ marginBottom: 16 }}>
                <div className="detail-panel-head">
                  <div className="detail-panel-title">谈判策略</div>
                  <div className="detail-panel-sub">{d.negotiation_tactics.length} 条 AI 建议</div>
                </div>
                <div className="tactics-grid">
                  {d.negotiation_tactics.map((t, i) => (
                    <div className="tactic-card" key={i}>
                      <div className="tactic-num">{i + 1}</div>
                      <div className="tactic-title">{t.title}</div>
                      <div className="tactic-body">{t.body}</div>
                    </div>
                  ))}
                </div>
              </div>

              <div className="detail-panel">
                <div className="detail-panel-head">
                  <div>
                    <div className="detail-panel-title">取最低价组合 · 最优清单工具</div>
                    <div className="detail-panel-sub">每行选最低价（理论最优总价：{fmtMoney(bestComboTotal)}）</div>
                  </div>
                  <button className="btn btn-primary btn-sm">
                    <Icon name="download" size={12} /> 导出最优清单
                  </button>
                </div>
                <table className="data-table">
                  <thead>
                    <tr>
                      <th>项目</th>
                      <th>取自</th>
                      <th style={{ textAlign: 'right' }}>单价</th>
                      <th style={{ textAlign: 'right' }}>数量</th>
                      <th style={{ textAlign: 'right' }}>小计</th>
                    </tr>
                  </thead>
                  <tbody>
                    {d.compare_matrix.map((row, i) => {
                      const validCompanies = d.companies.filter(c => row[c.id] && row[c.id].unit_price > 0);
                      const minCo = validCompanies.reduce((best, c) => row[c.id].unit_price < row[best.id].unit_price ? c : best, validCompanies[0] || d.companies[0]);
                      const minCell = row[minCo.id] || { unit_price: 0, qty: 0 };
                      const minPrice = minCell.unit_price || 0;
                      const qtyCandidates = (validCompanies.length ? validCompanies : d.companies)
                        .map(c => row[c.id] ? row[c.id].qty || 0 : 0)
                        .filter(v => v > 0);
                      const minQty = qtyCandidates.length ? Math.min(...qtyCandidates) : 0;
                      return (
                        <tr key={i}>
                          <td style={{ fontWeight: 500 }}>{row.name}</td>
                          <td>
                            <span className="company-logo" style={{ background: minCo.color, width: 18, height: 18, fontSize: 10 }}>{minCo.short[0]}</span>
                            <span style={{ marginLeft: 6, fontSize: 12 }}>{minCo.name}</span>
                          </td>
                          <td style={{ textAlign: 'right', color: 'var(--risk-low)', fontWeight: 600 }}>{minPrice ? `¥${minPrice.toLocaleString()}` : '—'}</td>
                          <td style={{ textAlign: 'right' }}>{minQty || 0} {row.unit}</td>
                          <td style={{ textAlign: 'right', fontWeight: 600 }}>{minPrice && minQty ? `¥${(minPrice * minQty).toLocaleString()}` : '—'}</td>
                        </tr>
                      );
                    })}
                    <tr>
                      <td colSpan={4} style={{ textAlign: 'right', fontWeight: 600 }}>合计</td>
                      <td style={{ textAlign: 'right', fontWeight: 700, color: 'var(--compare)' }}>{fmtMoney(bestComboTotal)}</td>
                    </tr>
                  </tbody>
                </table>
              </div>
            </>
          )}

          {tab === 'sources' && (
            <FileSourcesPanel
              skill="compare"
              files={fileSources}
              companies={d.companies}
              summary={`${d.companies.length} 家报价单 + 1 份口径说明 · 已按公司分组列出`}
            />
          )}

          <DetailActions>
            <button className="btn btn-primary" disabled={isReal && !(turn && turn.jobId)} onClick={() => handleExport('excel')}>
              <Icon name="file-spreadsheet" size={14} /> 导出对比 Excel
            </button>
            <button className="btn btn-ghost" disabled={isReal && !(turn && turn.jobId)} onClick={() => handleExport('pdf')}>
              <Icon name="file-text" size={14} /> 下载 PDF
            </button>
            <button className="btn btn-ghost" style={{ marginLeft: 'auto' }}>
              <Icon name="layers" size={14} /> 针对推荐家做联审
            </button>
          </DetailActions>
        </div>
      </div>
    </>
  );
};

// ----- Compare-internal helpers -----
const CoveragePill = ({ status }) => {
  const map = {
    complete: { label: '完整', color: 'var(--risk-low)', bg: 'var(--risk-low-bg)' },
    partial:  { label: '部分', color: 'var(--risk-mid)', bg: 'var(--risk-mid-bg)' },
    unclear:  { label: '不清', color: 'var(--risk-high)', bg: 'var(--risk-high-bg)' },
  };
  const m = map[status] || map.partial;
  return <span className="coverage-pill" style={{ background: m.bg, color: m.color }}>{m.label}</span>;
};

// 4-axis grouped bar chart
const CompareScoreChart = ({ companies }) => {
  // Each company's 4 score breakdown — derive from B-mock's company score weights
  // For demo, scale total score across 4 axes deterministically
  const axes = [
    { key: 'price', label: '价格', max: 40 },
    { key: 'qty',   label: '工程量', max: 25 },
    { key: 'cls',   label: '条款', max: 25 },
    { key: 'comp',  label: '完整性', max: 10 },
  ];
  // Demo splits per company (normalized to sum ≈ score)
  const splits = {
    A: [0.42, 0.28, 0.20, 0.10], // 28/72=39%
    B: [0.36, 0.22, 0.31, 0.11],
    C: [0.39, 0.31, 0.20, 0.10],
  };
  const data = axes.map((a, ai) => ({
    label: a.label,
    max: a.max,
    bars: companies.map(c => {
      const split = splits[c.id] || [0.40, 0.25, 0.25, 0.10];
      return { co: c, value: Math.round((c.score || 0) * split[ai]) };
    }),
  }));
  return (
    <div className="grouped-bars">
      {data.map((row, i) => (
        <div className="grouped-row" key={i}>
          <div className="grouped-row-label">{row.label} <small>/{row.max}</small></div>
          <div className="grouped-row-bars">
            {row.bars.map((b, j) => (
              <div className="grouped-bar-wrap" key={j}>
                <div className="grouped-bar-fill" style={{ width: (b.value / row.max * 100) + '%', background: b.co.color }}>
                  <span className="grouped-bar-num">{b.value}</span>
                </div>
              </div>
            ))}
          </div>
        </div>
      ))}
      <div className="grouped-legend">
        {data[0].bars.map((b, i) => (
          <span key={i} className="grouped-legend-item">
            <span className="legend-dot" style={{ background: b.co.color }} />
            {b.co.name}
          </span>
        ))}
      </div>
    </div>
  );
};

// Single-company deep dive — synthesizes A-mode style audit per company
const CompanyDeepDive = ({ company, allCompanies, matrix }) => {
  const co = company;
  if (!co) return null;
  const detailedItems = (co.items || []).map(it => {
    const unitPrice = normalizeCompareNumber(it.unitPrice);
    const bounds = parseCompareMarketBounds(it.marketRange, unitPrice);
    return {
      name: it.name || '未命名项目',
      unit: it.unit || '',
      qty: normalizeCompareNumber(it.qty),
      unit_price: unitPrice,
      total: normalizeCompareNumber(it.total, unitPrice * normalizeCompareNumber(it.qty)),
      market_low: bounds.low,
      market_high: bounds.high,
      risk: normalizeCompareRisk(it.risk),
      note: it.comment || '',
    };
  });
  const matrixItems = matrix.map(row => {
    const v = row[co.id] || { unit_price: 0, qty: 0 };
    const total = v.unit_price * v.qty;
    const market = row.market || v.unit_price || 0;
    const dev = market ? (v.unit_price - market) / market : 0;
    const risk = Math.abs(dev) > 0.18 ? 'high' : Math.abs(dev) > 0.08 ? 'mid' : 'low';
    return {
      name: row.name, unit: row.unit, qty: v.qty,
      unit_price: v.unit_price, total,
      market_low: Math.round(market * 0.85),
      market_high: Math.round(market * 1.15),
      risk,
      note: `市场参考 ${row.market_label || `¥${market}`}`,
    };
  });
  const items = detailedItems.length ? detailedItems : matrixItems;
  const high = items.filter(i => i.risk === 'high').length;
  const mid  = items.filter(i => i.risk === 'mid').length;
  const low  = items.filter(i => i.risk === 'low').length;

  return (
    <div className="deep-dive">
      <div className="deep-dive-summary">
        <ScoreGauge value={co.score} max={100} color={co.color} size={84} label="/100" />
        <div className="deep-dive-stats">
          <div>
            <div className="deep-dive-stat-label">总价</div>
            <div className="deep-dive-stat-value">{fmtMoney(co.total)}</div>
          </div>
          <div>
            <div className="deep-dive-stat-label">分项数</div>
            <div className="deep-dive-stat-value">{items.length}</div>
          </div>
          <div>
            <div className="deep-dive-stat-label">风险</div>
            <div className="deep-dive-stat-value" style={{ fontSize: 14 }}>
              <RiskCountChips counts={{ high, mid, low }} />
            </div>
          </div>
        </div>
      </div>
      <table className="data-table" style={{ marginTop: 12 }}>
        <thead>
          <tr>
            <th>项目</th>
            <th style={{ textAlign: 'right' }}>数量</th>
            <th style={{ textAlign: 'right' }}>单价</th>
            <th style={{ textAlign: 'right' }}>小计</th>
            <th style={{ width: 200 }}>市场区间</th>
            <th>风险</th>
          </tr>
        </thead>
        <tbody>
          {items.map((it, i) => (
            <tr key={i} className={riskRowClass(it.risk)}>
              <td style={{ fontWeight: 500 }}>{it.name}</td>
              <td style={{ textAlign: 'right' }}>{it.qty} {it.unit}</td>
              <td style={{ textAlign: 'right' }}>¥{it.unit_price.toLocaleString()}</td>
              <td style={{ textAlign: 'right', fontWeight: 600 }}>¥{it.total.toLocaleString()}</td>
              <td><MarketRangeBar value={it.unit_price} low={it.market_low} high={it.market_high} /></td>
              <td><span className={`risk-pill risk-pill-${it.risk}`}>{it.risk === 'high' ? '高' : it.risk === 'mid' ? '中' : '低'}</span></td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

window.CompareDetail = CompareDetail;
