'use server'

import {User} from '@prisma/client'
import bcrypt from 'bcryptjs'
import {AuthError} from 'next-auth'
import {getTranslations} from 'next-intl/server'
import * as z from 'zod'

import {signIn} from '@/auth'
import {db} from '@/lib/db/prisma/client'
import {LoginSchema} from '@/lib/schemas'

export const login = async (data: z.infer<typeof LoginSchema>) => {
	const t = await getTranslations('Auth')
	// Validate the input data
	const validatedData = LoginSchema.parse(data)

	//  If the data is invalid, return an error
	if (!validatedData) {
		return {error: t('Error.invalid-input-data')}
	}

	//  Destructure the validated data
	const {email, password} = validatedData

	const userExists = await db.user.findFirst({
		where: {email}
	})

	if (!userExists || !userExists.password || !userExists.email) {
		return {error: t('Error.user-not-found')}
	}

	try {
		await signIn('credentials', {
			email: userExists.email as string,
			password: password as string,
			redirectTo: '/'
		})
	} catch (error) {
		if (error instanceof AuthError) {
			switch (error.type) {
				case 'CredentialsSignin':
					return {error: 'Invalid credentials'}
				default:
					return {error: error.type}
			}
		}

		throw error
	}

	return {success: 'User successfully logged in!'}
}

export const authorizeCallback = async (
	credentials: Partial<Record<'email' | 'password', unknown>>
): Promise<User | null> => {
	const validatedData = z
		.object({
			email: z.string().email(),
			password: z.string().min(6)
		})
		.safeParse(credentials)

	if (!validatedData.success) return null

	const {email, password} = validatedData.data

	const user = await db.user.findFirst({
		where: {email}
	})

	if (!user || !user.password || !user.email) return null

	try {
		if (await bcrypt.compare(password, user.password)) {
			return user
		} else {
			console.log('Invalid credentials', user.email)
			return null
		}
	} catch (err) {
		console.log('Verifying password error', err)
	}
	return null
}
