// app/api/playlists/route.ts
import { NextResponse } from "next/server";
import { getServerSession } from "next-auth";
import { authOptions } from "@/lib/auth-options";
import { prisma } from "@/lib/prisma";

type VideoWithCourses = {
  videoCourses?: Array<{ courseId: string; exclusive: boolean }>
};

function mapRestrictedCourseIds(video: VideoWithCourses) {
  if (!video?.videoCourses?.length) return [];
  return video.videoCourses
    .filter((assignment) => assignment.exclusive)
    .map((assignment) => assignment.courseId);
}

function filterRestrictedVideos(videos: any[], userCourseIds: string[]) {
  return videos
    .filter((video) => {
      const restrictedCourseIds = mapRestrictedCourseIds(video);
      if (restrictedCourseIds.length === 0) return true;
      return restrictedCourseIds.some((courseId: string) =>
        userCourseIds.includes(courseId)
      );
    })
    .map((video) => ({
      ...video,
      restrictedCourseIds: mapRestrictedCourseIds(video),
    }));
}

export async function GET(req: Request) {
  const session = await getServerSession(authOptions);
  if (!session?.user?.email) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const user = await prisma.user.findUnique({
    where: { email: session.user.email },
    include: {
      enrollments: {
        include: { course: true },
      },
    },
  });

  const courseIds = user?.enrollments.map((e) => e.courseId) ?? [];

  // Get playlists directly assigned to enrolled courses
  const coursesWithPlaylists = await prisma.course.findMany({
    where: { id: { in: courseIds } },
    include: {
      playlists: {
        include: {
          videos: {
            include: {
              uploader: {
                select: {
                  id: true,
                  name: true,
                  image: true,
                },
              },
              videoCourses: true,
            },
            orderBy: { index: "asc" },
          },
          courses: {
            include: { course: true },
          },
        },
        orderBy: { sortOrder: "asc" },
      },
    },
    orderBy: { title: "asc" },
  });

  // Also get playlists assigned to courses via CoursePlaylist mapping
  const additionalPlaylists = await prisma.coursePlaylist.findMany({
    where: { courseId: { in: courseIds } },
      include: {
        playlist: {
          include: {
            videos: {
              include: {
                uploader: {
                  select: {
                    id: true,
                    name: true,
                    image: true,
                  },
                },
                videoCourses: true,
              },
              orderBy: { index: "asc" },
            },
            courses: {
              include: { course: true },
            },
          },
        },
        course: true,
      },
  });

  // Merge results: add additional playlists to their respective courses
  const playlistMap = new Map();
  additionalPlaylists.forEach(({ course, playlist }) => {
    if (!playlistMap.has(course.id)) {
      playlistMap.set(course.id, []);
    }
    playlist.videos = filterRestrictedVideos(playlist.videos, courseIds);
    playlistMap.get(course.id).push(playlist);
  });

  coursesWithPlaylists.forEach((course) => {
    course.playlists.forEach((playlist) => {
      playlist.videos = filterRestrictedVideos(playlist.videos, courseIds);
    });

    const additional = playlistMap.get(course.id) || [];
    const existingIds = new Set(course.playlists.map((p) => p.id));
    const newPlaylists = additional.filter((p: any) => !existingIds.has(p.id));
    newPlaylists.forEach((playlist: any) => {
      playlist.videos = filterRestrictedVideos(playlist.videos, courseIds);
    });
    course.playlists.push(...newPlaylists);
    course.playlists.sort((a, b) => a.sortOrder - b.sortOrder);
  });

  return NextResponse.json({ subjects: coursesWithPlaylists });
}
