import type { Metadata } from "next"
import type { JSX } from "react"
import { Suspense } from "react"
import { BarChart3 } from "lucide-react"
import { getTranslations } from "next-intl/server"

import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { Skeleton } from "@/shared/components/ui/skeleton"
import { getParam, type SearchParams } from "@/shared/lib/search-params"
import {
  getClassIdsByGradeIds,
  getStudentIdsByClassIds,
} from "@/modules/classes/data-access"

import {
  getTeacherClassPracticeOverviews,
  getClassStudentPracticeSummaries,
  getPracticeTypeBreakdown,
  getClassKnowledgePointWeakness,
  getStudentsWithoutPractice,
  getStudentNameMap,
} from "@/modules/adaptive-practice/data-access-analytics"
import { PracticeOverviewStatsCards } from "@/modules/adaptive-practice/components/practice-overview-stats-cards"
import { ClassPracticeComparisonTable } from "@/modules/adaptive-practice/components/class-practice-comparison-table"
import { PracticeTypeBreakdownChart } from "@/modules/adaptive-practice/components/practice-type-breakdown-chart"
import { ClassKnowledgePointWeaknessChart } from "@/modules/adaptive-practice/components/class-knowledge-point-weakness-chart"
import { StudentPracticeRankingTable } from "@/modules/adaptive-practice/components/student-practice-ranking-table"
import { InactiveStudentsAlert } from "@/modules/adaptive-practice/components/inactive-students-alert"
import { ClassFilter } from "@/modules/error-book/components/class-filter"
import type { ClassErrorOverview } from "@/modules/error-book/types"

export const dynamic = "force-dynamic"

export async function generateMetadata(): Promise<Metadata> {
  const t = await getTranslations("practice")
  return {
    title: `${t("teacher.title")} - Next_Edu`,
    description: t("teacher.description"),
  }
}

