import { useEffect, useState } from "react";
import { ModelManager } from "../components/ModelManager";
import { adminDatasources, type DatasourceKB } from "../api";

// 数据源 & RAG：真数据(全平台知识库清单，来自 sundynix_kb/sundynix_doc)。
// 此前该页 GraphRAG 拓扑图与「向量/全文/图谱权重滑块」全 mock——而且权重概念本身是虚构的：
// mcp-go 的 RRF 融合是各路等权的倒排互惠融合(rrfK=60 平滑常数)，没有"每路占几成"的权重。
// 故删假滑块+假拓扑，换成真数据源清单 + 诚实的检索管线说明。

const KIND_LABEL: Record<string, string> = { general: "通用", folder: "文件夹", project: "项目", case: "案例" };
const fmtWords = (n: number) => (n >= 1e4 ? `${(n / 1e4).toFixed(1)}万` : `${n}`);

export function DatasourcesPage() {
  const [counts, setCounts] = useState({ users: 0, kbs: 0, docs: 0 });
  const [rows, setRows] = useState<DatasourceKB[]>([]);
  const [loading, setLoading] = useState(true);
  const [err, setErr] = useState("");

  useEffect(() => {
    adminDatasources()
      .then((r) => {
        setCounts(r.counts);
        setRows(r.datasources);
        setErr("");
      })
      .catch((e) => setErr((e as Error).message))
      .finally(() => setLoading(false));
  }, []);

  const totalWords = rows.reduce((a, r) => a + r.total_words, 0);

  return (
    <div className="flex flex-col gap-6">
      {/* Embedding 模型配置（真实组件） */}
      <ModelManager
        kind="embedding"
        title="Embedding 模型（embedding → mcp-go RAG）"
        baseUrlHint="https://dashscope.aliyuncs.com/compatible-mode/v1"
        modelHint="text-embedding-v3"
      />

      {/* 检索管线说明（诚实：三路 + RRF 等权融合，非可调权重） */}
      <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
        <h3 className="mb-3 text-sm font-semibold text-gray-700">混合检索管线</h3>
        <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
          <Route color="violet" name="向量检索" impl="Milvus" desc="Embedding 相似度召回语义相关块" />
          <Route color="cyan" name="全文检索" impl="Bleve" desc="倒排索引召回关键词精确命中" />
          <Route color="emerald" name="图谱检索" impl="Neo4j" desc="实体三元组召回结构化关联" />
        </div>
        <p className="mt-3 text-[11px] leading-relaxed text-gray-400">
          三路并行召回 → <span className="font-medium text-gray-600">RRF 倒排互惠融合</span>（Reciprocal Rank Fusion，平滑常数 k=60）→ rerank 重排。
          融合按各路排名等权，无「每路占几成」的可调权重；单路可经 <code className="rounded bg-gray-100 px-1">SearchByMode</code> 指定。检索参数定义在 mcp-go 代码中。
        </p>
      </div>

      {/* 平台数据源计数 */}
      <div className="grid grid-cols-3 gap-4">
        <Stat label="知识库" value={String(counts.kbs)} tone="violet" />
        <Stat label="文档总数" value={String(counts.docs)} tone="cyan" sub={`约 ${fmtWords(totalWords)} 字`} />
        <Stat label="平台用户" value={String(counts.users)} tone="emerald" />
      </div>

      {/* 知识库清单（真数据） */}
      <div className="rounded-xl border border-gray-100 bg-white p-5 shadow-sm">
        <h3 className="mb-3 text-sm font-semibold text-gray-700">知识库清单（全平台）</h3>
        {loading ? (
          <div className="py-8 text-center text-xs text-gray-400">加载中…</div>
        ) : err ? (
          <div className="py-8 text-center text-xs text-rose-500">加载失败：{err}</div>
        ) : rows.length === 0 ? (
          <div className="py-8 text-center text-xs text-gray-400">还没有知识库</div>
        ) : (
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-gray-100 text-left text-[11px] uppercase tracking-wide text-gray-400">
                  <th className="py-2 pr-3 font-medium">知识库</th>
                  <th className="py-2 pr-3 font-medium">类型</th>
                  <th className="py-2 pr-3 font-medium">租户</th>
                  <th className="py-2 pr-3 text-right font-medium">文档数</th>
                  <th className="py-2 text-right font-medium">总字数</th>
                </tr>
              </thead>
              <tbody>
                {rows.map((r) => (
                  <tr key={r.id} className="border-b border-gray-50 last:border-0">
                    <td className="py-2 pr-3 font-medium text-gray-800">{r.name}</td>
                    <td className="py-2 pr-3"><span className="rounded bg-gray-100 px-1.5 py-0.5 text-[10px] text-gray-600">{KIND_LABEL[r.kind] ?? r.kind}</span></td>
                    <td className="py-2 pr-3 text-xs text-gray-500">{r.tenant_name || r.tenant_id || "—"}</td>
                    <td className="py-2 pr-3 text-right tabular-nums text-gray-700">{r.doc_count}</td>
                    <td className="py-2 text-right tabular-nums text-gray-500">{fmtWords(r.total_words)}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        )}
      </div>
    </div>
  );
}

const ROUTE_TONE: Record<string, { dot: string; text: string }> = {
  violet: { dot: "bg-violet-500", text: "text-violet-600" },
  cyan: { dot: "bg-cyan-500", text: "text-cyan-600" },
  emerald: { dot: "bg-emerald-500", text: "text-emerald-600" },
};
function Route({ color, name, impl, desc }: { color: string; name: string; impl: string; desc: string }) {
  const t = ROUTE_TONE[color];
  return (
    <div className="rounded-lg border border-gray-100 bg-gray-50/50 p-3">
      <div className="flex items-center gap-2">
        <span className={`h-2 w-2 rounded-full ${t.dot}`} />
        <span className="text-sm font-medium text-gray-700">{name}</span>
        <span className={`text-[10px] ${t.text}`}>{impl}</span>
      </div>
      <p className="mt-1 text-[11px] leading-relaxed text-gray-500">{desc}</p>
    </div>
  );
}

const STAT_TONE: Record<string, string> = { violet: "text-violet-600", cyan: "text-cyan-600", emerald: "text-emerald-600" };
function Stat({ label, value, sub, tone }: { label: string; value: string; sub?: string; tone: string }) {
  return (
    <div className="rounded-xl border border-gray-100 bg-white p-4 shadow-sm">
      <div className="text-xs text-gray-400">{label}</div>
      <div className={`mt-1 text-2xl font-semibold tabular-nums ${STAT_TONE[tone] ?? "text-gray-800"}`}>{value}</div>
      {sub && <div className="mt-1 text-[11px] text-gray-400">{sub}</div>}
    </div>
  );
}
