// @ts-check

const updateDbEntry = require("../../backend/db/updateDbEntry");
const encrypt = require("../../dsql/encrypt");
const hashPassword = require("../../dsql/hashPassword");
const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler");

/**
 * # Update API User Function
 *
 * @param {object} params
 * @param {Object<string, any>} params.payload
 * @param {string} params.dbFullName
 * @param {string | number} params.updatedUserId
 * @param {boolean} [params.useLocal]
 * @param {import("../../../types").DSQL_DatabaseSchemaType} [params.dbSchema]
 *
 * @returns {Promise<{ success: boolean, payload?: any, msg?: string }>}
 */
module.exports = async function apiUpdateUser({
    payload,
    dbFullName,
    updatedUserId,
    useLocal,
    dbSchema,
}) {
    const existingUserQuery = `SELECT * FROM users WHERE id = ?`;
    const existingUserValues = [updatedUserId];

    const existingUser = await varDatabaseDbHandler({
        queryString: existingUserQuery,
        queryValuesArray: existingUserValues,
        database: dbFullName,
        useLocal,
    });

    if (!existingUser?.[0]) {
        return {
            success: false,
            msg: "User not found",
        };
    }

    const data = (() => {
        const reqBodyKeys = Object.keys(payload);

        const targetTableSchema = (() => {
            try {
                const targetDatabaseSchema = dbSchema?.tables?.find(
                    (tbl) => tbl.tableName == "users"
                );
                return targetDatabaseSchema;
            } catch (error) {
                return undefined;
            }
        })();

        /** @type {any} */
        const finalData = {};

        reqBodyKeys.forEach((key) => {
            const targetFieldSchema = targetTableSchema?.fields?.find(
                (field) => field.fieldName == key
            );

            if (key?.match(/^date_|^id$|^uuid$/)) return;
            let value = payload[key];

            if (targetFieldSchema?.encrypted) {
                value = encrypt({ data: value });
            }

            finalData[key] = value;
        });

        if (finalData.password && typeof finalData.password == "string") {
            finalData.password = hashPassword({ password: finalData.password });
        }

        return finalData;
    })();

    const updateUser = await updateDbEntry({
        dbContext: "Dsql User",
        paradigm: "Full Access",
        dbFullName,
        tableName: "users",
        identifierColumnName: "id",
        identifierValue: updatedUserId,
        data: data,
        useLocal,
    });

    return {
        success: true,
        payload: updateUser,
    };
};