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";

export async function getCoursesAll(app: FastifyInstance) {
  app
    .withTypeProvider<ZodTypeProvider>()
    .get('/coursesall', {
      schema: {
        summary: 'Get courses',
        tags: ['courses'],
        querystring: z.object({
          query: z.string().nullish(),
          pageIndex: z.string().nullish().default('0').transform(Number),
        }),
        response: {
          200: z.object({
            courses: z.array(
              z.object({
                id: z.string(),
                title: z.string(),
                description: z.string(),
                image: z.string(),
                certificate: z.boolean(),
                status: z.boolean(),
                totalDuration: z.number(),
                modules: z.array(
                  z.object({
                    id: z.string(),
                    title: z.string(),
                    description: z.string(),
                    totalDuration: z.number(),
                    numberOfClasses: z.number(),
                    classes: z.array(
                      z.object({
                        id: z.string(),
                        title: z.string(),
                        video: z.string(),
                        description: z.string(),
                        duration: z.number(),
                        createdAt: z.string(),
                      })
                    )
                  })
                )
              })
            ),
            total: z.number(),
          }),
        },
      },
    }, async (request, reply) => {
      const { pageIndex, query } = request.query

      const [courses, total] = await Promise.all([
        prisma.course.findMany({
          select: {
            id: true,
            title: true,
            description: true,
            image: true,
            certificate: true,
            status: true,
            Module: {
              select: {
                id: true,
                title: true,
                description: true,
                Class: {
                  orderBy: [
                    { order: 'asc' },
                    { createdAt: 'asc' },
                  ],
                  select: {
                    id: true,
                    title: true,
                    video: true,
                    description: true,
                    duration: true,
                    createdAt: true,
                    order: true,
                  }
                }
              }
            }
          },
          where: {
            status: true,
            ...(query ? {
              OR: [
                { title: { contains: query } },
              ],
            } : {}),
          },
          take: 10,
          skip: pageIndex * 10,
          orderBy: {
            title: 'asc'
          }
        }),
        prisma.course.count({
          where: {
            status: true,
            ...(query ? {
              OR: [
                { title: { contains: query } },
              ],
            } : {}),
          },
        })
      ])

      const formattedCourses = courses.map(course => {
        let courseTotalDuration = 0;

        const modules = course.Module.map(module => {
          const totalDuration = module.Class.reduce((sum, cls) => sum + cls.duration, 0);
          const numberOfClasses = module.Class.length;
          courseTotalDuration += totalDuration;

          return {
            id: module.id,
            title: module.title,
            description: module.description,
            totalDuration,
            numberOfClasses,
            classes: module.Class.map(c => {
              return {
                id: c.id,
                title: c.title,
                video: c.video,
                description: c.description,
                duration: c.duration,
                createdAt: c.createdAt.toISOString(),
              }
            })
          }
        });

        return {
          id: course.id,
          title: course.title,
          description: course.description,
          image: course.image,
          certificate: course.certificate,
          status: course.status,
          totalDuration: courseTotalDuration,
          modules
        }
      });

      return reply.send({
        courses: formattedCourses,
        total,
      })
    })
}
