import Link from "next/link"
import { getTranslations } from "next-intl/server"

import { EmptyState } from "@/shared/components/ui/empty-state"
import { Button } from "@/shared/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/shared/components/ui/card"
import { StatusBadge } from "@/shared/components/ui/status-badge"
import { formatDate, cn } from "@/shared/lib/utils"
import { getParam, type SearchParams } from "@/shared/lib/search-params"
import { getStudentHomeworkAssignments } from "@/modules/homework/data-access-student"
import { getCurrentStudentUser } from "@/modules/users/data-access"
import { AssignmentFilters } from "@/modules/homework/components/assignment-filters"
import { Inbox, UserX, TriangleAlert } from "lucide-react"
import type {
  StudentHomeworkAssignmentListItem,
  StudentHomeworkProgressStatus,
} from "@/modules/homework/types"
import {
  STUDENT_HOMEWORK_PROGRESS_VARIANT,
} from "@/modules/homework/types"

export const dynamic = "force-dynamic"

const getActionLabel = (status: StudentHomeworkProgressStatus, t: (key: string) => string): string => {
  switch (status) {
    case "graded":
      return t("homework.review.title")
    case "submitted":
      return t("common.view")
    case "in_progress":
      return t("common.continue")
    default:
      return t("homework.take.startAssignment")
  }
}

const getActionVariant = (
  status: StudentHomeworkProgressStatus
): "default" | "secondary" | "outline" => {
  return status === "graded" || status === "submitted" ? "outline" : "default"
}

const isAnswered = (status: StudentHomeworkProgressStatus): boolean =>
  status === "submitted" || status === "graded"

const matchesStatusFilter = (
  status: StudentHomeworkProgressStatus,
  filter: string
): boolean => {
  if (filter === "all") return true
  if (filter === "pending") return status === "not_started" || status === "in_progress"
  if (filter === "submitted") return status === "submitted"
  if (filter === "graded") return status === "graded"
  return true
}

// Stable color mapping for subjects (hash-based, deterministic)
const SUBJECT_DOT_COLORS = [
  "bg-blue-500",
  "bg-emerald-500",
  "bg-amber-500",
  "bg-violet-500",
  "bg-rose-500",
  "bg-cyan-500",
  "bg-orange-500",
  "bg-pink-500",
  "bg-indigo-500",
  "bg-teal-500",
]

const getSubjectColor = (subject: string): string => {
  let hash = 0
  for (let i = 0; i < subject.length; i++) {
    hash = (hash * 31 + subject.charCodeAt(i)) | 0
  }
  const idx = Math.abs(hash) % SUBJECT_DOT_COLORS.length
  return SUBJECT_DOT_COLORS[idx]
}

type TranslationFn = (key: string) => string

function AssignmentCard({
  assignment: a,
  t,
  statusLabelMap,
}: {
  assignment: StudentHomeworkAssignmentListItem
  t: TranslationFn
  statusLabelMap: Record<StudentHomeworkProgressStatus, string>
}) {
  const now = new Date()
  const isOverdue = a.dueAt ? new Date(a.dueAt) < now : false
  const showOverdueBadge = isOverdue && !isAnswered(a.progressStatus)

  return (
    <Card className="flex h-full flex-col overflow-hidden transition-all hover:shadow-md">
      <CardHeader className="gap-2 pb-3">
        <div className="flex items-start justify-between gap-3">
          <CardTitle className="text-base">
            <Link href={`/student/learning/assignments/${a.id}`} className="hover:underline">
              {a.title}
            </Link>
          </CardTitle>
          <StatusBadge
            status={a.progressStatus}
            variantMap={STUDENT_HOMEWORK_PROGRESS_VARIANT}
            labelMap={statusLabelMap}
          />
        </div>
        <div className={cn(
          "text-xs",
          showOverdueBadge ? "text-destructive font-medium" : "text-muted-foreground"
        )}>
          <span>{t("homework.list.columns.dueAt")} {a.dueAt ? formatDate(a.dueAt) : "-"}</span>
          <span className="px-2" aria-hidden="true">•</span>
          <span>{t("homework.take.attempts")} {a.attemptsUsed}/{a.maxAttempts}</span>
          {showOverdueBadge && (
            <>
              <span className="px-2" aria-hidden="true">•</span>
              <span className="inline-flex items-center gap-1">
                <TriangleAlert className="h-3 w-3" />
                {t("homework.take.overdue")}
              </span>
            </>
          )}
        </div>
      </CardHeader>
      <CardContent className="mt-auto flex items-center justify-between">
        <div className="text-sm">
          <div className="text-muted-foreground">{t("homework.grade.score")}</div>
          <div className="font-medium tabular-nums">{a.latestScore ?? "-"}</div>
        </div>
        <Button asChild size="sm" variant={getActionVariant(a.progressStatus)}>
          <Link href={`/student/learning/assignments/${a.id}`}>
            {getActionLabel(a.progressStatus, t)}
          </Link>
        </Button>
      </CardContent>
    </Card>
  )
}

