import Link from "next/link"
import { PlusCircle, ClipboardList } from "lucide-react"
import type { Metadata } from "next"
import type { JSX } from "react"
import { getTranslations } from "next-intl/server"

import { requirePermission } from "@/shared/lib/auth-guard"
import { Permissions } from "@/shared/types/permissions"
import { Button } from "@/shared/components/ui/button"
import { EmptyState } from "@/shared/components/ui/empty-state"
import { getSearchParam, type SearchParams } from "@/shared/lib/utils"
import {
  getAdminClassesForScheduling,
  getScheduleChanges,
  getScheduleEntriesForAdmin,
} from "@/modules/scheduling/data-access"
import { ScheduleChangeList } from "@/modules/scheduling/components/schedule-change-list"
import { ScheduleConflictsView } from "@/modules/scheduling/components/schedule-conflicts-view"
import { ScheduleGridView } from "@/modules/scheduling/components/schedule-grid-view"
import type { ScheduleChangeStatus } from "@/modules/scheduling/types"

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

export const dynamic = "force-dynamic"

const isValidStatus = (v?: string): v is ScheduleChangeStatus =>
  v === "pending" || v === "approved" || v === "rejected" || v === "completed"

export default async function AdminSchedulingChangesPage({
  searchParams,
}: {
  searchParams: Promise<SearchParams>
}): Promise<JSX.Element> {
  const t = await getTranslations("scheduling")
  await requirePermission(Permissions.SCHEDULE_ADJUST)
  const sp = await searchParams
  const statusParam = getSearchParam(sp, "status")
  const status = isValidStatus(statusParam) ? statusParam : undefined
  const classIdParam = getSearchParam(sp, "classId")
  const classId = classIdParam && classIdParam !== "all" ? classIdParam : undefined

  const [classes, items, scheduleEntries] = await Promise.all([
    getAdminClassesForScheduling(),
    getScheduleChanges({ status, classId }),
    getScheduleEntriesForAdmin(),
  ])
  const classOptions = classes.map((c) => ({ id: c.id, name: c.name, grade: c.grade }))

  return (
    <div className="flex h-full flex-col space-y-8 p-8">
      <div className="flex items-center justify-between space-y-2">
        <div className="space-y-1">
          <h2 className="text-2xl font-bold tracking-tight">{t("changes.title")}</h2>
          <p className="text-muted-foreground">
            {t("changes.description")}
          </p>
        </div>
        <Button asChild>
          <Link href="/teacher/schedule-changes">
            <PlusCircle className="mr-2 h-4 w-4" />
            {t("changes.newRequest")}
          </Link>
        </Button>
      </div>

      {items.length === 0 && !status && !classId ? (
        <EmptyState
          icon={ClipboardList}
          title={t("changes.noChangesTitle")}
          description={t("changes.noChangesDescription")}
          action={{
            label: t("changes.newRequest"),
            href: "/teacher/schedule-changes",
          }}
        />
      ) : (
        <ScheduleChangeList items={items} canApprove />
      )}

      <div className="space-y-2">
        <h3 className="text-lg font-semibold">{t("changes.conflictDetection")}</h3>
        <p className="text-sm text-muted-foreground">
          {t("changes.conflictDetectionDescription")}
        </p>
        {classOptions.length === 0 ? (
          <EmptyState
            icon={ClipboardList}
            title={t("changes.noClassesTitle")}
            description={t("changes.noClassesDescription")}
          />
        ) : (
          <ScheduleConflictsView classes={classOptions} />
        )}
      </div>

      <div className="space-y-2">
        <h3 className="text-lg font-semibold">{t("changes.scheduleGrid")}</h3>
        <p className="text-sm text-muted-foreground">
          {t("changes.scheduleGridDescription")}
        </p>
        <ScheduleGridView entries={scheduleEntries} classes={classOptions} />
      </div>
    </div>
  )
}
