import { prisma } from '@/db';
import { Notification } from '@/generated/prisma/client';
import { parseError } from '@lib/errors';
import { authMiddleware } from '@lib/middleware';
import { createServerFn } from '@tanstack/react-start';
import { notificationListSchema } from './notify.schema';

export const getTopFiveNotification = createServerFn({ method: 'GET' })
  .middleware([authMiddleware])
  .handler(async ({ context: { user } }) => {
    try {
      const [list, total]: [Notification[], number] = await prisma.$transaction(
        [
          prisma.notification.findMany({
            where: {
              userId: user.id,
            },
            orderBy: {
              createdAt: 'asc',
            },
            take: 5,
          }),
          prisma.notification.count({
            where: {
              userId: user.id,
              readAt: null,
            },
          }),
        ],
      );

      return {
        list,
        hasNewNotify: total > 0,
      };
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });

export const getAllNotifications = createServerFn({ method: 'GET' })
  .middleware([authMiddleware])
  .validator(notificationListSchema)
  .handler(async ({ data, context: { user } }) => {
    try {
      const skip = (data.page - 1) * data.limit;

      const [list, total]: [NotificationWithUser[], number] =
        await prisma.$transaction([
          prisma.notification.findMany({
            where: {
              userId: user.id,
            },
            include: {
              user: {
                select: {
                  id: true,
                  name: true,
                  email: true,
                  image: true,
                },
              },
            },
            orderBy: {
              createdAt: 'asc',
            },
            take: data.limit,
            skip,
          }),
          prisma.notification.count({
            where: {
              userId: user.id,
            },
          }),
        ]);

      const totalPage = Math.ceil(+total / data.limit);

      return {
        result: list,
        pagination: {
          currentPage: data.page,
          totalPage,
          totalItem: total,
        },
      };
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });

export const updateReadedNotification = createServerFn({ method: 'POST' })
  .middleware([authMiddleware])
  .handler(async ({ context: { user } }) => {
    try {
      const result = await prisma.notification.findMany({
        where: { userId: user.id, readAt: null },
      });

      if (result.length > 0) {
        await prisma.notification.updateMany({
          where: { userId: user.id, readAt: null },
          data: { readAt: new Date() },
        });
      }
    } catch (error) {
      console.error(error);
      const { message, code } = parseError(error);
      throw { message, code };
    }
  });
