import {
    APILoginFunctionParams,
    APILoginFunctionReturn,
    DATASQUIREL_LoggedInUser,
} from "../../../types";
import grabDbFullName from "../../../utils/grab-db-full-name";
import varDatabaseDbHandler from "../../backend/varDatabaseDbHandler";
import hashPassword from "../../dsql/hashPassword";

/**
 * # API Login
 */
export default async function apiLoginUser({
    encryptionKey,
    email,
    username,
    password,
    database,
    additionalFields,
    email_login,
    email_login_code,
    email_login_field,
    skipPassword,
    social,
    dbUserId,
    debug,
}: APILoginFunctionParams): Promise<APILoginFunctionReturn> {
    const dbFullName = grabDbFullName({ dbName: database, userId: dbUserId });
    const dbAppend = global.DSQL_USE_LOCAL ? "" : `${dbFullName}.`;

    /**
     * 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;

    if (debug) {
        console.log("apiLoginUser:database:", dbFullName);
        console.log("apiLoginUser:Finding User ...");
    }

    let foundUser = await varDatabaseDbHandler({
        queryString: `SELECT * FROM ${dbAppend}users WHERE email = ? OR username = ?`,
        queryValuesArray: [email, username],
        database: dbFullName,

        debug,
    });

    if (debug) {
        console.log("apiLoginUser:foundUser:", foundUser);
    }

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

    let isPasswordCorrect = false;

    if (debug) {
        console.log("apiLoginUser:isPasswordCorrect:", isPasswordCorrect);
    }

    if (foundUser?.[0] && !email_login && skipPassword) {
        isPasswordCorrect = true;
    } else if (foundUser?.[0] && !email_login) {
        if (debug) {
            console.log("apiLoginUser:hashedPassword:", hashedPassword);
            console.log(
                "apiLoginUser:foundUser[0].password:",
                foundUser[0].password
            );
        }
        isPasswordCorrect = hashedPassword === foundUser[0].password;
    } else if (
        foundUser &&
        foundUser[0] &&
        email_login &&
        email_login_code &&
        email_login_field
    ) {
        const tempCode: string = foundUser[0][email_login_field];

        if (debug) {
            console.log("apiLoginUser:tempCode:", tempCode);
        }

        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 (debug) {
        console.log("apiLoginUser:isPasswordCorrect:", isPasswordCorrect);
        console.log("apiLoginUser:email_login:", email_login);
    }

    if (isPasswordCorrect && email_login) {
        const resetTempCode = await varDatabaseDbHandler({
            queryString: `UPDATE ${dbAppend}users SET ${email_login_field} = '' WHERE email = ? OR username = ?`,
            queryValuesArray: [email, username],
            database: dbFullName,
        });
    }

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

    let userPayload: DATASQUIREL_LoggedInUser = {
        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(),
    };

    if (debug) {
        console.log("apiLoginUser:userPayload:", userPayload);
        console.log("apiLoginUser:Sending Response Object ...");
    }

    const resposeObject: APILoginFunctionReturn = {
        success: true,
        msg: "Login Successful",
        payload: userPayload,
        userId: foundUser[0].id,
        csrf: csrfKey,
    };

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

    return resposeObject;
}
