'use client';

import * as React from 'react';
import { HoverCard, HoverCardTrigger, HoverCardContent } from '@/components/ui/hover-card';
// PriorityBreakdown 定义在 priority-explain.ts(纯模块,不带 JSX)—— 这里再导出,
// 老调用方 `import { PriorityBreakdown } from './priority-hover'` 不受影响。
export type { PriorityBreakdown } from './priority-explain';
import type { PriorityBreakdown } from './priority-explain';
import {
  explainConfidence,
  explainFreshness,
  explainPercentile,
  explainUrgency,
  explainValue,
  explainWillingness,
  type PriorityExplainSignals,
} from './priority-explain';

/**
 * PriorityHover — 优先级数字旁悬停展示 v3.0 三维拆解。
 *
 * 数据来源:plan.reasons[0].breakdown.priority(后端 priority-scorer v3 输出)
 *   综合 = 急迫性×0.4 + 价值性×0.3 + 意愿度×0.3
 *   总分 = 综合 × 新鲜度 × 置信度 × 10
 *   意愿度 = RFM依从×0.375 + 主诉行为×0.375 + 信任基础×0.25
 *
 * 列表 + 详情页共用。breakdown 缺失时回退最简文案。
 */

export function PriorityHover({
  score,
  breakdown,
  percentile,
  signals,
  children,
}: {
  score: number;
  breakdown?: PriorityBreakdown | null;
  /// 池内百分位(后端 PriorityDistributionService);缺失 → 不渲染位置行
  percentile?: number | null;
  /// primary reason 的 signals —— 用来把价值性讲成「种植 · 缺 3 颗」而不是「预估收入档 9/10」
  signals?: PriorityExplainSignals | null;
  children: React.ReactNode;
}) {
  return (
    <HoverCard openDelay={150} closeDelay={80}>
      {/* 直接把 children 作为 trigger,radix 锚定 children 本身(避免多包一层 span 错位)*/}
      <HoverCardTrigger asChild>{children}</HoverCardTrigger>
      <HoverCardContent align="end" sideOffset={6} className="w-80 p-3 text-[11.5px]">
        <PriorityBreakdownTable
          score={score}
          breakdown={breakdown}
          percentile={percentile}
          signals={signals}
        />
      </HoverCardContent>
    </HoverCard>
  );
}

function PriorityBreakdownTable({
  score,
  breakdown,
  percentile,
  signals,
}: {
  score: number;
  breakdown?: PriorityBreakdown | null;
  percentile?: number | null;
  signals?: PriorityExplainSignals | null;
}) {
  // 10 分制(保留两位小数):优先用 breakdown.raw(真 2 位精度),无则 score/10
  const disp = (breakdown?.raw ?? score / 10).toFixed(2);
  if (!breakdown || breakdown.urgency === undefined) {
    // 老数据 / 异常兜底(旧 6 因子 breakdown 也走这里)
    return (
      <div className="space-y-1.5">
        <Header disp={disp} percentile={percentile} />
        <p className="text-slate-500 leading-relaxed">
          三维加权:急迫性 ×0.4 + 价值性 ×0.3 + 意愿度 ×0.3,再 × 新鲜度 × 置信度。
          <br />
          (此条召回缺明细 — 重新计算后可恢复)
        </p>
      </div>
    );
  }
  const urgency = breakdown.urgency ?? 0;
  const value = breakdown.value ?? 0;
  const willing = breakdown.willingness ?? 0;
  const rfm = breakdown.rfmAdherence ?? 0;
  const intent = breakdown.intentBehavior ?? 0;
  const trust = breakdown.trustBase ?? 0;
  const fresh = breakdown.freshness ?? 1;
  const conf = breakdown.confidenceFactor ?? 1;
  const base = breakdown.base ?? urgency * 0.4 + value * 0.3 + willing * 0.3;
  return (
    <div className="space-y-1.5">
      <Header disp={disp} percentile={percentile} />
      <table className="w-full tabular-nums">
        <tbody>
          {/* hint 一律讲**这个患者**的情况,不讲口径定义 —— 定义换谁看都一样,看完还是不知道
              他为什么是 10 分。翻译逻辑在 priority-explain.ts。 */}
          <Row label="急迫性" value={`${urgency.toFixed(0)} × 0.4`} hint={explainUrgency(breakdown)} />
          <Row label="价值性" value={`${value.toFixed(0)} × 0.3`} hint={explainValue(breakdown, signals)} />
          <Row
            label="意愿度"
            value={`${willing.toFixed(1)} × 0.3`}
            hint={explainWillingness(breakdown)}
          />
          <Subtotal label="三维小计" value={base.toFixed(1)} />
          <Row
            label="× 新鲜度"
            value={fresh.toFixed(2)}
            hint={explainFreshness(breakdown)}
            tone={fresh < 1 ? 'amber' : undefined}
          />
          <Row
            label="× 置信度"
            value={conf.toFixed(2)}
            hint={explainConfidence(breakdown)}
            tone={conf < 1 ? 'amber' : undefined}
          />
          <Subtotal label="= 总分" value={disp} bold />
        </tbody>
      </table>
    </div>
  );
}

function Header({ disp, percentile }: { disp: string; percentile?: number | null }) {
  const pos = explainPercentile(percentile);
  return (
    <div className="border-b border-slate-100 pb-1.5">
      <div className="flex items-baseline justify-between">
        <span className="text-[13px] font-semibold text-slate-900">优先级 {disp} / 10</span>
        <span className="text-[10.5px] text-slate-500">急迫 × 价值 × 意愿</span>
      </div>
      {/* 池内位置 —— 没有这行,「9.78 / 10」会被当成"还行"(实际生产池中位数只有 3.1) */}
      {pos && (
        <div className="mt-1 flex items-center gap-1.5">
          <span className="h-1 flex-1 overflow-hidden rounded-full bg-slate-100">
            <span
              className="block h-full rounded-full bg-teal-500"
              style={{ width: `${Math.max(2, percentile ?? 0)}%` }}
            />
          </span>
          <span className="flex-none text-[10.5px] font-medium text-teal-700">{pos}</span>
        </div>
      )}
    </div>
  );
}

function Row({
  label,
  value,
  hint,
  tone,
}: {
  label: string;
  value: string;
  hint?: string;
  tone?: 'emerald' | 'amber';
}) {
  const valueClass =
    tone === 'emerald'
      ? 'text-emerald-700 font-medium'
      : tone === 'amber'
        ? 'text-amber-700 font-medium'
        : 'text-slate-700';
  return (
    <tr>
      <td className="py-0.5 text-slate-600 whitespace-nowrap">{label}</td>
      <td className={`py-0.5 text-right ${valueClass} whitespace-nowrap`}>{value}</td>
      <td className="py-0.5 pl-2 text-[10.5px] text-slate-400">{hint ?? ''}</td>
    </tr>
  );
}

function Subtotal({ label, value, bold }: { label: string; value: string; bold?: boolean }) {
  return (
    <tr>
      <td colSpan={3} className="border-t border-slate-100 pt-1 pb-0.5">
        <span className="flex justify-between">
          <span className={`text-slate-700 ${bold ? 'font-semibold' : ''}`}>{label}</span>
          <span
            className={`tabular-nums ${bold ? 'text-rose-700 font-bold' : 'text-slate-800 font-medium'}`}
          >
            {value}
          </span>
        </span>
      </td>
    </tr>
  );
}