export default async function StudentAssignmentsPage({
  searchParams,
}: {
  searchParams: Promise<SearchParams>
}) {
  const t = await getTranslations("examHomework")
  const student = await getCurrentStudentUser()

  const statusLabelMap: Record<StudentHomeworkProgressStatus, string> = {
    not_started: t("homework.status.not_started"),
    in_progress: t("homework.status.in_progress"),
    submitted: t("homework.status.submitted"),
    graded: t("homework.status.graded"),
  }

  if (!student) {
    return (
      <div className="space-y-8">
        <div>
          <h2 className="text-2xl font-bold tracking-tight">{t("homework.list.title")}</h2>
          <p className="text-muted-foreground">{t("homework.list.description")}</p>
        </div>
        <EmptyState title={t("homework.error.notFound")} description={t("homework.error.assignmentNotFound")} icon={UserX} />
      </div>
    )
  }

  const [sp, assignments] = await Promise.all([
    searchParams,
    getStudentHomeworkAssignments(student.id),
  ])

  const q = (getParam(sp, "q") || "").toLowerCase().trim()
  const statusFilter = getParam(sp, "status") || "all"

  // 应用筛选
  const filtered = assignments.filter((a) => {
    if (q && !a.title.toLowerCase().includes(q)) return false
    if (!matchesStatusFilter(a.progressStatus, statusFilter)) return false
    return true
  })

  const hasAssignments = assignments.length > 0
  const hasFiltered = filtered.length > 0

  const assignmentsBySubject = filtered.reduce((acc, assignment) => {
    const subject = assignment.subjectName?.trim() || t("common.other")
    const existing = acc.get(subject)
    if (existing) {
      existing.push(assignment)
    } else {
      acc.set(subject, [assignment])
    }
    return acc
  }, new Map<string, StudentHomeworkAssignmentListItem[]>())
  const subjectEntries = Array.from(assignmentsBySubject.entries()).sort((a, b) =>
    a[0].localeCompare(b[0])
  )

  return (
    <div className="space-y-8">
      <div>
        <h2 className="text-2xl font-bold tracking-tight">{t("homework.list.title")}</h2>
        <p className="text-muted-foreground">{t("homework.list.description")}</p>
      </div>

      {hasAssignments && <AssignmentFilters />}

      {!hasAssignments ? (
        <EmptyState title={t("homework.list.empty")} description={t("homework.list.emptyDescription")} icon={Inbox} />
      ) : !hasFiltered ? (
        <EmptyState
          title={t("homework.list.emptyFiltered")}
          description={t("homework.list.emptyFilteredDescription")}
          icon={Inbox}
        />
      ) : (
        <div className="space-y-6">
          {subjectEntries.map(([subject, items]) => {
            // 单次遍历分桶，避免重复 filter（PERF-05）
            const answered: StudentHomeworkAssignmentListItem[] = []
            const unanswered: StudentHomeworkAssignmentListItem[] = []
            for (const a of items) {
              if (isAnswered(a.progressStatus)) {
                answered.push(a)
              } else {
                unanswered.push(a)
              }
            }

            return (
              <div key={subject} className="space-y-3">
                <div className="flex items-center gap-2 text-sm font-semibold">
                  <span
                    className={cn("h-2.5 w-2.5 rounded-full", getSubjectColor(subject))}
                    aria-hidden="true"
                  />
                  <span className="text-muted-foreground">{subject}</span>
                  <span className="text-xs font-normal text-muted-foreground/70">
                    ({items.length})
                  </span>
                </div>
                {unanswered.length > 0 && (
                  <div className="space-y-3">
                    <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      {t("homework.status.not_started")}
                    </div>
                    <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
                      {unanswered.map((a) => (
                        <AssignmentCard key={a.id} assignment={a} t={t} statusLabelMap={statusLabelMap} />
                      ))}
                    </div>
                  </div>
                )}
                {answered.length > 0 && (
                  <div className="space-y-3">
                    <div className="text-xs font-semibold uppercase tracking-wide text-muted-foreground">
                      {t("common.completed")}
                    </div>
                    <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-3">
                      {answered.map((a) => (
                        <AssignmentCard key={a.id} assignment={a} t={t} statusLabelMap={statusLabelMap} />
                      ))}
                    </div>
                  </div>
                )}
              </div>
            )
          })}
        </div>
      )}
    </div>
  )
}
