import Link from "next/link";
import FormContainer from "@/components/FormContainer";
import ListFilterSort from "@/components/ListFilterSort";
import Pagination from "@/components/Pagination";
import Table from "@/components/Table";
import { getSupabaseClient } from "@/lib/supabase";
import { ITEM_PER_PAGE } from "@/lib/settings";
import { Tables } from "@/types/supabase";
import Image from "next/image";
import { auth } from "@clerk/nextjs/server";
import { Suspense } from "react";

export const dynamic = "force-dynamic";

type LessonList = Tables<"Lesson"> & {
  subject: Tables<"Subject"> | null;
  class: Tables<"Class"> | null;
  teacher: Tables<"Teacher"> | null;
};

const LessonListPage = async ({
  searchParams,
}: {
  searchParams: { [key: string]: string | undefined };
}) => {

  const { sessionClaims } = auth();
  const role = (sessionClaims?.metadata as { role?: string })?.role;


  const columns = [
    {
      header: "Lesson",
      accessor: "lessonName",
    },
    {
      header: "Subject",
      accessor: "name",
    },
    {
      header: "Date",
      accessor: "date",
      className: "hidden sm:table-cell",
    },
    {
      header: "Time",
      accessor: "time",
      className: "hidden sm:table-cell",
    },
    {
      header: "Class",
      accessor: "class",
    },
    {
      header: "Teacher",
      accessor: "teacher",
      className: "hidden md:table-cell",
    },
    ...(role === "admin" || role === "teacher" || role === "student"
      ? [
        {
          header: "Actions",
          accessor: "action",
        },
      ]
      : []),
  ];

  const formatTime = (iso: string | undefined) =>
    iso ? new Date(iso).toLocaleTimeString("en-GB", { hour: "2-digit", minute: "2-digit" }) : null;
  const formatDate = (iso: string | undefined) =>
    iso ? new Date(iso).toLocaleDateString("en-GB", { day: "numeric", month: "short", year: "numeric" }) : "-";

  const renderRow = (item: LessonList) => {
    const start = formatTime(item.startTime);
    const end = formatTime(item.endTime);
    const timeStr = start && end ? `${start} – ${end}` : "-";
    const dateStr = formatDate(item.startTime);
    return (
    <tr
      key={item.id}
      className="border-b border-gray-200 even:bg-slate-50 text-sm hover:bg-lamaPurpleLight"
    >
      <td className="flex items-center gap-4 p-4">{item.name || "-"}</td>
      <td>{item.subject?.name || "-"}</td>
      <td className="hidden sm:table-cell">{dateStr}</td>
      <td className="hidden sm:table-cell">{timeStr}</td>
      <td>{item.class?.name || "-"}</td>
      <td className="hidden md:table-cell">
        {item.teacher ? item.teacher.name + " " + item.teacher.surname : "-"}
      </td>
      <td>
        <div className="flex items-center gap-2">
          {(role === "admin" || role === "teacher" || role === "student") && (
            <Link href={`/whiteboard?lessonId=${item.id}`}>
              <button
                className="w-7 h-7 flex items-center justify-center rounded-full bg-lamaSky"
                title="View Whiteboard"
              >
                <Image src="/student.png" alt="Board" width={14} height={14} />
              </button>
            </Link>
          )}
          {role === "admin" && (
            <>
              <FormContainer table="lesson" type="update" data={item} />
              <FormContainer table="lesson" type="delete" id={item.id} />
            </>
          )}
        </div>
      </td>
    </tr>
  );
  };

  const { page, ...queryParams } = searchParams;

  const p = page ? parseInt(page) : 1;
  const supabase = await getSupabaseClient();

  // Filter options for ListFilterSort
  const [teachersRes, classesRes] = await Promise.all([
    supabase.from("Teacher").select("id, name, surname").order("name"),
    supabase.from("Class").select("id, name").order("name"),
  ]);
  const teacherOptions = (teachersRes.data ?? []).map((t) => ({
    value: t.id,
    label: `${t.name} ${t.surname}`.trim(),
  }));
  const classOptions = (classesRes.data ?? []).map((c) => ({
    value: String(c.id),
    label: c.name,
  }));

  const sortOptions = [
    { value: "startTime", label: "Date" },
    { value: "name", label: "Lesson name" },
  ];
  const filters = [
    { key: "teacherId", label: "Teacher", options: teacherOptions },
    { key: "classId", label: "Class", options: classOptions },
  ];

  // Fetch lessons only (no embeds) so RLS on Subject/Class/Teacher cannot drop rows
  let query = supabase.from("Lesson").select("*", { count: "exact" });

  if (queryParams) {
    for (const [key, value] of Object.entries(queryParams)) {
      if (value === undefined) continue;
      switch (key) {
        case "classId":
          query = query.eq("classId", parseInt(value));
          break;
        case "teacherId":
          query = query.eq("teacherId", value);
          break;
        case "search":
          query = query.ilike("name", `%${value}%`);
          break;
        case "sortBy": {
          const col = value === "name" || value === "startTime" ? value : "startTime";
          const asc = queryParams.sortOrder !== "desc";
          query = query.order(col, { ascending: asc });
          break;
        }
        default:
          break;
      }
    }
  }
  if (!queryParams.sortBy) {
    query = query.order("startTime", { ascending: true });
  }

  query = query.range(ITEM_PER_PAGE * (p - 1), ITEM_PER_PAGE * p - 1);

  const { data: lessons, count, error } = await query;

  if (error) {
    console.error("Error fetching lessons from Supabase:", error);
  }

  const lessonRows = lessons ?? [];

  // Load subject, class, teacher in separate queries (avoids embed RLS dropping lesson rows)
  const subjectIds = Array.from(new Set(lessonRows.map((l) => l.subjectId).filter((id) => id != null)));
  const classIds = Array.from(new Set(lessonRows.map((l) => l.classId).filter((id) => id != null)));
  const teacherIds = Array.from(new Set(lessonRows.map((l) => l.teacherId).filter((id) => id != null)));

  const [subjectsRes, classesRes2, teachersRes2] = await Promise.all([
    subjectIds.length ? supabase.from("Subject").select("id, name").in("id", subjectIds) : { data: [] },
    classIds.length ? supabase.from("Class").select("id, name").in("id", classIds) : { data: [] },
    teacherIds.length ? supabase.from("Teacher").select("id, name, surname").in("id", teacherIds) : { data: [] },
  ]);

  // Use Number() for map keys so string vs number from API doesn't break lookup
  const subjectMap = new Map((subjectsRes.data ?? []).map((s) => [Number(s.id), s]));
  const classMap = new Map((classesRes2.data ?? []).map((c) => [Number(c.id), c]));
  const teacherMap = new Map((teachersRes2.data ?? []).map((t) => [t.id, t]));

  const data = lessonRows.map((lesson) => ({
    ...lesson,
    subject: subjectMap.get(Number(lesson.subjectId)) ?? null,
    class: classMap.get(Number(lesson.classId)) ?? null,
    teacher: teacherMap.get(lesson.teacherId) ?? null,
  })) as LessonList[];

  return (
    <div className="bg-white p-4 rounded-md flex-1 m-4 mt-0">
      <div className="flex items-center justify-between">
        <h1 className="hidden md:block text-lg font-semibold">All Lessons</h1>
      </div>
      <Suspense fallback={<div className="py-3 border-b border-gray-200 animate-pulse" />}>
        <ListFilterSort sortOptions={sortOptions} filters={filters} showSearch>
          {role === "admin" && <FormContainer table="lesson" type="create" />}
        </ListFilterSort>
      </Suspense>
      <Table columns={columns} renderRow={renderRow} data={data} />
      {/* PAGINATION */}
      <Pagination page={p} count={count || 0} />
    </div>
  );
};

export default LessonListPage;
