// 评级面板 v2 — 镜像回答专属
//
// 显示位置: 顶部答主行的下方, 正文之前 (用户先看评级, 再决定要不要花时间读).
// 只挂在每个问题的第一条 (镜像回答推荐的那条), 普通后续回答不显示.
//
// 默认状态:
//   ┌────────────────────────────────┬──────────┐
//   │ ⏱ 时效性  ▮▮▮▮▯                │          │
//   │ 🛡 权威性  ▮▮▮▮▮                │   ⬤ 93   │
//   │ 👤 认可度  ▮▮▮▯▯                │  贴合度  │
//   │ 🏷 关键词  [司美] [BMI] [适应症] │          │
//   └────────────────────────────────┴──────────┘
//   ▾ 为什么向你推荐这条 (默认展开, 可收起)
//
// 点击 时效/权威/认可 任一行 → 在该行下方插入一条小解释:
//   ⏱ 时效性  ▮▮▮▮▯  ▲
//   ┊  近一个月内的数据相对较新                 ┊
//
// 关键词行不收起 (本身就是内容).
// 折叠状态由独立的 useState 维护, 三个度量可以多个同时展开.

const EP_BG     = '#13161B';
const EP_BORDER = '#1F232A';
const EP_TEXT   = '#D8DCE0';
const EP_MUTED  = '#7A8089';
const EP_DIM    = '#3F454E';
const EP_FILL   = '#5BB0FF';
const EP_GREEN  = '#4ECDC4';
const EP_YELLOW = '#E8B447';
const EP_RED    = '#E55757';

