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 getClassBySlug(app: FastifyInstance) {
  app
    .withTypeProvider<ZodTypeProvider>()
    .register(auth)
    .get('/get-class/:slug?', {
      schema: {
        summary: 'Get class by slug or first class if slug is not provided',
        security: [{ bearerAuth: [] }],
        tags: ['classes'],
        params: z.object({
          slug: z.string().optional(),
        }),
        response: {
          200: z.object({
            id: z.string(),
            slug: z.string(),
            name: z.string(),
            video: z.string(),
            description: z.string(),
            nextClass: z.object({
              id: z.string(),
              slug: z.string(),
              title: z.string(),
            }).optional(),
          }),
          400: z.object({
            message: z.string()
          })
        },
      },
    }, async (request, reply) => {
      const { slug } = request.params;
      const userId = await request.getCurrentUserId();

      if (!userId) {
        throw new UnauthorizedError('You do not have permission to access this route');
      }

      let classData;

      if (slug) {
        classData = await prisma.class.findUnique({
          where: { slug: slug },
          select: {
            id: true,
            slug: true,
            title: true,
            video: true,
            description: true,
            order: true, // Campo usado para ordenar as aulas
            createdAt: true, // Campo usado para desempate
            module: {
              select: {
                courseId: true,
              }
            }
          },
        });

        if (!classData) {
          return reply.status(404).send({ message: 'Class not found' });
        }
      } else {
        // Fetch the first class of the course
        const firstClass = await prisma.class.findFirst({
          where: {
            module: {
              course: {
                UserCourse: {
                  some: {
                    userId: userId,
                  },
                },
              },
            },
          },
          orderBy: [
            { order: 'asc' },
            { createdAt: 'asc' }
          ],
          select: {
            id: true,
            slug: true,
            title: true,
            video: true,
            description: true,
            order: true, // Campo usado para ordenar as aulas
            createdAt: true, // Campo usado para desempate
            module: {
              select: {
                courseId: true,
              }
            }
          },
        });

        if (!firstClass) {
          return reply.status(404).send({ message: 'No classes found for the user' });
        }

        classData = firstClass;
      }

      const userCourse = await prisma.userCourse.findFirst({
        where: {
          userId: userId,
          courseId: classData.module.courseId,
        },
      });

      if (!userCourse) {
        throw new UnauthorizedError('You do not have permission to access this class');
      }

      // Fetch the next class in the course, independent of the module
      const nextClass = await prisma.class.findFirst({
        where: {
          module: {
            courseId: classData.module.courseId,
          },
          OR: [
            {
              order: {
                gt: classData.order
              }
            },
            {
              order: classData.order,
              createdAt: {
                gt: classData.createdAt
              }
            }
          ]
        },
        orderBy: [
          { order: 'asc' },
          { createdAt: 'asc' }
        ],
        select: {
          id: true,
          slug: true,
          title: true,
        }
      });

      return reply.send({
        id: classData.id,
        slug: classData.slug,
        name: classData.title,
        video: classData.video,
        description: classData.description,
        nextClass: nextClass ? {
          id: nextClass.id,
          slug: nextClass.slug,
          title: nextClass.title,
        } : undefined,
      });
    });
}
