/**
 * V5-17 A1/A2：AI 反馈闭环 + 解释性展示。
 *
 * 调用 AI 对课案文档进行教学评一致性反馈，返回结构化建议。
 * 反馈包含：
 * - strengths：课案优点
 * - improvements：改进建议
 * - alignment：教学评一致性评估
 * - differentiation：差异化教学建议
 *
 * 每条建议附带 reason（解释性展示），帮助教师理解 AI 判断依据。
 */
import "server-only";
import { env } from "@/env.mjs";
import { createAiChatCompletion } from "@/shared/lib/ai";
import { isRecord } from "@/shared/lib/type-guards";
import { z } from "zod";
import type { LessonPlanDocument, LessonPlanNode } from "../types";

/** AI 反馈单条建议 */
export interface AiFeedbackItem {
  /** i18n 键后缀（feedback.* 命名空间下） */
  category: "strengths" | "improvements" | "alignment" | "differentiation";
  /** 建议标题 */
  title: string;
  /** 解释性理由（A2：解释性展示） */
  reason: string;
  /** 关联节点 ID（如适用） */
  nodeId?: string;
}

/** AI 反馈结果 */
export interface AiFeedbackResult {
  items: AiFeedbackItem[];
  /** 整体评分（0-100） */
  overallScore: number;
  /** 摘要 */
  summary: string;
}

const FeedbackItemSchema = z.object({
  category: z.enum(["strengths", "improvements", "alignment", "differentiation"]),
  title: z.string().min(1),
  reason: z.string(),
  nodeId: z.string().optional(),
});

const FeedbackResultSchema = z.object({
  items: z.array(FeedbackItemSchema),
  overallScore: z.number().min(0).max(100),
  summary: z.string(),
});

const AI_FEEDBACK_PROMPT_TEMPLATE = `你是资深教学设计专家。请对以下课案文档进行教学评一致性评估，给出结构化反馈。

课案文档（JSON）：
---
{doc}
---

请从四个维度评估：
1. strengths：课案优点
2. improvements：改进建议
3. alignment：教学评一致性（目标-教学-评价是否对齐）
4. differentiation：差异化教学建议

返回 JSON 对象，含：
- items：数组，每项含 category（维度）/title（建议标题）/reason（解释性理由，说明为何给出此建议）/nodeId（关联节点 ID，可选）
- overallScore：整体评分 0-100
- summary：一句话摘要

注意：reason 字段必须解释判断依据，帮助教师理解。`;

/** 安全提取节点文本用于 AI prompt */
function extractNodeText(node: LessonPlanNode): string {
  const data = node.data as unknown;
  if (!isRecord(data)) return "";
  const html = typeof data.html === "string" ? data.html : "";
  const sourceText = typeof data.sourceText === "string" ? data.sourceText : "";
  return html || sourceText || "";
}

/**
 * 调用 AI 对课案文档生成结构化反馈。
 *
 * @param doc 课案文档
 * @returns AI 反馈结果；AI 不可用时返回空结果
 */
export async function generateLessonPlanFeedback(
  doc: LessonPlanDocument,
): Promise<AiFeedbackResult> {
  // 提取教学节点摘要（排除正文节点，控制 token 用量）
  const teachingNodes = doc.nodes.filter(
    (n): n is LessonPlanNode => n.type !== "textbook_content",
  );
  if (teachingNodes.length === 0) {
    return { items: [], overallScore: 0, summary: "" };
  }

  const docSummary = teachingNodes.slice(0, 20).map((n) => ({
    id: n.id,
    type: n.type,
    title: n.title,
    stage: n.stage,
    differentiation: n.differentiation,
    text: extractNodeText(n).slice(0, 200),
  }));

  const prompt = AI_FEEDBACK_PROMPT_TEMPLATE.replace(
    "{doc}",
    JSON.stringify(docSummary),
  );

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

    // 从返回内容中提取 JSON 对象
    const jsonMatch = content.match(/\{[\s\S]*\}/);
    if (!jsonMatch) return { items: [], overallScore: 0, summary: "" };

    const parsed: unknown = JSON.parse(jsonMatch[0]);
    const validated = FeedbackResultSchema.safeParse(parsed);
    if (!validated.success) {
      return { items: [], overallScore: 0, summary: "" };
    }

    return validated.data;
  } catch {
    return { items: [], overallScore: 0, summary: "" };
  }
}
