import { FastifyInstance } from "fastify";
import { ZodTypeProvider } from "fastify-type-provider-zod";
import { z } from "zod";
import { prisma } from "../../lib/prisma";
import { auth } from "../../middlewares/auth";
import { UnauthorizedError } from "../_errors/unauthorized-error";

export async function getUserCourses(app: FastifyInstance) {
  app
    .withTypeProvider<ZodTypeProvider>()
    .register(auth)
    .get('/user-courses', {
      schema: {
        summary: 'Get user courses',
        security: [{ bearerAuth: [] }],
        tags: ['courses'],
        response: {
          200: z.object({
            courses: z.array(
              z.object({
                id: z.string(),
                title: z.string(),
                slug: z.string(),
                totalDuration: z.number(),
                progress: z.number(),
              })
            ),
          }),
        },
      },
    }, async (request, reply) => {
      const userId = await request.getCurrentUserId();

      if (!userId) {
        throw new UnauthorizedError('You do not have permission to access this route');
      }

      const userCourses = await prisma.userCourse.findMany({
        where: {
          userId: userId,
        },
        select: {
          course: {
            select: {
              id: true,
              title: true,
              slug: true,
              Module: {
                select: {
                  Class: {
                    select: {
                      id: true,
                      duration: true,
                    }
                  }
                }
              }
            }
          }
        }
      });

      const formattedCourses = await Promise.all(userCourses.map(async userCourse => {
        const course = userCourse.course;
        const totalClasses = course.Module.reduce((count, module) => count + module.Class.length, 0);

        const attendedClassesCount = await prisma.classAttended.count({
          where: {
            userId: userId,
            classId: {
              in: course.Module.flatMap(module => module.Class.map(cls => cls.id))
            }
          }
        });

        const totalDuration = course.Module.reduce((courseDuration, module) => {
          return courseDuration + module.Class.reduce((moduleDuration, cls) => {
            return moduleDuration + cls.duration;
          }, 0);
        }, 0);

        const progress = totalClasses > 0 ? (attendedClassesCount / totalClasses) * 100 : 0;

        return {
          id: course.id,
          title: course.title,
          slug: course.slug,
          totalDuration,
          progress,
        };
      }));

      return reply.send({
        courses: formattedCourses,
      });
    });
}
