import "server-only";
import { z } from "zod";
import { env } from "@/env.mjs";
import { createAiChatCompletion } from "@/shared/lib/ai";
import { isRecord } from "@/shared/lib/type-guards";
import {
  getKnowledgePointsByTextbookId,
  getKnowledgePointsByChapterId,
} from "@/modules/textbooks/data-access";

const SuggestedKpSchema = z.object({
  id: z.string().min(1),
  name: z.string().min(1),
  reason: z.string(),
});

const SuggestedKpListSchema = z.array(SuggestedKpSchema);

/** 从 unknown 节点安全提取文本（类型守卫从 unknown 收窄） */
const extractNodeText = (node: unknown): string => {
  if (!isRecord(node)) return ""
  const data = node.data
  if (!isRecord(data)) return ""
  const html = typeof data.html === "string" ? data.html : ""
  const sourceText = typeof data.sourceText === "string" ? data.sourceText : ""
  return html || sourceText || ""
}

// P2 修复：AI prompt 提取为模块常量，便于维护和未来国际化
// 注：AI prompt 属于系统级提示词，非用户可见文本，暂不纳入 next-intl i18n 体系
const AI_SUGGEST_PROMPT_TEMPLATE = `你是教学设计助手。以下是教师备课内容：
---
{text}
---
请从下列知识点中推荐最相关的 3-8 个，并说明理由。返回 JSON 数组，每项含 id/name/reason。
候选知识点：{kpList}`;

export async function suggestKnowledgePoints(
  doc: { nodes: unknown[] },
  textbookId?: string,
  chapterId?: string,
): Promise<{ id: string; name: string; reason: string }[]> {
  // 1. 提取课案纯文本
  const text = doc.nodes
    .map((b) => extractNodeText(b))
    .join("\n")
    .slice(0, 3000);

  if (!text.trim()) return [];

  // 2. 获取候选知识点池
  if (!textbookId) return [];
  const allKps = chapterId
    ? await getKnowledgePointsByChapterId(chapterId)
    : await getKnowledgePointsByTextbookId(textbookId);
  if (allKps.length === 0) return [];

  const kpList = allKps.map((kp) => ({ id: kp.id, name: kp.name })).slice(0, 100);

  // 3. 调用 AI（使用模板构建 prompt）
  const prompt = AI_SUGGEST_PROMPT_TEMPLATE
    .replace("{text}", text)
    .replace("{kpList}", JSON.stringify(kpList));

  const { content } = await createAiChatCompletion({
    messages: [{ role: "user", content: prompt }],
    model: env.AI_MODEL ?? "gpt-4o-mini",
    temperature: 0.3,
  });

  try {
    // 尝试从返回内容中提取 JSON 数组
    const jsonMatch = content.match(/\[[\s\S]*\]/);
    if (!jsonMatch) return [];
    const parsed: unknown = JSON.parse(jsonMatch[0]);
    const validated = SuggestedKpListSchema.safeParse(parsed);
    if (!validated.success) return [];
    // 过滤掉不在候选池中的 id
    const validIds = new Set(kpList.map((k) => k.id));
    return validated.data.filter((p) => validIds.has(p.id));
  } catch {
    return [];
  }
}
