import { eq, sql, and } from "drizzle-orm";
import useDatabase from "~/composables/useDatabase";
import { userSessionsTable } from "~/db/schema";
import type { Return } from "~/types/api";
import type { UserSession, UserSessionRequired } from "~/types/auth";

export function checkSession(e: H3Event<EventRequestHandler>, session: UserSession): Return | undefined
{
    const db = useDatabase();
    
    if(session.id && session.user?.id)
    {
        const sessionId = db.select({ user_id: userSessionsTable.user_id }).from(userSessionsTable).where(and(eq(userSessionsTable.id, sql.placeholder('id')), eq(userSessionsTable.user_id, sql.placeholder('user_id')))).prepare().get({ id: session.id, user_id: session.user.id })

        if(sessionId && sessionId.user_id === session.user?.id)
        {
            return { success: true, session };
        }
        else
        {
            clearUserSession(e);
            
            setResponseStatus(e, 406);
            return { success: false, error: new Error('Vous êtes déjà connecté') };
        }
    }
}
export function logSession(e: H3Event<EventRequestHandler>, session: UserSessionRequired): UserSessionRequired
{
    const db = useDatabase();

    db.insert(userSessionsTable).values({ id: sql.placeholder('id'), user_id: sql.placeholder('user_id'), timestamp: sql.placeholder('timestamp') }).prepare().run({ id: session.id, user_id: session.user.id, timestamp: new Date() });
    return session;
}
export async function refreshSessionFromDB(e: H3Event<EventRequestHandler>, sessionId: string): Promise<void>
{
    const db = useDatabase();

    const user = db.query.userSessionsTable.findFirst({
        columns: {
            id: false,
        },
        with: {
            users: {
                with: {
                    permission: true,
                    data: true,
                }
            }
        },
        where: (table) => eq(table.id, sql.placeholder('id'))
    }).prepare().get({ id: sessionId });

    if(user)
    {
        await replaceUserSession(e, { 
            id: sessionId,
            user: {
                ...user.users.data,
                email: user.users.email,
                username: user.users.username,
                state: user.users.state,
                permissions: user.users.permission.map(e => e.permission),
            }
        });
    }
    else
    {
        throw createError({ statusCode: 401, message: 'Invalid session' });
    }
}