// @ts-check

const LOCAL_DB_HANDLER = require("../../../utils/backend/global-db/LOCAL_DB_HANDLER");
const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler");
const hashPassword = require("../../dsql/hashPassword");

/** @type {import("../../../types").APILoginFunction} */
module.exports = async function apiLoginUser({
    encryptionKey,
    email,
    username,
    password,
    database,
    additionalFields,
    email_login,
    email_login_code,
    email_login_field,
    token,
    skipPassword,
    social,
    useLocal,
}) {
    const dbFullName = database;

    /**
     * Check input validity
     *
     * @description Check input validity
     */
    if (
        email?.match(/ /) ||
        (username && username?.match(/ /)) ||
        (password && password?.match(/ /))
    ) {
        return {
            success: false,
            msg: "Invalid Email/Password format",
        };
    }

    /**
     * Password hash
     *
     * @description Password hash
     */
    let hashedPassword = password
        ? hashPassword({
              encryptionKey: encryptionKey,
              password: password,
          })
        : null;

    let foundUser = useLocal
        ? await LOCAL_DB_HANDLER(
              `SELECT * FROM users WHERE email = ? OR username = ?`,
              [email, username]
          )
        : await varDatabaseDbHandler({
              queryString: `SELECT * FROM users WHERE email = ? OR username = ?`,
              queryValuesArray: [email, username],
              database: dbFullName.replace(/[^a-z0-9_]/g, ""),
          });

    if ((!foundUser || !foundUser[0]) && !social)
        return {
            success: false,
            payload: null,
            msg: "No user found",
        };

    let isPasswordCorrect = false;

    if (foundUser?.[0] && !email_login && skipPassword) {
        isPasswordCorrect = true;
    } else if (foundUser?.[0] && !email_login) {
        isPasswordCorrect = hashedPassword === foundUser[0].password;
    } else if (
        foundUser &&
        foundUser[0] &&
        email_login &&
        email_login_code &&
        email_login_field
    ) {
        /** @type {string} */
        const tempCode = foundUser[0][email_login_field];

        if (!tempCode) throw new Error("No code Found!");

        const tempCodeArray = tempCode.split("-");
        const [code, codeDate] = tempCodeArray;
        const millisecond15mins = 1000 * 60 * 15;

        if (Date.now() - Number(codeDate) > millisecond15mins) {
            throw new Error("Code Expired");
        }
        isPasswordCorrect = code === email_login_code;
    }

    let socialUserValid = false;

    if (!isPasswordCorrect && !socialUserValid) {
        return {
            success: false,
            msg: "Wrong password, no social login validity",
            payload: null,
        };
    }

    if (isPasswordCorrect && email_login) {
        const resetTempCode = useLocal
            ? await LOCAL_DB_HANDLER(
                  `UPDATE users SET ${email_login_field} = ? WHERE email = ? OR username = ?`,
                  ["", email, username]
              )
            : await varDatabaseDbHandler({
                  queryString: `UPDATE users SET ${email_login_field} = ? WHERE email = ? OR username = ?`,
                  queryValuesArray: ["", email, username],
                  database: dbFullName.replace(/[^a-z0-9_]/g, ""),
              });
    }

    let csrfKey =
        Math.random().toString(36).substring(2) +
        "-" +
        Math.random().toString(36).substring(2);

    /** @type {import("../../../types").DATASQUIREL_LoggedInUser} */
    let userPayload = {
        id: foundUser[0].id,
        first_name: foundUser[0].first_name,
        last_name: foundUser[0].last_name,
        username: foundUser[0].username,
        email: foundUser[0].email,
        phone: foundUser[0].phone,
        social_id: foundUser[0].social_id,
        image: foundUser[0].image,
        image_thumbnail: foundUser[0].image_thumbnail,
        verification_status: foundUser[0].verification_status,
        social_login: foundUser[0].social_login,
        social_platform: foundUser[0].social_platform,
        csrf_k: csrfKey,
        more_data: foundUser[0].more_user_data,
        logged_in_status: true,
        date: Date.now(),
    };

    const resposeObject = {
        success: true,
        msg: "Login Successful",
        payload:
            /** @type {import("../../../types").DATASQUIREL_LoggedInUser} */ (
                userPayload
            ),
        userId: foundUser[0].id,
    };

    if (
        additionalFields &&
        Array.isArray(additionalFields) &&
        additionalFields.length > 0
    ) {
        additionalFields.forEach((key) => {
            userPayload[key] = foundUser[0][key];
        });
    }

    return resposeObject;
};