import { Prisma } from '@prisma/client'
import type { DefaultData, FactoryBuilder } from './types'
import { buildIncludes, mergeData } from './utils'

export const factoryExtension = Prisma.defineExtension((client) => {
  return client.$extends({
    name: '@prisma-extensions/factory',
    model: {
      $allModels: {
        $factory<Model, Args extends object>(
          this: Model,
          defaultData: DefaultData<Model, Args>,
        ): FactoryBuilder<Model> {
          return {
            attributes(data = {}) {
              return mergeData<Model>(defaultData, data)
            },

            create: async (data = {}) => {
              const mergedData = mergeData<Model>(defaultData, data)

              // @ts-expect-error: Requires more types from Prisma
              return await this.create({
                data: mergedData,
                include: buildIncludes<Model>(mergedData),
              })
            },
          }
        },
      },
    },
  })
})
