import jwt from "jsonwebtoken";
import {db} from "../../../../database/dbclient.js";
import {users} from "../../../../database/schema/users.js";
import {eq, sql} from "drizzle-orm";
import {checkPassword} from "../utils/checkPassword.js";
import {roleCheck} from "./userRoles/getUserAccess.js";
import {createLog} from "../../logger/logger.js";
import {differenceInDays} from "date-fns";

/**
 * Authenticate a user and return a JWT.
 */
const {sign} = jwt;

export async function login(
    username: string,
    password: string
): Promise<{token: string; user: {user_id: string; username: string}}> {
    const user = await db.select().from(users).where(eq(users.username, username));

    //console.log(user);
    if (user.length === 0) {
        throw new Error("Invalid or Missing user");
    }
    // check the password
    const checkedPass = await checkPassword(password, user[0]?.password);
    //console.log(checkedPass);
    if (!checkedPass) {
        throw new Error("Invalid Password");
    }

    // Create a JWT
    const secret: string = process.env.JWT_SECRET!;
    const expiresIn = Number(process.env.JWT_EXPIRES!) || 60;

    // get the user roles
    const roles = await roleCheck(user[0].user_id);
    const userData = {
        user_id: user[0].user_id,
        username: user[0].username,
        email: user[0].email,
        //roles: roles || null,
        role: user[0].role || null, // this should be removed onces full migration to v2 is completed
        prod: btoa(`${username.toLowerCase()}:${password}`),
    };

    // update the user last login
    try {
        const lastLog = await db
        .update(users)
        .set({lastLogin: sql`NOW()`})
        .where(eq(users.user_id, user[0].user_id))
        .returning({lastLogin: users.lastLogin});
        createLog(
            "info",
            "lst",
            "auth",
            `Its been ${differenceInDays(lastLog[0]?.lastLogin ?? "", new Date(Date.now()))} days since ${
                user[0].username
            } has logged in`
        );
        //]);
    } catch (error) {
        createLog("error", "lst", "auth", "There was an error updating the user last login");
    }

    const token = sign({user: userData}, secret, {expiresIn: expiresIn * 60});

    return {token, user: userData};
}
