/**
 * M8 AI 课案质量评估 - 数据访问层
 *
 * 评估 5 个维度：clarity（清晰度） alignment（课标对齐）/ engagement（参与度）
 * differentiation（差异化） assessment（评价）
 * 评估结果存入 lessonPlanAiEvaluations 表。
 */
import "server-only";
import { db } from "@/shared/db";
import { lessonPlanAiEvaluations } from "@/shared/db/schema";
import { eq, desc } from "drizzle-orm";
import type { LessonPlanDocument } from "./types";

/** 单次评估结果 */
export interface AiEvaluation {
  id: string;
  planId: string;
  versionNo: number;
  overallScore: number | null;
  dimensionScores: DimensionScores | null;
  suggestions: string | null;
  recommendedStandardIds: string[] | null;
  evaluatedBy: string;
  createdAt: Date;
}

/** 维度评分 */
export interface DimensionScores {
  clarity: number;
  alignment: number;
  engagement: number;
  differentiation: number;
  assessment: number;
}

/**
 * 查询某课案的所有 AI 评估记录
 */
export async function getEvaluationsByPlanId(
  planId: string,
): Promise<AiEvaluation[]> {
  const rows = await db
    .select()
    .from(lessonPlanAiEvaluations)
    .where(eq(lessonPlanAiEvaluations.planId, planId))
    .orderBy(desc(lessonPlanAiEvaluations.createdAt));
  return rows.map(mapRowToEvaluation);
}

/**
 * 查询最新一次评估
 */
export async function getLatestEvaluation(
  planId: string,
): Promise<AiEvaluation | null> {
  const rows = await db
    .select()
    .from(lessonPlanAiEvaluations)
    .where(eq(lessonPlanAiEvaluations.planId, planId))
    .orderBy(desc(lessonPlanAiEvaluations.createdAt))
    .limit(1);
  return rows.length === 0 ? null : mapRowToEvaluation(rows[0]!);
}

/**
 * 创建 AI 评估记录
 */
export async function createEvaluation(
  input: {
    planId: string;
    versionNo: number;
    overallScore?: number;
    dimensionScores?: DimensionScores;
    suggestions?: string;
    recommendedStandardIds?: string[];
  },
  evaluatedBy: string,
): Promise<AiEvaluation> {
  const [row] = await db.insert(lessonPlanAiEvaluations).values({
    planId: input.planId,
    versionNo: input.versionNo,
    overallScore: input.overallScore ?? null,
    dimensionScores: input.dimensionScores ?? null,
    suggestions: input.suggestions ?? null,
    recommendedStandardIds: input.recommendedStandardIds ?? null,
    evaluatedBy,
  });
  const insertedId = row.insertId;
  const all = await getEvaluationsByPlanId(input.planId);
  const created = all.find((e) => e.id === String(insertedId));
  if (!created) throw new Error("AI_EVALUATION_CREATE_FAILED");
  return created;
}

/**
 * 删除评估记录
 */
export async function deleteEvaluation(id: string): Promise<void> {
  await db
    .delete(lessonPlanAiEvaluations)
    .where(eq(lessonPlanAiEvaluations.id, id));
}

// ---- AI 评估算法（本地实现，可替换为远程 API）---

/**
 * 评估课案文档质量
 *
 * 当前为基于规则的简化评估，未来可替换为 AI 模型。
 * - clarity：基于节点数量、标题长度、文本长度
 * - alignment：基于课标关联数（如有）
 * - engagement：基于互动组件数（poll/quiz 计数，需传入 hasInteractiveItems）
 * - differentiation：基于分层练习数（exercise block 数）
 * - assessment：基于作业 block 数 + 互动组件数
 */
export function evaluateDocument(
  doc: LessonPlanDocument,
  options: { standardsLinkedCount?: number; hasInteractiveItems?: boolean } = {},
): { overallScore: number; dimensionScores: DimensionScores; suggestions: string } {
  const nodes = doc.nodes;
  const teachingNodes = nodes.filter((n) => n.type !== "textbook_content");

  // clarity: 节点数 + 标题平均长度
  const avgTitleLength =
    teachingNodes.length > 0
      ? teachingNodes.reduce((sum, n) => sum + (n.title?.length ?? 0), 0) /
        teachingNodes.length
      : 0;
  const clarity = Math.min(
    100,
    Math.round((teachingNodes.length >= 5 ? 50 : teachingNodes.length * 10) + avgTitleLength * 2),
  );

  // alignment: 课标关联数
  const alignment = Math.min(100, (options.standardsLinkedCount ?? 0) * 25);

  // engagement: 是否含互动组件
  const engagement = options.hasInteractiveItems ? 80 : 30;

  // differentiation: 练习 block 数
  const exerciseBlocks = teachingNodes.filter((n) => n.type === "exercise").length;
  const differentiation = Math.min(100, exerciseBlocks * 30);

  // assessment: 作业 block + 互动
  const homeworkBlocks = teachingNodes.filter((n) => n.type === "homework").length;
  const assessment = Math.min(
    100,
    homeworkBlocks * 40 + (options.hasInteractiveItems ? 30 : 0),
  );

  const overallScore = Math.round(
    (clarity + alignment + engagement + differentiation + assessment) / 5,
  );

  const suggestions: string[] = [];
  if (clarity < 60) suggestions.push("addMoreNodeDetails");
  if (alignment < 50) suggestions.push("linkMoreStandards");
  if (engagement < 50) suggestions.push("addInteractiveComponents");
  if (differentiation < 50) suggestions.push("addDifferentiatedExercises");
  if (assessment < 50) suggestions.push("addAssessmentBlocks");

  return {
    overallScore,
    dimensionScores: { clarity, alignment, engagement, differentiation, assessment },
    suggestions: suggestions.join(","),
  };
}

function mapRowToEvaluation(
  row: typeof lessonPlanAiEvaluations.$inferSelect,
): AiEvaluation {
  return {
    id: row.id,
    planId: row.planId,
    versionNo: row.versionNo,
    overallScore: row.overallScore,
    dimensionScores: (row.dimensionScores as DimensionScores) ?? null,
    suggestions: row.suggestions,
    recommendedStandardIds:
      (row.recommendedStandardIds as string[] | null) ?? null,
    evaluatedBy: row.evaluatedBy,
    createdAt: row.createdAt,
  };
}
