// QuoteDetail — Mode A: single-vendor audit
const quoteMoney = (value) => (
  typeof value === 'number' ? `¥${value.toLocaleString()}` : (value || '—')
);

const quoteDataFromViewModel = (vm) => ({
  meta: {
    company: vm.company,
    project: vm.projectName,
    city_tier: vm.cityTier,
    review_date: vm.reviewDate,
    reviewer: 'BitBuild AI',
    version: vm.resultVersion,
    quote_amount: vm.totalPrice,
    area: vm.area,
    area_type: vm.areaType,
  },
  total_score: vm.totalScore,
  score_breakdown: vm.scoreBreakdown,
  risk_counts: vm.riskCounts,
  missing_count: vm.missingCount,
  top_risks: (vm.topRisks || []).map(r => ({ level: r.level || 'high', title: r.title, suggestion: r.suggestion })),
  items: (vm.items || []).map(item => ({
    name: item.name,
    unit: item.unit,
    qty: item.qty,
    unit_price: item.unitPrice,
    total: item.total,
    market_range: item.marketRange,
    risk: item.risk,
    note: item.comment,
    source_page: item.sourcePage,
    source_section: item.sourceSection,
  })),
  negotiation: (vm.negotiation || []).map(item => ({
    item: item.name,
    current: item.current,
    target: item.target,
    discount: item.discount,
    reason: item.reason,
  })),
  missing_items: vm.missingItems || [],
  contract_clauses: vm.contractClauses || [],
  warnings: vm.warnings || [],
  coverage_check: vm.coverageCheck || null,
});

const quoteRiskTone = (score) => {
  const value = Number(score);
  if (value >= 85) return '风险较低';
  if (value >= 70) return '中等风险';
  if (value >= 60) return '中等偏上风险';
  return '高风险';
};

const quoteWeakestScore = (rows) => {
  const validRows = (rows || [])
    .filter(row => Number(row.max) > 0)
    .map(row => ({ ...row, ratio: Number(row.score) / Number(row.max) }))
    .sort((a, b) => a.ratio - b.ratio);
  return validRows[0] || null;
};

const QuoteConclusion = ({ data }) => {
  const scoreIssue = quoteWeakestScore(data.score_breakdown);
  const firstRisk = (data.top_risks || [])[0];
  const firstMissing = (data.missing_items || [])[0];
  const firstMissingName = typeof firstMissing === 'string' ? firstMissing : firstMissing && firstMissing.name;
  const clauseCount = (data.contract_clauses || []).length;
  const negotiationCount = (data.negotiation || []).length;

  return (
    <>
      报价整体水平 <strong>{quoteRiskTone(data.total_score)}</strong>，总分 <strong>{data.total_score}/100</strong>。
      {scoreIssue && (
        <>
          <br/>
          主要扣分集中在 <strong>{scoreIssue.label}</strong>（{scoreIssue.score}/{scoreIssue.max}）。
        </>
      )}
      {firstRisk && (
        <>
          <br/>
          优先复核 <strong>{firstRisk.title}</strong>。
        </>
      )}
      {firstMissingName && (
        <>
          漏项方面建议先补确认 <strong>{firstMissingName}</strong>。
        </>
      )}
      <div style={{ marginTop: 10, color: 'var(--text-secondary)', fontSize: 12 }}>
        当前识别 <strong>{data.items.length}</strong> 项明细，漏项 <strong>{data.missing_count}</strong> 项，
        可谈判项 <strong>{negotiationCount}</strong> 项，合同条款需关注 <strong>{clauseCount}</strong> 项。
      </div>
    </>
  );
};

