/**
 * De server-only import (die geïnstalleerd moet worden via pnpm) zorgt ervoor dat de code in dit bestand enkel op de
 * server uitgevoerd kan worden.
 * Als één van de geëxporteerde functies geïmporteerd wordt in een client component of hook zal de applicatie niet
 * compileren en een foutmelding opgooien.
 */
import 'server-only'
import {prismaClient} from './prismaClient'
import type {Contact, Prisma} from '@/generated/prisma/client'
import {toggleFavoriteQuery} from '@/generated/prisma/sql/toggleFavoriteQuery'

export type CreateContactParams = Prisma.ContactCreateInput

/**
 * Create a new contact for the currently logged-in user.
 * @param contact
 */
export function createContact(contact: CreateContactParams): Promise<Contact> {
  return prismaClient.contact.create({data: contact})
}

/**
 * Retrieve the contacts for the currently logged-in user.
 */
export function getContacts(contactName: string = ''): Promise<Contact[]> {
  return prismaClient.contact.findMany({
    where: {
      OR: [
        {firstName: {contains: contactName, mode: 'insensitive'}},
        {lastName: {contains: contactName, mode: 'insensitive'}},
      ],
    },
  }) as Promise<Contact[]>
}

/**
 * Retrieve the contacts which have been added to user's favorites.
 */
export function getFavoriteContacts(): Promise<Contact[]> {
  return prismaClient.contact.findMany({
    where: {favorite: true},
  })
}

/**
 * Retrieve a single contact.
 *
 * @param id The id of the contact to retrieve.
 */
export function getContact(id: string): Promise<Contact> {
  // De findUnique methode geeft een null terug als er geen match gevonden is.
  // De findUniqueOrThrow methode gooit een error als er geen match gevonden is.
  return prismaClient.contact.findUniqueOrThrow({where: {id}})
}

export type UpdateContactParams = Prisma.ContactUpdateInput & {id: string}

/**
 * Update an existing contact.
 *
 * @param contact The updated contact info.
 */
export function updateContact(contact: UpdateContactParams): Promise<Contact> {
  return prismaClient.contact.update({where: {id: contact.id}, data: contact})
}

/**
 * Delete an existing contact.
 *
 * @param id The id of the contact to delete.
 */
export async function deleteContact(id: string): Promise<void> {
  await prismaClient.contact.delete({where: {id}})
}

/**
 * Toggle the favorite option for a given contact.
 *
 * @param id The id of the contact for which the favorite column must be toggled.
 */
export async function toggleFavorite(id: string): Promise<Contact> {
  const data = await prismaClient.$queryRawTyped(toggleFavoriteQuery(id))
  // Deze cast is nodig omdat de Prisma JSON generator niet werkt met TypedSQL queries.
  return data[0] as Contact
}