async function TeacherPracticeContent({
  searchParams,
}: {
  searchParams: Promise<SearchParams>
}): Promise<JSX.Element> {
  const ctx = await requirePermission(Permissions.ADAPTIVE_PRACTICE_READ)
  const t = await getTranslations("practice")

  const params = await searchParams
  const classIds = ctx.dataScope.type === "class_taught" ? ctx.dataScope.classIds : []
  const gradeIds = ctx.dataScope.type === "grade_managed" ? ctx.dataScope.gradeIds : []

  if (classIds.length === 0 && gradeIds.length === 0 && ctx.dataScope.type !== "all") {
    return (
      <div className="flex h-full flex-col space-y-8 p-8">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">{t("teacher.title")}</h1>
          <p className="text-muted-foreground">{t("teacher.description")}</p>
        </div>
        <EmptyState
          icon={BarChart3}
          title={t("teacher.noClass")}
          description={t("teacher.noClassDescription")}
          className="h-[360px] bg-card"
        />
      </div>
    )
  }

  // 年级主任/教研组长：展开年级为班级
  let targetClassIds = classIds
  if (gradeIds.length > 0) {
    const gradeClassIds = await getClassIdsByGradeIds(gradeIds)
    targetClassIds = [...new Set([...classIds, ...gradeClassIds])]
  }

  // 获取所有学生 ID
  const allStudentIds = await getStudentIdsByClassIds(targetClassIds)

  if (allStudentIds.length === 0) {
    return (
      <div className="flex h-full flex-col space-y-8 p-8">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">{t("teacher.title")}</h1>
          <p className="text-muted-foreground">{t("teacher.description")}</p>
        </div>
        <EmptyState
          icon={BarChart3}
          title={t("teacher.noStudent")}
          description={t("teacher.noStudentDescription")}
          className="h-[360px] bg-card"
        />
      </div>
    )
  }

  // 解析 URL 参数：班级筛选
  const classParam = getParam(params, "classId")
  const effectiveClassId = classParam ?? "all"

  // 班级概览（用于班级筛选器显示）
  const classOverviews = await getTeacherClassPracticeOverviews(targetClassIds)

  // 构造 ClassFilter 所需的数据格式
  const classFilterData: ClassErrorOverview[] = classOverviews.map((c) => ({
    classId: c.classId,
    className: c.className,
    studentCount: c.totalStudents,
    totalErrorItems: c.totalSessions,
    dueReviewCount: 0,
    averageErrorPerStudent: c.totalStudents > 0 ? c.totalSessions / c.totalStudents : 0,
    averageMasteryRate: c.averageAccuracy,
  }))

  // 确定查询的班级范围
  const queryClassIds = effectiveClassId === "all" ? targetClassIds : [effectiveClassId]
  const queryStudentIds = await getStudentIdsByClassIds(queryClassIds)

  // 并行查询所有统计数据
  const [typeBreakdown, studentSummaries, nameMap, inactiveIds] = await Promise.all([
    getPracticeTypeBreakdown(queryStudentIds),
    // 按班级查询学生摘要（如果是单班级视图，直接查询；如果是全部视图，按班级逐个查询后合并）
    effectiveClassId === "all"
      ? getClassStudentPracticeSummariesForClasses(queryClassIds)
      : getClassStudentPracticeSummaries(effectiveClassId),
    getStudentNameMap(queryStudentIds),
    effectiveClassId === "all"
      ? getInactiveStudentsForClasses(queryClassIds)
      : getStudentsWithoutPractice(effectiveClassId),
  ])

  // 聚合统计
  const totalSessions = classOverviews.reduce((sum, c) => sum + c.totalSessions, 0)
  const totalAnswered = classOverviews.reduce((sum, c) => sum + c.totalQuestionsAnswered, 0)
  const totalCorrect = classOverviews.reduce((sum, c) => sum + c.totalCorrect, 0)
  const totalActiveStudents = classOverviews.reduce((sum, c) => sum + c.activeStudents, 0)
  const totalStudents = classOverviews.reduce((sum, c) => sum + c.totalStudents, 0)
  const averageAccuracy = totalAnswered > 0 ? totalCorrect / totalAnswered : 0
  const participationRate = totalStudents > 0 ? totalActiveStudents / totalStudents : 0

  // 单班级视图：查询知识点薄弱度
  const weakKps = effectiveClassId !== "all"
    ? await getClassKnowledgePointWeakness(effectiveClassId, 10)
    : []

  const hasData = totalSessions > 0

  if (!hasData) {
    return (
      <div className="flex h-full flex-col space-y-8 p-8">
        <div>
          <h1 className="text-2xl font-bold tracking-tight">{t("teacher.title")}</h1>
          <p className="text-muted-foreground">{t("teacher.description")}</p>
        </div>
        <EmptyState
          icon={BarChart3}
          title={t("teacher.noData")}
          description={t("teacher.noDataDescription")}
          className="h-[360px] bg-card"
        />
      </div>
    )
  }

  return (
    <div className="flex h-full flex-col space-y-6 p-8">
      <div>
        <h1 className="text-2xl font-bold tracking-tight">{t("teacher.title")}</h1>
        <p className="text-muted-foreground">{t("teacher.description")}</p>
      </div>

      {/* 班级筛选器 */}
      {classFilterData.length > 0 ? (
        <Suspense fallback={<Skeleton className="h-10 w-full" />}>
          <ClassFilter
            classes={classFilterData}
            currentClassId={effectiveClassId}
          />
        </Suspense>
      ) : null}

      {/* 统计卡片 */}
      <PracticeOverviewStatsCards
        totalClasses={classOverviews.length}
        totalSessions={totalSessions}
        totalAnswered={totalAnswered}
        averageAccuracy={averageAccuracy}
        participationRate={participationRate}
      />

      {/* 班级对比表（仅在"全部班级"视图下显示） */}
      {effectiveClassId === "all" && classOverviews.length > 1 ? (
        <ClassPracticeComparisonTable data={classOverviews} />
      ) : null}

      {/* 练习类型分布图 */}
      {typeBreakdown.length > 0 ? (
        <PracticeTypeBreakdownChart data={typeBreakdown} />
      ) : null}

      {/* 知识点薄弱度（仅在单班级视图下显示） */}
      {effectiveClassId !== "all" ? (
        <ClassKnowledgePointWeaknessChart data={weakKps} />
      ) : null}

      {/* 学生练习排名 */}
      {studentSummaries.length > 0 ? (
        <StudentPracticeRankingTable data={studentSummaries} studentNames={nameMap} />
      ) : null}

      {/* 未参与练习学生提醒 */}
      <InactiveStudentsAlert
        inactiveStudentIds={inactiveIds}
        studentNames={nameMap}
      />
    </div>
  )
}

/**
 * 获取多个班级的学生练习摘要（合并结果）。
 *
 * 用于"全部班级"视图，按班级逐个查询后合并。
 */
async function getClassStudentPracticeSummariesForClasses(
  classIds: string[],
) {
  const results = await Promise.all(
    classIds.map((classId) => getClassStudentPracticeSummaries(classId)),
  )
  // 合并并按练习数降序排列
  return results.flat().sort((a, b) => b.totalSessions - a.totalSessions)
}

/**
 * 获取多个班级中未参与练习的学生 ID 列表（合并结果）。
 */
async function getInactiveStudentsForClasses(
  classIds: string[],
): Promise<string[]> {
  const results = await Promise.all(
    classIds.map((classId) => getStudentsWithoutPractice(classId)),
  )
  return results.flat()
}

export default async function TeacherPracticePage({
  searchParams,
}: {
  searchParams: Promise<SearchParams>
}): Promise<JSX.Element> {
  return (
    <Suspense
      fallback={
        <div className="flex h-full flex-col space-y-8 p-8">
          <Skeleton className="h-10 w-48" />
          <Skeleton className="h-10 w-full" />
          <div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-5">
            {Array.from({ length: 5 }).map((_, i) => (
              <Skeleton key={i} className="h-[100px]" />
            ))}
          </div>
          <Skeleton className="h-[300px] w-full" />
        </div>
      }
    >
      <TeacherPracticeContent searchParams={searchParams} />
    </Suspense>
  )
}