const QuoteDetail = ({ turn, onBack, onExport }) => {
  const [tab, setTab] = React.useState('score');
  const [filterRisk, setFilterRisk] = React.useState('all');
  const [openClause, setOpenClause] = React.useState(null);
  const isReal = turn && turn.source === 'real';
  const vm = isReal ? turn.viewModel : null;
  const hasRealResult = isReal && turn.status === 'done' && vm && !vm.reportMissing;
  const isError = isReal && turn.status === 'error';

  if (isReal && !hasRealResult) {
    const title = vm ? vm.projectName : '报价审核';
    const message = isError
      ? (turn.error || '报价审核失败，请返回对话重新审核。')
      : (vm && vm.reportMissing)
        ? '报告模型缺失，请重新审核或下载旧报告。'
        : '后端 /api/review/single 请求还在运行，完成后这里会展示真实报价审核报告。';
    return (
      <>
        <DetailHead skill="quote" title={`${title} · 报价审核状态`} onBack={onBack} />
        <div className="content">
          <div className="detail-wrap">
            <div className="detail-panel">
              <div className="detail-panel-head">
                <div>
                  <div className="detail-panel-title">{isError ? '审核失败' : vm && vm.reportMissing ? '报告模型缺失' : '正在审核中'}</div>
                  <div className="detail-panel-sub">真实报价审核不回退 mock 数据</div>
                </div>
              </div>
              <div className="review-list">
                <div className="review-item">
                  <Icon name={isError || (vm && vm.reportMissing) ? 'circle-alert' : 'loader-2'} size={14} className={isError || (vm && vm.reportMissing) ? '' : 'icon spinning'} style={{ marginTop: 1, color: isError || (vm && vm.reportMissing) ? 'var(--risk-high)' : 'var(--quote)' }} />
                  <span>{message}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </>
    );
  }

  const d = hasRealResult ? quoteDataFromViewModel(vm) : window.BB_DATA.MOCK_REVIEW_A;
  const fileSources = hasRealResult ? (vm.files || []) : window.BB_DATA.FILE_SOURCES.quote;
  const coverage = d.coverage_check;
  const handleExport = (format) => {
    if (hasRealResult && onExport && turn.jobId) onExport(turn.jobId, format);
  };

  const TABS = [
    { id: 'score',     label: '得分卡',    icon: 'gauge' },
    { id: 'risks',     label: 'TOP 风险',  icon: 'alert-triangle', badge: d.top_risks.length },
    { id: 'items',     label: '明细审核',  icon: 'list-checks' },
    { id: 'negotiate', label: '谈判 & 漏项', icon: 'message-square-dot' },
    { id: 'clauses',   label: '合同条款',  icon: 'file-text' },
    { id: 'sources',   label: '文件来源',  icon: 'paperclip', badge: fileSources.length },
  ];

  return (
    <>
      <DetailHead skill="quote" title={`${d.meta.company} · 报价审核报告`} onBack={onBack} />
      <div className="content">
        <div className="detail-wrap">
          <DetailSummary
            skill="quote"
            title={`${d.meta.company} · 报价审核报告`}
            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: 'git-branch', text: d.meta.version },
            ]}
            metrics={[
              {
                label: '总分',
                node: <ScoreGauge value={d.total_score} max={100} color="var(--quote)" size={84} label="/100" />,
              },
              { label: '报价金额', value: fmtMoney(d.meta.quote_amount), style: { fontSize: 22 } },
              { label: '面积', value: d.meta.area, unit: '㎡' },
              {
                label: '风险数',
                node: <RiskCountChips counts={d.risk_counts} />,
              },
              { label: '漏项', value: d.missing_count, unit: '项', style: { color: 'var(--risk-mid)' } },
            ]}
          />

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

          {tab === 'score' && (
            <div className="detail-panel">
              <div className="detail-panel-head">
                <div className="detail-panel-title">评分细则</div>
                <div className="detail-panel-sub">总分 {d.total_score} / 100</div>
              </div>
              <div style={{ padding: '20px 24px', display: 'grid', gridTemplateColumns: '1.4fr 1fr', gap: 32, alignItems: 'center' }}>
                <ScoreBars scores={d.score_breakdown} color="var(--quote)" />
                <div className="conclusion-card">
                  <div className="conclusion-head">
                    <Icon name="message-square-text" size={14} style={{ color: 'var(--quote)' }} />
                    AI 综合结论
                  </div>
                  <div className="conclusion-body">
                    <QuoteConclusion data={d} />
                  </div>
                </div>
              </div>
            </div>
          )}

          {tab === 'risks' && (
            <div className="detail-panel">
              <div className="detail-panel-head">
                <div className="detail-panel-title">TOP {d.top_risks.length} 风险点</div>
                <div className="detail-panel-sub">按严重度排序</div>
              </div>
              <div className="risk-card-list">
                {d.top_risks.map((r, i) => (
                  <RiskItemCard key={i} {...r} idx={i} />
                ))}
              </div>
            </div>
          )}

          {tab === 'items' && (
            <div className="detail-panel">
              <div className="detail-panel-head">
                <div className="detail-panel-title">明细审核 · {d.items.length} 项</div>
                <div className="detail-panel-sub">
                  {coverage
                    ? `识别/输出 ${coverage.recognizedQuoteItemCount || coverage.recognized_quote_item_count || 0} / ${coverage.outputItemCount || coverage.output_item_count || d.items.length} 项`
                    : '行底色按风险着色'}
                </div>
              </div>
              {coverage && (
                <div className="file-source-summary" style={{ background: 'var(--quote)', color: 'white' }}>
                  <Icon name={coverage.coverageStatus === 'complete' || coverage.coverage_status === 'complete' ? 'check-circle-2' : 'triangle-alert'} size={13} />
                  <span>
                    明细覆盖：{coverage.coverageStatus || coverage.coverage_status || 'unclear'} · {coverage.coverageNote || coverage.coverage_note || '未提供覆盖说明'}
                  </span>
                </div>
              )}
              <div style={{ padding: '12px 16px 0' }}>
                <ItemsTable items={d.items} filterRisk={filterRisk} onSetFilter={setFilterRisk} />
              </div>
            </div>
          )}

          {tab === 'negotiate' && (
            <>
              <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.length} 项可议价</div>
                </div>
                <table className="data-table">
                  <thead>
                    <tr>
                      <th>项目</th>
                      <th style={{ textAlign: 'right' }}>当前价</th>
                      <th style={{ textAlign: 'right' }}>目标价</th>
                      <th style={{ textAlign: 'right' }}>降幅</th>
                      <th>谈判理由</th>
                    </tr>
                  </thead>
                  <tbody>
                    {d.negotiation.map((n, i) => (
                      <tr key={i}>
                        <td style={{ fontWeight: 500 }}>{n.item}</td>
                        <td style={{ textAlign: 'right' }}>{quoteMoney(n.current)}</td>
                        <td style={{ textAlign: 'right', color: 'var(--risk-low)', fontWeight: 600 }}>{quoteMoney(n.target)}</td>
                        <td style={{ textAlign: 'right' }}>
                          <span className="discount-pill">{n.discount}</span>
                        </td>
                        <td style={{ color: 'var(--text-secondary)', fontSize: 12 }}>{n.reason}</td>
                      </tr>
                    ))}
                  </tbody>
                </table>
              </div>

              <div className="detail-panel">
                <div className="detail-panel-head">
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                    <Icon name="plus-circle" size={14} style={{ color: 'var(--risk-mid)' }} />
                    <div className="detail-panel-title">疑似漏项 · {d.missing_items.length} 项</div>
                  </div>
                </div>
                <div className="missing-list">
                  {d.missing_items.map((m, i) => (
                    <div className="missing-item" key={i}>
                      <Icon name="plus-circle" size={16} style={{ color: 'var(--risk-mid)', flexShrink: 0 }} />
                      <div style={{ flex: 1 }}>
                        <div className="missing-item-name">{m.name || m}</div>
                        <div className="missing-item-why">{m.why || '报价中未明确列出，建议签约前确认。'}</div>
                      </div>
                      <button className="btn btn-ghost btn-sm">
                        <Icon name="plus" size={12} /> 加入清单
                      </button>
                    </div>
                  ))}
                </div>
              </div>
            </>
          )}

          {tab === 'clauses' && (
            <div className="detail-panel">
              <div className="detail-panel-head">
                <div className="detail-panel-title">合同条款审核</div>
                <button className="btn btn-ghost"><Icon name="copy" size={13} /> 复制全部</button>
              </div>
              {d.contract_clauses.map((c, i) => (
                <div className={`clause-item ${c.type === 'risk' ? 'clause-risk' : 'clause-ok'}`} key={i}>
                  <div className="clause-head" onClick={() => setOpenClause(openClause === i ? null : i)}>
                    <span className={`clause-pill ${c.type === 'risk' ? 'risk-pill-mid' : 'risk-pill-low'}`}>
                      {c.type === 'risk' ? '风险' : '合理'}
                    </span>
                    <span className="clause-title">{c.title}</span>
                    <Icon name={openClause === i ? 'chevron-up' : 'chevron-down'} size={14} style={{ marginLeft: 'auto', color: 'var(--text-secondary)' }} />
                  </div>
                  {openClause === i && (
                    <div className="clause-body">
                      <div className="clause-quote">「{c.content}」</div>
                      <div className="clause-advice">
                        <Icon name="lightbulb" size={12} style={{ color: 'var(--quote)' }} />
                        <span>{c.advice}</span>
                      </div>
                    </div>
                  )}
                </div>
              ))}
            </div>
          )}

          {tab === 'sources' && (
            <FileSourcesPanel
              skill="quote"
              files={fileSources}
              summary={hasRealResult ? `本次审核基于 ${fileSources.length} 份上传报价文件 · 结果来自 /api/review/single · 展示口径来自 quote_report_model` : `本次审核基于 ${fileSources.length} 份输入文件 · 报价单 + 合同 + 主材清单`}
            />
          )}

          <DetailActions>
            <button className="btn btn-primary" disabled={hasRealResult && !turn.jobId} onClick={() => handleExport('excel')}><Icon name="file-spreadsheet" size={14} /> 下载 Excel</button>
            <button className="btn btn-ghost" disabled={hasRealResult && !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>
    </>
  );
};

window.QuoteDetail = QuoteDetail;
