// Shared detail components — reused across quantity / quote / combined / compare modes
const fmtMoney = (n) => {
  if (typeof n !== 'number') return n;
  const abs = Math.abs(n);
  if (abs >= 10000) return (n / 10000).toFixed(2) + ' 万';
  return '¥' + n.toLocaleString('zh-CN');
};
const fmtMoneySigned = (n) => (n >= 0 ? '+' : '−') + fmtMoney(Math.abs(n));
const fmtPct = (v, digits = 1) => (v >= 0 ? '+' : '−') + (Math.abs(v) * 100).toFixed(digits) + '%';

const SKILL_THEMES = {
  quantity: { color: 'var(--quantity)', bg: '#E7F1FB', icon: 'ruler',        title: '工程量算量报告' },
  quote:    { color: 'var(--quote)',    bg: '#FDEBD0', icon: 'search-check', title: '报价审核报告' },
  combined: { color: 'var(--combined)', bg: '#EEDDF5', icon: 'layers',       title: '图纸+报价联审报告' },
  compare:  { color: 'var(--compare)',  bg: '#D5F5E3', icon: 'scale',        title: '多家报价横向对比' },
};

// ----- Score gauge — radial 0-100 ring -----
const ScoreGauge = ({ value, max = 100, color = 'var(--quote)', size = 96, label = '总分' }) => {
  const r = (size - 12) / 2;
  const c = 2 * Math.PI * r;
  const pct = Math.max(0, Math.min(1, value / max));
  return (
    <div className="score-gauge" style={{ width: size, height: size }}>
      <svg viewBox={`0 0 ${size} ${size}`} width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--bg-subtle)" strokeWidth="8" />
        <circle
          cx={size/2} cy={size/2} r={r}
          fill="none" stroke={color} strokeWidth="8"
          strokeLinecap="round"
          strokeDasharray={c} strokeDashoffset={c * (1 - pct)}
          transform={`rotate(-90 ${size/2} ${size/2})`}
          style={{ transition: 'stroke-dashoffset .6s ease' }}
        />
      </svg>
      <div className="score-gauge-inner">
        <div className="score-gauge-value">{value}</div>
        <div className="score-gauge-label">{label}</div>
      </div>
    </div>
  );
};

// ----- Score bars — 4 horizontal bars -----
const ScoreBars = ({ scores, color = 'var(--quote)' }) => (
  <div className="score-bars">
    {scores.map((s) => {
      const pct = (s.score / s.max) * 100;
      return (
        <div className="score-bar" key={s.key}>
          <div className="score-bar-row">
            <span className="score-bar-label">{s.label}</span>
            <span className="score-bar-num">
              <strong>{s.score}</strong>
              <span className="score-bar-max">/ {s.max}</span>
            </span>
          </div>
          <div className="score-bar-track">
            <div className="score-bar-fill" style={{ width: pct + '%', background: color }} />
          </div>
          {s.note && <div className="score-bar-note">{s.note}</div>}
        </div>
      );
    })}
  </div>
);

// ----- Risk count chips -----
const RiskCountChips = ({ counts, layout = 'row' }) => (
  <div className={`risk-chips risk-chips-${layout}`}>
    <span className="risk-chip risk-chip-high">
      <span className="risk-dot" />
      高风险 <strong>{counts.high}</strong>
    </span>
    <span className="risk-chip risk-chip-mid">
      <span className="risk-dot" />
      中风险 <strong>{counts.mid}</strong>
    </span>
    <span className="risk-chip risk-chip-low">
      <span className="risk-dot" />
      低风险 <strong>{counts.low}</strong>
    </span>
  </div>
);

