"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = apiSendEmailCode;
const varDatabaseDbHandler_1 = __importDefault(require("../../backend/varDatabaseDbHandler"));
const nodemailer_1 = __importDefault(require("nodemailer"));
const get_auth_cookie_names_1 = __importDefault(require("../../backend/cookies/get-auth-cookie-names"));
const encrypt_1 = __importDefault(require("../../dsql/encrypt"));
const serialize_cookies_1 = __importDefault(require("../../../utils/serialize-cookies"));
/**
 * # Send Email Login Code
 */
function apiSendEmailCode(_a) {
    return __awaiter(this, arguments, void 0, function* ({ email, database, email_login_field, mail_domain, mail_port, sender, mail_username, mail_password, html, useLocal, response, extraCookies, }) {
        if (email === null || email === void 0 ? void 0 : email.match(/ /)) {
            return {
                success: false,
                msg: "Invalid Email/Password format",
            };
        }
        const createdAt = Date.now();
        const foundUserQuery = `SELECT * FROM ${database}.users WHERE email = ?`;
        const foundUserValues = [email];
        let foundUser = yield (0, varDatabaseDbHandler_1.default)({
            queryString: foundUserQuery,
            queryValuesArray: foundUserValues,
            database,
            useLocal,
        });
        ////////////////////////////////////////
        ////////////////////////////////////////
        ////////////////////////////////////////
        if (!foundUser || !foundUser[0]) {
            return {
                success: false,
                msg: "No user found",
            };
        }
        function generateCode() {
            const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            let code = "";
            for (let i = 0; i < 8; i++) {
                code += chars[Math.floor(Math.random() * chars.length)];
            }
            return code;
        }
        if ((foundUser === null || foundUser === void 0 ? void 0 : foundUser[0]) && email_login_field) {
            const tempCode = generateCode();
            let transporter = nodemailer_1.default.createTransport({
                host: mail_domain || process.env.DSQL_MAIL_HOST,
                port: mail_port
                    ? mail_port
                    : process.env.DSQL_MAIL_PORT
                        ? Number(process.env.DSQL_MAIL_PORT)
                        : 465,
                secure: true,
                auth: {
                    user: mail_username || process.env.DSQL_MAIL_EMAIL,
                    pass: mail_password || process.env.DSQL_MAIL_PASSWORD,
                },
            });
            let mailObject = {};
            mailObject["from"] = `"Datasquirel SSO" <${sender || "support@datasquirel.com"}>`;
            mailObject["sender"] = sender || "support@datasquirel.com";
            mailObject["to"] = email;
            mailObject["subject"] = "One Time Login Code";
            mailObject["html"] = html.replace(/{{code}}/, tempCode);
            const info = yield transporter.sendMail(mailObject);
            if (!(info === null || info === void 0 ? void 0 : info.accepted))
                throw new Error("Mail not Sent!");
            const setTempCodeQuery = `UPDATE ${database}.users SET ${email_login_field} = ? WHERE email = ?`;
            const setTempCodeValues = [tempCode + `-${createdAt}`, email];
            let setTempCode = yield (0, varDatabaseDbHandler_1.default)({
                queryString: setTempCodeQuery,
                queryValuesArray: setTempCodeValues,
                database,
                useLocal,
            });
            /** @type {import("../../../types").SendOneTimeCodeEmailResponse} */
            const resObject = {
                success: true,
                code: tempCode,
                email: email,
                createdAt,
                msg: "Success",
            };
            if (response) {
                const cookieKeyNames = (0, get_auth_cookie_names_1.default)();
                const oneTimeCodeCookieName = cookieKeyNames.oneTimeCodeName;
                const encryptedPayload = (0, encrypt_1.default)({
                    data: JSON.stringify(resObject),
                });
                if (!encryptedPayload) {
                    throw new Error("apiSendEmailCode Error: Failed to encrypt payload");
                }
                /** @type {import("../../../../package-shared/types").CookieObject} */
                const oneTimeCookieObject = {
                    name: oneTimeCodeCookieName,
                    value: encryptedPayload,
                    sameSite: "Strict",
                    path: "/",
                    httpOnly: true,
                    secure: true,
                };
                /** @type {import("../../../../package-shared/types").CookieObject[]} */
                const cookiesObjectArray = extraCookies
                    ? [...extraCookies, oneTimeCookieObject]
                    : [oneTimeCookieObject];
                const serializedCookies = (0, serialize_cookies_1.default)({
                    cookies: cookiesObjectArray,
                });
                response.setHeader("Set-Cookie", serializedCookies);
            }
            return resObject;
        }
        else {
            return {
                success: false,
                msg: "Invalid Email/Password format",
            };
        }
    });
}