"use server"

import { getTranslations } from "next-intl/server"
import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"
import { handleActionError } from "@/shared/lib/action-utils"

import {
  getClassComparison,
  getClassComparisonWithSignificance,
  getGradeDistribution,
  getGradeDistributionByGradeId,
  getGradeTrend,
  getStudentGrowthArchive,
  getStudentPositionInClassDistribution,
  getSubjectComparison,
  type ClassComparisonParams,
  type GradeDistributionByGradeParams,
  type GradeDistributionParams,
  type GradeTrendParams,
  type SubjectComparisonParams,
} from "./data-access-analytics"
import { getRankingTrend } from "./data-access-ranking"
import {
  ClassComparisonQuerySchema,
  GradeDistributionByGradeQuerySchema,
  GradeDistributionQuerySchema,
  GradeTrendQuerySchema,
  RankingTrendQuerySchema,
  StudentGrowthArchiveQuerySchema,
  SubjectComparisonQuerySchema,
} from "./schema"
import { assertClassInScope } from "./lib/scope-check"
import type {
  ClassComparisonItem,
  ClassComparisonResult,
  GradeDistributionByGradeResult,
  GradeDistributionResult,
  GradeDistributionWithPosition,
  GradeTrendResult,
  RankingTrendResult,
  StudentGrowthArchiveResult,
  SubjectComparisonItem,
} from "./types"

/**
 * grades 模块分析类 Server Actions。
 *
 * P1-5 重构：所有错误消息已接入 i18n（next-intl）。
 * - 校验失败使用 `t("action.invalidQuery")`
 * - scope 校验失败使用 `t(\`action.scopeError.${code}\`)`
 * - 学生/家长越权访问排名趋势使用专用翻译键
 */

export async function getGradeTrendAction(
  params: Omit<GradeTrendParams, "scope" | "currentUserId">
): Promise<ActionState<GradeTrendResult | null>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = GradeTrendQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const scopeError = assertClassInScope(ctx.dataScope, parsed.data.classId)
    if (scopeError) {
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const result = await getGradeTrend({
      ...parsed.data,
      scope: ctx.dataScope,
      currentUserId: ctx.userId,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getClassComparisonAction(
  params: Omit<ClassComparisonParams, "scope">
): Promise<ActionState<ClassComparisonItem[]>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = ClassComparisonQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    // 对 class_taught scope 校验（gradeId 维度无法直接校验，依赖 data-access 层过滤）
    // data-access 层的 getClassComparison 已通过 buildScopeClassFilter 应用 scope 过滤。
    const result = await getClassComparison({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * P3-5: 获取班级对比数据 + 统计显著性分析结果。
 * 在 getClassComparisonAction 基础上额外返回 Cohen's d 与 p 值。
 */
export async function getClassComparisonWithSignificanceAction(
  params: Omit<ClassComparisonParams, "scope">
): Promise<ActionState<ClassComparisonResult>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = ClassComparisonQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const result = await getClassComparisonWithSignificance({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getSubjectComparisonAction(
  params: Omit<SubjectComparisonParams, "scope">
): Promise<ActionState<SubjectComparisonItem[]>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = SubjectComparisonQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const scopeError = assertClassInScope(ctx.dataScope, parsed.data.classId)
    if (scopeError) {
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const result = await getSubjectComparison({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getGradeDistributionAction(
  params: Omit<GradeDistributionParams, "scope" | "currentUserId">
): Promise<ActionState<GradeDistributionResult>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = GradeDistributionQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const scopeError = assertClassInScope(ctx.dataScope, parsed.data.classId)
    if (scopeError) {
      return { success: false, message: t(`action.scopeError.${scopeError}`) }
    }

    const result = await getGradeDistribution({
      ...parsed.data,
      scope: ctx.dataScope,
      currentUserId: ctx.userId,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

export async function getRankingTrendAction(
  studentId: string,
  subjectId?: string,
  semester?: "1" | "2"
): Promise<ActionState<RankingTrendResult | null>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = RankingTrendQuerySchema.safeParse({ studentId, subjectId, semester })
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    // P1-5 修复：硬编码英文消息改为 i18n
    // 学生只能查看自己的排名趋势
    if (ctx.dataScope.type === "class_members" && ctx.userId !== parsed.data.studentId) {
      return { success: false, message: t("action.ownRankingTrendOnly") }
    }
    // 家长只能查看子女的排名趋势
    if (
      ctx.dataScope.type === "children" &&
      !ctx.dataScope.childrenIds.includes(parsed.data.studentId)
    ) {
      return { success: false, message: t("action.childrenRankingTrendOnly") }
    }

    // 传递 scope 到 data-access 层，对 class_taught scope 在数据层校验学生归属
    const result = await getRankingTrend(
      parsed.data.studentId,
      parsed.data.subjectId,
      parsed.data.semester,
      ctx.dataScope
    )
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * 年级仪表盘 - 维度1：获取年级整体 + 按班级拆分的成绩分布。
 * grade_managed / all / class_taught scope 均可调用，data-access 层已应用行级过滤。
 */
export async function getGradeDistributionByGradeIdAction(
  params: Omit<GradeDistributionByGradeParams, "scope">
): Promise<ActionState<GradeDistributionByGradeResult>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = GradeDistributionByGradeQuerySchema.safeParse(params)
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    const result = await getGradeDistributionByGradeId({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * P3-9: 获取学生所在班级的成绩分布 + 学生本人位置标注（隐私保护视图）。
 * 仅学生本人（class_members scope）可调用，查询所在班级的分布 + 自己的归一化分数。
 */
export async function getStudentPositionInClassDistributionAction(
  studentId: string
): Promise<ActionState<GradeDistributionWithPosition | null>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    if (ctx.dataScope.type !== "class_members") {
      return { success: false, message: t("action.studentOnly") }
    }

    // 学生只能查看自己的分布位置
    if (ctx.userId !== studentId) {
      return { success: false, message: t("action.ownGradesOnly") }
    }

    const result = await getStudentPositionInClassDistribution(studentId, ctx.dataScope)
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}

/**
 * P3-4: 获取学生纵向成长档案（跨学年/学期聚合）。
 *
 * 权限规则：
 * - class_members（学生）：仅能查看自己的成长档案
 * - children（家长）：仅能查看子女的成长档案
 * - class_taught（教师）：仅能查看所教班级学生的成长档案（data-access 层校验）
 * - grade_managed / all：可查看任意学生的成长档案
 */
export async function getStudentGrowthArchiveAction(
  studentId: string
): Promise<ActionState<StudentGrowthArchiveResult | null>> {
  try {
    const ctx = await requirePermission(Permissions.GRADE_RECORD_READ)
    const t = await getTranslations("grades")

    const parsed = StudentGrowthArchiveQuerySchema.safeParse({ studentId })
    if (!parsed.success) {
      return {
        success: false,
        message: t("action.invalidQuery"),
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    // 学生只能查看自己的成长档案
    if (ctx.dataScope.type === "class_members" && ctx.userId !== parsed.data.studentId) {
      return { success: false, message: t("action.ownGradesOnly") }
    }
    // 家长只能查看子女的成长档案
    if (
      ctx.dataScope.type === "children" &&
      !ctx.dataScope.childrenIds.includes(parsed.data.studentId)
    ) {
      return { success: false, message: t("action.childrenGradesOnly") }
    }

    const result = await getStudentGrowthArchive(parsed.data.studentId, ctx.dataScope)
    return { success: true, data: result }
  } catch (e) {
    return handleActionError(e)
  }
}