// ----- Risk item card -----
const RiskItemCard = ({ level, title, suggestion, idx }) => (
  <div className={`risk-card risk-card-${level}`}>
    <div className="risk-card-band" />
    <div className="risk-card-body">
      <div className="risk-card-head">
        <span className={`risk-pill risk-pill-${level}`}>
          {level === 'high' ? '高' : level === 'mid' ? '中' : '低'}
        </span>
        {idx !== undefined && <span className="risk-card-idx">#{idx + 1}</span>}
        <div className="risk-card-title">{title}</div>
      </div>
      {suggestion && (
        <div className="risk-card-suggest">
          <Icon name="lightbulb" size={12} style={{ color: 'var(--text-muted)', marginTop: 2 }} />
          <span>{suggestion}</span>
        </div>
      )}
    </div>
  </div>
);

// ----- Market range bar — current vs [low, high] -----
const MarketRangeBar = ({ value, low, high, rangeText }) => {
  if (!Number.isFinite(Number(low)) || !Number.isFinite(Number(high))) {
    return <span style={{ color: 'var(--text-secondary)', fontSize: 12 }}>{rangeText || '—'}</span>;
  }
  low = Number(low);
  high = Number(high);
  value = Number(value);
  // Compute span from 0.85 * low to 1.15 * high so value is always in range
  const min = Math.min(low * 0.85, value * 0.95);
  const max = Math.max(high * 1.15, value * 1.05);
  const span = max - min;
  const lowPct = ((low - min) / span) * 100;
  const highPct = ((high - min) / span) * 100;
  const valPct = ((value - min) / span) * 100;
  const status = value > high ? 'high' : value < low ? 'low' : 'mid';
  return (
    <div className="market-range">
      <div className="market-range-track">
        <div className="market-range-band" style={{ left: lowPct + '%', width: (highPct - lowPct) + '%' }} />
        <div className={`market-range-pin market-range-pin-${status}`} style={{ left: valPct + '%' }}>
          <span className="market-range-pin-val">{typeof value === 'number' ? value : '—'}</span>
        </div>
      </div>
      <div className="market-range-scale">
        <span>{low}</span>
        <span>{high}</span>
      </div>
    </div>
  );
};

// ----- Diff bar — diverging ± from 0 -----
const DiffBar = ({ value, max = 0.4 }) => {
  // value = diff_rate; positive = right (red, virtual report), negative = left (green, missing)
  const clamped = Math.max(-max, Math.min(max, value));
  const pct = (Math.abs(clamped) / max) * 50;
  const positive = value >= 0;
  return (
    <div className="diff-bar">
      <div className="diff-bar-track">
        <div className="diff-bar-zero" />
        <div
          className={`diff-bar-fill ${positive ? 'pos' : 'neg'}`}
          style={positive
            ? { left: '50%', width: pct + '%' }
            : { right: '50%', width: pct + '%' }}
        />
      </div>
      <span className={`diff-bar-num ${positive ? 'pos' : 'neg'}`}>{fmtPct(value)}</span>
    </div>
  );
};

// ----- Risk row coloring helper -----
const riskRowClass = (risk) => `risk-row-${risk}`;

// ----- Items table — used in Quote audit & Combined -----
const ItemsTable = ({ items, filterRisk, onSetFilter }) => {
  const filtered = filterRisk === 'all' ? items : items.filter(i => i.risk === filterRisk);
  const hasSource = items.some(i => i.source_page || i.sourcePage || i.source_section || i.sourceSection);
  const sourceText = (it) => {
    const page = it.source_page || it.sourcePage;
    const section = it.source_section || it.sourceSection;
    const pageText = page ? `P${page}` : '页码未标';
    return section ? `${pageText} · ${section}` : pageText;
  };
  return (
    <>
      <div className="items-toolbar">
        <span className="items-toolbar-label">筛选：</span>
        {['all', 'high', 'mid', 'low'].map(r => (
          <button
            key={r}
            className={`filter-pill ${filterRisk === r ? 'active' : ''} ${r !== 'all' ? 'risk-pill-' + r : ''}`}
            onClick={() => onSetFilter(r)}
          >
            {r === 'all' ? `全部 ${items.length}` : r === 'high' ? '高' : r === 'mid' ? '中' : '低'}
          </button>
        ))}
      </div>
      <table className="data-table items-table">
        <thead>
          <tr>
            <th>项目</th>
            <th>单位</th>
            <th style={{ textAlign: 'right' }}>数量</th>
            <th style={{ textAlign: 'right' }}>单价</th>
            <th style={{ textAlign: 'right' }}>总价</th>
            <th style={{ width: 200 }}>市场区间</th>
            <th>风险</th>
            {hasSource && <th>来源</th>}
            <th>备注</th>
          </tr>
        </thead>
        <tbody>
          {filtered.map((it, i) => (
            <tr key={i} className={riskRowClass(it.risk)}>
              <td style={{ fontWeight: 500 }}>{it.name}</td>
              <td style={{ color: 'var(--text-secondary)' }}>{it.unit}</td>
              <td style={{ textAlign: 'right' }}>{it.qty}</td>
              <td style={{ textAlign: 'right' }}>¥{Number(it.unit_price || 0).toLocaleString()}</td>
              <td style={{ textAlign: 'right', fontWeight: 600 }}>¥{Number(it.total || 0).toLocaleString()}</td>
              <td><MarketRangeBar value={it.unit_price} low={it.market_low} high={it.market_high} rangeText={it.market_range} /></td>
              <td><span className={`risk-pill risk-pill-${it.risk}`}>{it.risk === 'high' ? '高' : it.risk === 'mid' ? '中' : '低'}</span></td>
              {hasSource && <td style={{ color: 'var(--text-secondary)', fontSize: 12 }}>{sourceText(it)}</td>}
              <td style={{ color: 'var(--text-secondary)', fontSize: 12 }}>{it.note || it.comment}</td>
            </tr>
          ))}
        </tbody>
      </table>
    </>
  );
};

// ----- Data source chip (quantity mode) -----
const DataSourceChip = ({ source }) => {
  const map = {
    drawing:  { label: '从图', color: 'var(--quantity)', bg: '#E7F1FB', icon: 'file-image' },
    inferred: { label: '推算', color: 'var(--risk-mid)', bg: 'var(--risk-mid-bg)', icon: 'sigma' },
    estimate: { label: '经验估算', color: 'var(--text-secondary)', bg: 'var(--bg-subtle)', icon: 'lightbulb' },
  };
  const m = map[source] || map.estimate;
  return (
    <span className="source-chip" style={{ color: m.color, background: m.bg }}>
      <Icon name={m.icon} size={11} />
      {m.label}
    </span>
  );
};

// ----- Detail summary header — 4 themes -----
const DetailSummary = ({ skill, title, metaItems, metrics, children, actions }) => {
  const theme = SKILL_THEMES[skill] || SKILL_THEMES.quantity;
  return (
    <div className="detail-summary" data-skill={skill}>
      <div className="detail-summary-top">
        <div>
          <div className="detail-summary-title">
            <div className="modal-icon" style={{ width: 36, height: 36, borderRadius: 10, background: theme.bg, color: theme.color }}>
              <Icon name={theme.icon} size={18} />
            </div>
            {title || theme.title}
          </div>
          {metaItems && (
            <div className="detail-summary-meta" style={{ marginTop: 10 }}>
              {metaItems.map((m, i) => (
                <span key={i}><Icon name={m.icon} size={12} /> {m.text}</span>
              ))}
            </div>
          )}
        </div>
        <div style={{ display: 'flex', gap: 6, alignItems: 'flex-start' }}>
          {actions || (
            <>
              <button className="btn btn-ghost"><Icon name="file-spreadsheet" size={14} /> Excel</button>
              <button className="btn btn-ghost"><Icon name="file-text" size={14} /> PDF</button>
            </>
          )}
        </div>
      </div>

      {metrics && (
        <div className={`detail-summary-metrics metrics-${metrics.length}`}>
          {metrics.map((m, i) => (
            <div key={i}>
              <div className="summary-metric-label">{m.label}</div>
              <div className="summary-metric-value" style={m.style || {}}>
                {m.node ? m.node : (
                  <>{m.value}{m.unit && <small>{m.unit}</small>}</>
                )}
              </div>
              {m.sub && <div className="summary-metric-sub">{m.sub}</div>}
            </div>
          ))}
        </div>
      )}

      {children}
    </div>
  );
};

// ----- Detail head bar -----
const DetailHead = ({ skill, title, onBack }) => {
  const theme = SKILL_THEMES[skill] || SKILL_THEMES.quantity;
  return (
    <div className="detail-head">
      <button className="detail-back" onClick={onBack}>
        <Icon name="arrow-left" size={14} />
        返回对话
      </button>
      <div className="detail-title" style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
        <span className="detail-skill-pill" style={{ color: theme.color, background: theme.bg }}>
          <Icon name={theme.icon} size={11} />
          {skill === 'quantity' ? '算量' : skill === 'quote' ? '审核' : skill === 'combined' ? '联审' : '对比'}
        </span>
        {title}
      </div>
      <div style={{ marginLeft: 'auto', display: 'flex', gap: 4 }}>
        <button className="topbar-btn" title="分享"><Icon name="share-2" size={16} /></button>
        <button className="topbar-btn" title="下载"><Icon name="download" size={16} /></button>
        <button className="topbar-btn" title="更多"><Icon name="more-horizontal" size={16} /></button>
      </div>
    </div>
  );
};

// ----- Tab bar -----
const TabBar = ({ tabs, value, onChange }) => (
  <div className="detail-tabs">
    {tabs.map(t => (
      <div
        key={t.id}
        className={`detail-tab ${value === t.id ? 'active' : ''}`}
        onClick={() => onChange(t.id)}
      >
        {t.icon && <Icon name={t.icon} size={13} style={{ marginRight: 5, marginBottom: -2 }} />}
        {t.label}
        {t.badge !== undefined && <span className="tab-badge">{t.badge}</span>}
      </div>
    ))}
  </div>
);

// ----- Bottom sticky actions -----
const DetailActions = ({ children }) => (
  <div className="detail-actions">{children}</div>
);

// ----- File source panel — list of uploaded inputs the analysis is based on -----
const FILE_KIND_LABELS = {
  drawing:  '图纸',
  quote:    '报价单',
  contract: '合同',
  image:    '照片',
  note:     '说明',
};
const FILE_STATUS_MAP = {
  ok:      { label: '已识别', color: 'var(--risk-low)',  bg: 'var(--risk-low-bg)',  icon: 'check-circle' },
  partial: { label: '部分识别', color: 'var(--risk-mid)', bg: 'var(--risk-mid-bg)',  icon: 'triangle-alert' },
  failed:  { label: '识别失败', color: 'var(--risk-high)', bg: 'var(--risk-high-bg)', icon: 'circle-alert' },
};

const FileSourcesPanel = ({ files, skill, summary, onPreview, companies }) => {
  const theme = SKILL_THEMES[skill] || SKILL_THEMES.quantity;
  // Group by company if companies present
  const byCompany = companies && companies.length;
  const groups = byCompany
    ? [
        ...companies.map(c => ({
          key: c.id, label: `${c.name}`, color: c.color,
          files: files.filter(f => f.company === c.id),
        })),
        { key: '_other', label: '通用 / 共享', color: 'var(--text-muted)',
          files: files.filter(f => !f.company) },
      ].filter(g => g.files.length > 0)
    : null;

  const renderCard = (f) => {
    const st = FILE_STATUS_MAP[f.status] || FILE_STATUS_MAP.ok;
    return (
      <div className="file-source-card" key={f.id} onClick={() => onPreview && onPreview(f)}>
        <div className="file-source-thumb" style={{ background: theme.bg, color: theme.color }}>
          <Icon name={f.icon || 'file'} size={28} />
          <div className="file-source-kind">{FILE_KIND_LABELS[f.kind] || f.kind}</div>
        </div>
        <div className="file-source-body">
          <div className="file-source-row1">
            <span className="file-source-name">{f.label}</span>
            <span className="file-source-status" style={{ color: st.color, background: st.bg }}>
              <Icon name={st.icon} size={10} /> {st.label}
            </span>
          </div>
          <div className="file-source-meta">
            <span><Icon name="file" size={10} /> {f.pages} 页</span>
            <span>{f.size}</span>
            <span><Icon name="clock" size={10} /> {f.uploadedAt}</span>
          </div>
          <div className="file-source-usage">
            <Icon name="link" size={10} style={{ color: theme.color, flexShrink: 0, marginTop: 2 }} />
            <span>{f.usage}</span>
          </div>
        </div>
      </div>
    );
  };

  return (
    <div className="detail-panel">
      <div className="detail-panel-head">
        <div>
          <div className="detail-panel-title">分析所基于的文件</div>
          <div className="detail-panel-sub">{files.length} 份输入 · 点击查看原文件</div>
        </div>
        <button className="btn btn-ghost btn-sm">
          <Icon name="upload" size={12} /> 补充文件
        </button>
      </div>
      {summary && (
        <div className="file-source-summary" style={{ background: theme.bg, color: theme.color }}>
          <Icon name="info" size={13} />
          <span>{summary}</span>
        </div>
      )}
      {byCompany ? (
        <div className="file-source-groups">
          {groups.map(g => (
            <div key={g.key} className="file-source-group">
              <div className="file-source-group-head">
                <span className="file-source-group-dot" style={{ background: g.color }} />
                <strong>{g.label}</strong>
                <span className="file-source-group-count">{g.files.length} 份</span>
              </div>
              <div className="file-source-list">
                {g.files.map(renderCard)}
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div className="file-source-list">
          {files.map(renderCard)}
        </div>
      )}
    </div>
  );
};

Object.assign(window, {
  fmtMoney, fmtMoneySigned, fmtPct, SKILL_THEMES,
  ScoreGauge, ScoreBars, RiskCountChips, RiskItemCard,
  MarketRangeBar, DiffBar, ItemsTable, DataSourceChip,
  DetailSummary, DetailHead, TabBar, DetailActions, riskRowClass,
  FileSourcesPanel,
});
