import { Asset, Prisma } from "@/generated/prisma/client"
import { paginate } from "@/lib/paginate"
import prisma from "@/lib/prisma"
import {
  AssetWithAssignment,
  AssetWithItemAndCategory,
} from "@/lib/types/asset"

export const AssetService = {
  findAll: async (opts?: {
    includeItem?: boolean
    includeCategory?: boolean
  }) => {
    return prisma.asset.findMany({
      include: {
        item: opts?.includeItem
          ? {
              include: opts?.includeCategory ? { category: true } : undefined,
            }
          : undefined,
      },
    })
  },

  findAllAvailable: async (): Promise<Asset[]> => {
    return prisma.asset.findMany({
      where: {
        status: {
          equals: "AVAILABLE",
        },
      },
    })
  },

  findAllAssetsCount: async (): Promise<number> => {
    return prisma.asset.count()
  },

  findAllWithItemAndCategory: async ({
    page,
    pageSize,
    search,
  }: {
    page?: number
    pageSize?: number
    search?: string
  }) => {
    return paginate<AssetWithItemAndCategory>({
      model: prisma.asset,
      page,
      pageSize,
      where: {
        ...(search
          ? {
              OR: [
                { serialNumber: { contains: search, mode: "insensitive" } },
                {
                  item: {
                    is: {
                      name: { contains: search, mode: "insensitive" },
                    },
                  },
                },
                {
                  item: {
                    is: {
                      category: {
                        is: {
                          name: { contains: search, mode: "insensitive" },
                        },
                      },
                    },
                  },
                },
              ],
            }
          : {}),
      },
      orderBy: { item: { name: "asc" } },
      select: {
        id: true,
        serialNumber: true,
        deliveryNote: true,
        status: true,
        item: {
          select: {
            id: true,
            name: true,
            category: { select: { id: true, name: true } },
          },
        },
      },
    })
  },

  findById: async (id: string): Promise<AssetWithAssignment | null> => {
    return prisma.asset.findUnique({
      where: { id },
      include: { item: true, assignment: true },
    })
  },

  findByItemId: async (itemId: string): Promise<Asset[]> => {
    return prisma.asset.findMany({ where: { itemId } })
  },

  findBySerialNumber: async (
    serialNumber: string,
  ): Promise<AssetWithAssignment | null> => {
    return prisma.asset.findUnique({
      where: { serialNumber },
      include: { item: true, assignment: true },
    })
  },

  create: async (data: Prisma.AssetCreateInput): Promise<Asset> => {
    return prisma.asset.create({ data })
  },

  update: async (id: string, data: Prisma.AssetUpdateInput): Promise<Asset> => {
    return prisma.asset.update({ where: { id }, data })
  },

  delete: async (id: string): Promise<Asset> => {
    return prisma.asset.delete({ where: { id } })
  },
}
