'use server'

import { z } from 'zod';
import { sql } from '@/app/lib/db';
import { signIn } from '@/auth';
import bcrypt from "bcryptjs";
import { AuthError } from 'next-auth';

export async function authenticate(
    prevState: string | undefined,
    formData: FormData,
) {
    try {
        const redirectTo =
            (formData.get('redirectTo') as string)?.startsWith('/')
                ? (formData.get('redirectTo') as string)
                : '/dashboard';

        await signIn('credentials', {
            ...Object.fromEntries(formData),
            redirectTo,
        });
    } catch (error) {
        if (error instanceof AuthError) {
            switch (error.type) {
                case 'CredentialsSignin':
                    return 'Invalid email or password.';
                default:
                    return 'Something went wrong. Please try again.';
            }
        }
        throw error;
    }
}

export async function register(
    prevState: string | undefined,
    formData: FormData,
) {
    const schema = z.object({
        user_name: z.string().min(1),
        email: z.string().email(),
        password: z.string().min(6),
        redirectTo: z.string().optional(),
    });

    const parsed = schema.safeParse({
        user_name: formData.get('user_name'),
        email: formData.get('email'),
        password: formData.get('password'),
        redirectTo: formData.get('redirectTo'),
    });

    if (!parsed.success) {
        return 'Invalid form data.';
    }

    const { user_name, email, password, redirectTo } = parsed.data;

    // sanitize redirect
    const safeRedirect =
        redirectTo?.startsWith('/') ? redirectTo : '/dashboard';

    const hashed = await bcrypt.hash(password, 10);

    try {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        await sql.begin(async (tx: any) => {
            const existing = await tx`SELECT user_id FROM "user" WHERE email=${email}`;

            if (existing.length > 0) {
                throw new Error('User already exists.');
            }

            await tx`
                INSERT INTO "user" (user_name, email, password)
                VALUES (${user_name}, ${email}, ${hashed})
            `;
        });
    } catch (e: any) {
        if (e instanceof Error && e.message === 'User already exists.') {
            return e.message;
        }
        return 'Failed to create user.';
    }

    try {
        await signIn('credentials', {
            email,
            password,
            redirectTo: safeRedirect,
        });
    } catch (error) {
        if (error instanceof AuthError) {
            return 'Account created, but auto-login failed. Please log in.';
        }
        throw error;
    }
}