function EvalPanel({ answer, persona, topicAvgVotes, sourceQuestion, onSourceTap, recommendation, defaultExpanded = false }) {
  // defaultExpanded=true → 三行 metric 全部默认展开 (page 4 数字化评估 feature 用)
  const [expandedRows, setExpandedRows] = React.useState(
    defaultExpanded ? new Set(['time', 'auth', 'recog']) : new Set()
  );
  const [bottomOpen, setBottomOpen] = React.useState(true);

  const toggle = (key) => setExpandedRows(prev => {
    const next = new Set(prev);
    if (next.has(key)) next.delete(key); else next.add(key);
    return next;
  });

  // ── Scoring ────────────────────────────────────────────
  const months = monthsSince(answer.publishDate);
  const timelinessCells =
    months < 6  ? 5 :
    months < 12 ? 4 :
    months < 18 ? 3 :
    months < 24 ? 2 : 1;

  const authorityCells =
    persona?.credential === 'verified' ? 5 :
    persona?.credential === 'kol'      ? 4 :
    persona?.badges?.length > 0        ? 4 :
    persona?.credential === 'expert'   ? 3 :
    persona?.stats?.followers > 5000   ? 3 :
    persona?.stats?.followers > 1000   ? 2 : 1;

  const ratio = topicAvgVotes > 0 ? answer.voteUp / topicAvgVotes : 1;
  const recognitionCells =
    ratio >= 2.0 ? 5 :
    ratio >= 1.0 ? 4 :
    ratio >= 0.5 ? 3 :
    ratio >= 0.2 ? 2 : 1;

  // 唯一显示指标: composite — Judge 真正用来排序的综合分 (维度匹配 50% +
  // 权威 20% + 赞数 15% + 时效 15%). 用 composite 是为了让用户看到的分
  // 跟卡片顺序对得上 — 之前显示 dimensionFit 但排序用 composite, 出现
  // "前面 80 分, 后面突然 88" 的视觉错配.
  const score = Math.max(0, Math.min(100,
    answer.composite != null ? answer.composite :
    (answer.answersQuestion != null ? answer.answersQuestion :
     (answer.relevance ?? 0))
  ));
  const isAd = (answer.composite ?? 0) < 0;
  const ringColor =
    isAd          ? EP_RED   :
    score >= 95   ? EP_GREEN :
    score >= 90   ? EP_FILL  :
                    EP_YELLOW;
  // alias 给下面 UI 用
  const relevance = score;

  // ── Per-metric explanation text ────────────────────────
  const timelinessExp = (
    months < 3  ? `${answer.publishDate} 发布, 数据非常新.` :
    months < 6  ? `${answer.publishDate} 发布, 近一个月内的数据相对较新.` :
    months < 12 ? `${answer.publishDate} 发布, 一年内有效.` :
    months < 24 ? `${answer.publishDate} 发布, 时间稍远, 部分细节可能已变化.` :
                  `${answer.publishDate} 发布, 内容已较远, 仅供参考.`
  );

  const authorityExp = (
    persona?.credential === 'verified' ? `知乎认证医师 — ${persona.credentialText.replace('知乎认证医师 · ', '')}.` :
    persona?.credential === 'kol'      ? `知乎认证 KOL — ${persona.credentialText || persona.name}.` :
    persona?.badges?.length > 0        ? `话题创作者: ${persona.badges[0]}.` :
    persona?.credential === 'expert'   ? `行业从业者 (${persona.profession}), 内容有可验证背景.` :
    persona?.stats?.followers > 5000   ? `${persona.stats.followers.toLocaleString()} 关注, 该话题下活跃用户.` :
                                          `普通用户, 内容来自亲历经验.`
  );

  const recognitionExp = (
    ratio >= 2.0 ? `${answer.voteUp.toLocaleString()} 赞同, 远高于本题平均水平.` :
    ratio >= 1.0 ? `${answer.voteUp.toLocaleString()} 赞同, 高于本题平均.` :
    ratio >= 0.5 ? `${answer.voteUp.toLocaleString()} 赞同, 接近本题平均.` :
                    `${answer.voteUp.toLocaleString()} 赞同, 低于本题平均, 内容价值由你判断.`
  );

  return (
    <div style={{
      margin: '8px 12px 0',
      background: EP_BG,
      border: `1px solid ${EP_BORDER}`,
      borderRadius: 6,
      color: EP_TEXT,
    }}>
      <div style={{ display: 'flex', padding: '8px 8px 6px' }}>
        {/* Left — 4 metric rows */}
        <div style={{ flex: 1, minWidth: 0 }}>
          <MetricRow icon="time"   label="时效性" cells={timelinessCells}
            expanded={expandedRows.has('time')} explanation={timelinessExp}
            onToggle={() => toggle('time')}/>
          <MetricRow icon="shield" label="权威性" cells={authorityCells}
            expanded={expandedRows.has('auth')} explanation={authorityExp}
            onToggle={() => toggle('auth')}/>
          <MetricRow icon="person" label="点赞" cells={recognitionCells}
            expanded={expandedRows.has('recog')} explanation={recognitionExp}
            onToggle={() => toggle('recog')}/>
          <KeywordRow keywords={answer.keywords || []}/>
        </div>
        {/* Right — relevance ring */}
        <div style={{
          flexShrink: 0, marginLeft: 8, width: 56,
          display: 'flex', flexDirection: 'column', alignItems: 'center',
          justifyContent: 'flex-start', paddingTop: 4,
        }}>
          <div style={{ fontSize: 9, color: EP_MUTED, marginBottom: 4 }}>回答匹配度</div>
          {ringColor ? (
            <>
              <RelevanceRing score={isAd ? null : relevance} color={ringColor}/>
              <div style={{ fontSize: 8.5, color: ringColor, marginTop: 3, fontWeight: 600 }}>
                {isAd ? '广告嫌疑' : score >= 95 ? '完整回答' : score >= 90 ? '回答到位' : '部分回答'}
              </div>
            </>
          ) : (
            <div style={{ fontSize: 9, color: EP_DIM, marginTop: 12 }}>—</div>
          )}
        </div>
      </div>

      {/* 原帖链接 — 放在 metric grid 和"为什么推荐"中间. 点击跳转 source question. */}
      {sourceQuestion && onSourceTap && (
        <div onClick={onSourceTap} style={{
          padding: '7px 10px',
          borderTop: `1px solid ${EP_BORDER}`,
          display: 'flex', alignItems: 'center', gap: 6,
          cursor: 'pointer', fontSize: 9.5,
        }}>
          <span style={{ color: EP_MUTED, flexShrink: 0 }}>原帖</span>
          <span style={{
            flex: 1, minWidth: 0,
            overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
            color: EP_FILL,
          }}>{sourceQuestion}</span>
          <span style={{ color: EP_FILL, flexShrink: 0, fontSize: 10 }}>›</span>
        </div>
      )}

      {/* Bottom — collapsible "why recommended".
         新 schema (Judge 输出): core_point / why_fits / caveat
         老 schema (DEMO_SCENARIOS fallback): source_intro / expertise_evidence / relevance_to_user
         caveat 段用警示色 + 左边竖线区分, 突出"不完全契合"的提醒. */}
      <div style={{ borderTop: `1px solid ${EP_BORDER}` }}>
        {bottomOpen && (
          <div style={{ padding: '7px 8px 4px', fontSize: 10, color: EP_TEXT, lineHeight: 1.6 }}>
            {recommendation && recommendation.core_point ? (
              <>
                <p style={{ margin: 0 }}>{recommendation.core_point}</p>
                {recommendation.why_fits && (
                  <p style={{ margin: '4px 0 0' }}>{recommendation.why_fits}</p>
                )}
                {recommendation.caveat && (
                  <p style={{
                    margin: '6px 0 0',
                    paddingLeft: 8,
                    borderLeft: '2px solid #D89A52',
                    color: '#C9A076',
                  }}>
                    <span style={{ fontWeight: 600, color: '#D89A52' }}>但要注意 — </span>
                    {recommendation.caveat}
                  </p>
                )}
              </>
            ) : recommendation && recommendation.source_intro ? (
              <>
                <p style={{ margin: 0 }}>{recommendation.source_intro}</p>
                <p style={{ margin: '4px 0 0' }}>{recommendation.expertise_evidence}</p>
                <p style={{ margin: '4px 0 0' }}>{recommendation.relevance_to_user}</p>
              </>
            ) : (
              explanationFor(answer, persona, { months, ratio, isAd, relevance })
            )}
          </div>
        )}
        <div onClick={() => setBottomOpen(o => !o)} style={{
          padding: '4px 8px 6px', cursor: 'pointer',
          fontSize: 9.5, color: EP_MUTED, textAlign: 'right',
        }}>
          {bottomOpen ? '收起 ▴' : '为什么向你推荐这条 ▾'}
        </div>
      </div>
    </div>
  );
}

