import { NextApiRequest, NextApiResponse } from "next";
import { IncomingMessage, ServerResponse } from "http";
import NSQLite from "@moduletrace/nsqlite";
import { NSQLITE_TURBOCI_ADMIN_USERS, NSQLiteTables } from "../../db/types";
import { User } from "../../types";
import { setCookie } from "../../utils/cookies-actions";
import { EJSON } from "../../exports/client-exports";
import encrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/encrypt";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword";
import dayjs from "dayjs";
import grabCookieNames from "../../utils/grab-cookie-names";

type Params = {
    req: NextApiRequest | IncomingMessage;
    res: NextApiResponse | ServerResponse;
    user_id?: string | number;
    password?: string;
    email_or_username?: string;
};

export default async function loginUser({
    req,
    res,
    user_id,
    password,
    email_or_username,
}: Params): Promise<APIResponseObject> {
    let fetched_user: NSQLITE_TURBOCI_ADMIN_USERS | undefined;

    if (user_id) {
        const user_res = await NSQLite.select<
            NSQLITE_TURBOCI_ADMIN_USERS,
            (typeof NSQLiteTables)[number]
        >({
            table: "users",
            targetId: user_id,
        });

        if (!user_res.singleRes?.id) {
            throw new Error(`Couldn't Find user for login`);
        }

        fetched_user = user_res.singleRes;
    }

    if (email_or_username) {
        const user_res = await NSQLite.select<
            NSQLITE_TURBOCI_ADMIN_USERS,
            (typeof NSQLiteTables)[number]
        >({
            table: "users",
            query: {
                query: {
                    email: {
                        value: email_or_username,
                    },
                    username: {
                        value: email_or_username,
                    },
                },
                searchOperator: "OR",
            },
        });

        if (!user_res.singleRes?.id) {
            throw new Error(`Couldn't Find user for login`);
        }

        fetched_user = user_res.singleRes;
    }

    if (!fetched_user) {
        return {
            success: false,
            msg: `User Not Found!`,
        };
    }

    if (password) {
        const hashed_password = hashPassword({ password });

        if (hashed_password !== fetched_user.password) {
            return {
                success: false,
                msg: `Invalid Password.`,
            };
        }
    }

    const now = Date.now();

    const csrf_k =
        Math.random().toString(36).substring(2) +
        "-" +
        Math.random().toString(36).substring(2);

    const logged_in_user_payload: User = {
        first_name: fetched_user.first_name!,
        last_name: fetched_user.last_name!,
        date: now,
        email: fetched_user.email!,
        csrf_k,
        id: fetched_user.id!,
        logged_in_status: true,
        image: fetched_user.image,
        image_thumbnail: fetched_user.image,
        super_admin: fetched_user.is_super_admin ? true : false,
    };

    const payload_string = EJSON.stringify(logged_in_user_payload);
    const encrypted_payload = encrypt({ data: payload_string || "" });

    const expiration_date = dayjs(Date.now()).add(7, "days");
    expiration_date.add(7, "days");

    const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();

    const host = req.headers.host;

    setCookie(res, [
        {
            name: auth_key_cookie_name,
            value: encrypted_payload || "",
            options: {
                secure: host !== "localhost",
                path: "/",
                expires: expiration_date,
                domain: host,
            },
        },
        {
            name: csrf_cookie_name,
            value: csrf_k,
            options: {
                path: "/",
                expires: expiration_date,
                domain: host,
            },
        },
    ]);

    return {
        success: true,
        singleRes: logged_in_user_payload,
    };
}
