"use server"

import { requirePermission, PermissionDeniedError } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import type { ActionState } from "@/shared/types/action-state"

import {
  getClassComparison,
  getGradeDistribution,
  getGradeTrend,
  getSubjectComparison,
  type ClassComparisonParams,
  type GradeDistributionParams,
  type GradeTrendParams,
  type SubjectComparisonParams,
} from "./data-access-analytics"
import { getRankingTrend } from "./data-access-ranking"
import {
  ClassComparisonQuerySchema,
  GradeDistributionQuerySchema,
  GradeTrendQuerySchema,
  RankingTrendQuerySchema,
  SubjectComparisonQuerySchema,
} from "./schema"
import type {
  ClassComparisonItem,
  GradeDistributionResult,
  GradeTrendResult,
  RankingTrendResult,
  SubjectComparisonItem,
} from "./types"

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

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

    const result = await getGradeTrend({
      ...parsed.data,
      scope: ctx.dataScope,
      currentUserId: ctx.userId,
    })
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

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

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

    const result = await getClassComparison({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

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

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

    const result = await getSubjectComparison({
      ...parsed.data,
      scope: ctx.dataScope,
    })
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

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

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

    const result = await getGradeDistribution({
      ...parsed.data,
      scope: ctx.dataScope,
      currentUserId: ctx.userId,
    })
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}

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 parsed = RankingTrendQuerySchema.safeParse({ studentId, subjectId, semester })
    if (!parsed.success) {
      return {
        success: false,
        message: "Invalid query parameters",
        errors: parsed.error.flatten().fieldErrors,
      }
    }

    // Students can only view their own ranking trend
    if (ctx.dataScope.type === "class_members" && ctx.userId !== parsed.data.studentId) {
      return { success: false, message: "Can only view your own ranking trend" }
    }
    // Parents can only view their children's ranking trend
    if (
      ctx.dataScope.type === "children" &&
      !ctx.dataScope.childrenIds.includes(parsed.data.studentId)
    ) {
      return { success: false, message: "Can only view your children's ranking trend" }
    }

    const result = await getRankingTrend(
      parsed.data.studentId,
      parsed.data.subjectId,
      parsed.data.semester
    )
    return { success: true, data: result }
  } catch (e) {
    if (e instanceof PermissionDeniedError) {
      return { success: false, message: e.message }
    }
    if (e instanceof Error) return { success: false, message: e.message }
    return { success: false, message: "Unexpected error" }
  }
}