// ─── Sub-components ────────────────────────────────────────
function MetricRow({ icon, label, cells, expanded, explanation, onToggle, numericDisplay }) {
  return (
    <div style={{ marginBottom: 5 }}>
      <div onClick={onToggle} style={{
        display: 'flex', alignItems: 'center', gap: 6,
        cursor: 'pointer', padding: '1px 0',
      }}>
        <MetricIcon kind={icon} color={EP_MUTED}/>
        <span style={{ width: 36, color: EP_MUTED, fontSize: 9, flexShrink: 0 }}>{label}</span>
        <BatteryCells lit={cells} total={5}/>
        {numericDisplay != null && (
          <span style={{ color: EP_TEXT, fontSize: 9, marginLeft: 6, fontFamily: '"DIN Alternate", monospace' }}>
            {numericDisplay}
          </span>
        )}
        <div style={{ flex: 1 }}/>
        <span style={{ color: EP_DIM, fontSize: 9, marginLeft: 4 }}>
          {expanded ? '▴' : '▾'}
        </span>
      </div>
      {expanded && (
        <div style={{
          margin: '3px 0 0 22px',
          padding: '4px 8px',
          background: '#0E1116',
          border: `1px solid ${EP_BORDER}`,
          borderRadius: 4,
          fontSize: 9.5, color: '#9BC3E8',
          lineHeight: 1.4,
        }}>{explanation}</div>
      )}
    </div>
  );
}

function KeywordRow({ keywords }) {
  return (
    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 6, padding: '2px 0' }}>
      <MetricIcon kind="tag" color={EP_MUTED}/>
      <span style={{ width: 36, color: EP_MUTED, fontSize: 9, flexShrink: 0, marginTop: 1 }}>关键词</span>
      <div style={{ display: 'flex', gap: 3, flexWrap: 'wrap', flex: 1, minWidth: 0 }}>
        {keywords.length === 0
          ? <span style={{ color: EP_DIM, fontSize: 8.5 }}>—</span>
          : keywords.slice(0, 5).map((k, i) => (
              <span key={i} style={{
                padding: '1px 5px', borderRadius: 6,
                background: '#1F2A3A', color: '#9BC3E8',
                fontSize: 8.5, lineHeight: 1.5,
                whiteSpace: 'nowrap',
              }}>{k}</span>
            ))
        }
      </div>
    </div>
  );
}

function BatteryCells({ lit, total = 5 }) {
  return (
    <div style={{ display: 'flex', gap: 2 }}>
      {Array.from({ length: total }).map((_, i) => (
        <div key={i} style={{
          width: 9, height: 6, borderRadius: 1,
          background: i < lit ? EP_FILL : EP_DIM,
          transition: 'background 0.2s',
        }}/>
      ))}
    </div>
  );
}

