// @ts-check

const fs = require("fs");
const handleNodemailer = require("../../backend/handleNodemailer");
const path = require("path");
const addMariadbUser = require("../../backend/addMariadbUser");
const varDatabaseDbHandler = require("../../backend/varDatabaseDbHandler");
const encrypt = require("../../dsql/encrypt");
const addDbEntry = require("../../backend/db/addDbEntry");
const loginSocialUser = require("./loginSocialUser");

/**
 * @type {import("../../../types").HandleSocialDbFunction}
 */
module.exports = async function handleSocialDb({
    database,
    social_id,
    email,
    social_platform,
    payload,
    invitation,
    supEmail,
    additionalFields,
    useLocal,
}) {
    try {
        const existingSocialIdUserQuery = `SELECT * FROM users WHERE social_id = ? AND social_login='1' AND social_platform = ? `;
        const existingSocialIdUserValues = [
            social_id.toString(),
            social_platform,
        ];

        let existingSocialIdUser = await varDatabaseDbHandler({
            database: database ? database : "datasquirel",
            queryString: existingSocialIdUserQuery,
            queryValuesArray: existingSocialIdUserValues,
            useLocal,
        });

        if (existingSocialIdUser && existingSocialIdUser[0]) {
            return await loginSocialUser({
                user: existingSocialIdUser[0],
                social_platform,
                invitation,
                database,
                additionalFields,
                useLocal,
            });
        }

        const finalEmail = email ? email : supEmail ? supEmail : null;

        if (!finalEmail) {
            return {
                success: false,
                payload: null,
                msg: "No Email Present",
            };
        }

        const existingEmailOnlyQuery = `SELECT * FROM users WHERE email='${finalEmail}'`;

        let existingEmailOnly = await varDatabaseDbHandler({
            database: database ? database : "datasquirel",
            queryString: existingEmailOnlyQuery,
            useLocal,
        });

        if (existingEmailOnly && existingEmailOnly[0]) {
            return {
                success: false,
                payload: null,
                msg: "This Email is already taken",
            };
        }

        const foundUserQuery = `SELECT * FROM users WHERE email=? AND social_login='1' AND social_platform=? AND social_id=?`;
        const foundUserQueryValues = [finalEmail, social_platform, social_id];

        const foundUser = await varDatabaseDbHandler({
            database: database ? database : "datasquirel",
            queryString: foundUserQuery,
            queryValuesArray: foundUserQueryValues,
            useLocal,
        });

        if (foundUser && foundUser[0]) {
            return await loginSocialUser({
                user: payload,
                social_platform,
                invitation,
                database,
                additionalFields,
                useLocal,
            });
        }

        const socialHashedPassword = encrypt({
            data: social_id.toString(),
        });

        /** @type {any} */
        const data = {
            social_login: "1",
            verification_status: supEmail ? "0" : "1",
            password: socialHashedPassword,
        };

        Object.keys(payload).forEach((key) => {
            data[key] = payload[key];
        });

        /** @type {any} */
        const newUser = await addDbEntry({
            dbContext: database ? "Dsql User" : undefined,
            paradigm: database ? "Full Access" : undefined,
            dbFullName: database ? database : "datasquirel",
            tableName: "users",
            duplicateColumnName: "email",
            duplicateColumnValue: finalEmail,
            data: {
                ...data,
                email: finalEmail,
            },
            useLocal,
        });

        if (newUser?.insertId) {
            if (!database) {
                /**
                 * Add a Mariadb User for this User
                 */
                await addMariadbUser({ userId: newUser.insertId, useLocal });
            }

            const newUserQueriedQuery = `SELECT * FROM users WHERE id='${newUser.insertId}'`;

            const newUserQueried = await varDatabaseDbHandler({
                database: database ? database : "datasquirel",
                queryString: newUserQueriedQuery,
                useLocal,
            });

            if (!newUserQueried || !newUserQueried[0])
                return {
                    success: false,
                    payload: null,
                    msg: "User Insertion Failed!",
                };

            if (supEmail && database?.match(/^datasquirel$/)) {
                /**
                 * Send email Verification
                 *
                 * @description Send verification email to newly created agent
                 */
                let generatedToken = encrypt({
                    data: JSON.stringify({
                        id: newUser.insertId,
                        email: supEmail,
                        dateCode: Date.now(),
                    }),
                });

                handleNodemailer({
                    to: supEmail,
                    subject: "Verify Email Address",
                    text: "Please click the link to verify your email address",
                    html: fs
                        .readFileSync(
                            "./email/send-email-verification-link.html",
                            "utf8"
                        )
                        .replace(/{{host}}/, process.env.DSQL_HOST || "")
                        .replace(/{{token}}/, generatedToken || ""),
                }).then((mail) => {});
            }

            const STATIC_ROOT = process.env.DSQL_STATIC_SERVER_DIR;

            if (!STATIC_ROOT) {
                console.log("Static File ENV not Found!");
                return {
                    success: false,
                    payload: null,
                    msg: "Static File ENV not Found!",
                };
            }

            /**
             * Create new user folder and file
             *
             * @description Create new user folder and file
             */
            if (!database || database?.match(/^datasquirel$/)) {
                let newUserSchemaFolderPath = `${process.env.DSQL_USER_DB_SCHEMA_PATH}/user-${newUser.insertId}`;

                let newUserMediaFolderPath = path.join(
                    STATIC_ROOT,
                    `images/user-images/user-${newUser.insertId}`
                );

                fs.mkdirSync(newUserSchemaFolderPath);
                fs.mkdirSync(newUserMediaFolderPath);

                fs.writeFileSync(
                    `${newUserSchemaFolderPath}/main.json`,
                    JSON.stringify([]),
                    "utf8"
                );
            }

            return await loginSocialUser({
                user: newUserQueried[0],
                social_platform,
                invitation,
                database,
                additionalFields,
                useLocal,
            });
        } else {
            console.log(
                "Social User Failed to insert in 'handleSocialDb.js' backend function =>",
                newUser
            );

            return {
                success: false,
                payload: null,
                msg: "Social User Failed to insert in 'handleSocialDb.js' backend function",
            };
        }
    } catch (/** @type {any} */ error) {
        console.log(
            "ERROR in 'handleSocialDb.js' backend function =>",
            error.message
        );

        return {
            success: false,
            payload: null,
            msg: error.message,
        };
    }
};
