import { Prisma } from "@/generated/prisma/client"
import { paginate } from "@/lib/paginate"
import prisma from "@/lib/prisma"
import { CreateAssignmentFormType } from "@/lib/schemas/assignment.schemas"
import { Assignment, AssignmentWithRecipientItemAsset } from "@/lib/types"

import { getAuthenticatedUserId } from "./auth.service"

export const AssignmentService = {
  findAllWithRecipient: async ({
    page,
    pageSize,
    search,
  }: {
    page?: number
    pageSize?: number
    search?: string
  }) => {
    return paginate<AssignmentWithRecipientItemAsset>({
      model: prisma.assignment,
      page,
      pageSize,
      where: {
        returnDate: {
          equals: null,
        },
        ...(search
          ? {
              OR: [
                {
                  recipient: {
                    firstName: { contains: search, mode: "insensitive" },
                  },
                },
                {
                  recipient: {
                    lastName: { contains: search, mode: "insensitive" },
                  },
                },
              ],
            }
          : {}),
      },
      include: {
        recipient: true,
        item: true,
        asset: true,
      },
      orderBy: {
        createdAt: "desc",
      },
    })
  },
  findById: async (
    id: string,
  ): Promise<AssignmentWithRecipientItemAsset | null> => {
    return prisma.assignment.findUnique({
      where: { id },
      include: {
        recipient: true,
        item: true,
        asset: true,
      },
    })
  },
  findAllByRecipient: async (
    recipientId: string,
  ): Promise<AssignmentWithRecipientItemAsset[]> => {
    return prisma.assignment.findMany({
      where: { recipientId },
      include: {
        recipient: true,
        item: true,
        asset: true,
      },
    })
  },
  create: async (data: CreateAssignmentFormType): Promise<Assignment> => {
    return prisma.assignment.create({
      data: {
        ...data,
        createdBy: await getAuthenticatedUserId(),
      },
    })
  },
  delete: async (id: string): Promise<Assignment> => {
    return prisma.assignment.update({
      where: { id },
      data: {
        returnDate: new Date(),
        recipientId: null,
        quantity: null,
        assetId: null,
        itemId: null,
      },
    })
  },
  update: async (
    id: string,
    data: Prisma.AssignmentUpdateInput,
  ): Promise<Assignment> => {
    return prisma.assignment.update({
      where: { id },
      data,
    })
  },
}