function MetricIcon({ kind, color = '#7A8089' }) {
  const size = 12;
  const stroke = color;
  const sw = 1.2;
  if (kind === 'time') return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" style={{ flexShrink: 0 }}>
      <circle cx="6" cy="6" r="4.6" stroke={stroke} strokeWidth={sw}/>
      <path d="M6 6 L6 3.5 M6 6 L8 6" stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
    </svg>
  );
  if (kind === 'shield') return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" style={{ flexShrink: 0 }}>
      <path d="M6 1.2 L10 3 L10 6.5 C10 9 8 10.5 6 11 C4 10.5 2 9 2 6.5 L2 3 Z"
        stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
    </svg>
  );
  if (kind === 'person') return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" style={{ flexShrink: 0 }}>
      <circle cx="6" cy="4" r="1.9" stroke={stroke} strokeWidth={sw}/>
      <path d="M2 11 C2 8.5 4 7.3 6 7.3 C8 7.3 10 8.5 10 11"
        stroke={stroke} strokeWidth={sw} strokeLinecap="round"/>
    </svg>
  );
  if (kind === 'tag') return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" style={{ flexShrink: 0 }}>
      <path d="M1.5 5.5 L5.5 1.5 L10.5 1.5 L10.5 6.5 L6.5 10.5 Z"
        stroke={stroke} strokeWidth={sw} strokeLinejoin="round"/>
      <circle cx="8.2" cy="3.8" r="0.6" fill={stroke}/>
    </svg>
  );
  return null;
}

function RelevanceRing({ score, color }) {
  const size = 42;
  const stroke = 4;
  const r = (size - stroke) / 2;
  const circ = 2 * Math.PI * r;
  const offset = score == null ? circ : circ * (1 - score / 100);
  return (
    <div style={{ position: 'relative', width: size, height: size }}>
      <svg width={size} height={size}>
        <circle cx={size/2} cy={size/2} r={r}
          stroke={EP_DIM} strokeWidth={stroke} fill="none"/>
        {score != null && (
          <circle cx={size/2} cy={size/2} r={r}
            stroke={color} strokeWidth={stroke} fill="none"
            strokeDasharray={circ}
            strokeDashoffset={offset}
            strokeLinecap="round"
            transform={`rotate(-90 ${size/2} ${size/2})`}/>
        )}
      </svg>
      <div style={{
        position: 'absolute', inset: 0,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 14, fontWeight: 700, color,
      }}>{score == null ? '—' : Math.round(score)}</div>
    </div>
  );
}

// ─── Heuristics ────────────────────────────────────────────
function fmtVotes(n) {
  if (n == null) return '0';
  if (n >= 10000) return (n / 10000).toFixed(n >= 100000 ? 0 : 1) + '万';
  if (n >= 1000)  return (n / 1000).toFixed(1) + 'k';
  return n.toString();
}

function monthsSince(dateStr) {
  if (!dateStr) return 99;
  const NOW_Y = 2026, NOW_M = 5;
  const [y, m] = dateStr.split('-').map(Number);
  if (!y || !m) return 99;
  return (NOW_Y - y) * 12 + (NOW_M - m);
}

function explanationFor(answer, persona, sig) {
  const parts = [];
  if (sig.isAd) {
    parts.push('AI 在文本中检测到品牌引导 / 私信钩子, 标记为广告嫌疑.');
    parts.push('如果你只想看真实经验, 可以跳过.');
    return parts.join(' ');
  }
  if (persona?.credential === 'verified') {
    parts.push(`这条回答较好覆盖了用户的核心问题. 作者${persona.name}是${persona.credentialText.replace('知乎认证医师 · ', '')}的执业医师, 该话题下有稳定输出.`);
  } else if (persona?.badges?.length > 0) {
    parts.push(`这条回答较好覆盖了用户的核心问题. 作者${persona.name}是${persona.badges[0]}, 内容有可验证从业背景.`);
  } else if (persona?.stats?.followers > 1000) {
    parts.push(`这条回答从亲历者角度回应了用户的核心问题. 作者${persona.name}在该话题下有持续输出.`);
  } else {
    parts.push(`这条回答从亲历者角度回应了用户的核心问题, 内容来自个人经验.`);
  }
  if (sig.months > 18) {
    parts.push(`注意: 内容发布于 ${answer.publishDate}, 时间较远, 涉及最新方案 (如药物/工具) 需另行核实.`);
  } else if (sig.months >= 12) {
    parts.push(`参考价值较高, 部分细节可能随时间变化, 请结合最新信息判断.`);
  }
  return parts.join(' ');
}

Object.assign(window, { EvalPanel });
