import { NSQLITE_TURBOCI_ADMIN_USERS, NSQLiteTables } from "@/src/db/types";
import { APIReqObject } from "@/src/types";
import loginUser from "@/src/functions/auth/login-user";
import hashPassword from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/hashPassword";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import NSQLite from "@moduletrace/nsqlite";
import type { NextApiRequest, NextApiResponse } from "next";
import userAuth from "@/src/utils/user-auth";
import { slugify } from "@/src/exports/client-exports";
import setupDeploymentUser from "@/src/functions/deployment-users/setup-deployment-user";

export default async function handler(
    req: NextApiRequest,
    res: NextApiResponse<APIResponseObject>,
) {
    try {
        const { singleRes: user } = await userAuth({ req });

        if (req.method !== "POST") {
            return res.json({
                success: false,
                msg: `Wrong Method`,
            });
        }

        const { new_user } = req.body as APIReqObject;

        if (user?.id && !new_user?.username?.match(/^[a-z0-9\-]{3,}$/)) {
            throw new Error(`Please pass a valid username`);
        }

        if (!new_user) {
            throw new Error(`No new User Object Passed!`);
        }

        if (!new_user.password) {
            throw new Error(`New User Password is required.`);
        }

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

        if (existing_users_res.payload?.[0]?.id && !user?.id) {
            return res.json({
                success: false,
                msg: `Super Admin User already exists. Other Users can be created by this user.`,
            });
        }

        if (user?.id && !user.super_admin) {
            return res.json({
                success: false,
                msg: `Operation not allowed!`,
            });
        }

        const { first_name, email, last_name, password, username } = new_user;

        const new_user_password = hashPassword({ password });

        const new_user_insert_res = await NSQLite.insert<
            NSQLITE_TURBOCI_ADMIN_USERS,
            (typeof NSQLiteTables)[number]
        >({
            data: [
                {
                    first_name,
                    last_name,
                    email,
                    password: new_user_password,
                    is_super_admin: user?.id ? 0 : 1,
                    username: username ? slugify(username) : undefined,
                },
            ],
            table: "users",
        });

        const new_user_id = new_user_insert_res.postInsertReturn?.insertId;

        if (!new_user_id) {
            throw new Error(`Couldn't create New User.`);
        }

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

        const newly_inserted_user = newly_inserted_user_res.singleRes;

        if (!newly_inserted_user?.id) {
            console.log("newly_inserted_user_res", newly_inserted_user_res);
            throw new Error(`Couldn't Find Newly inserted user.`);
        }

        if (user?.id && !newly_inserted_user.username) {
            const newly_inserted_user_res = await NSQLite.delete<
                NSQLITE_TURBOCI_ADMIN_USERS,
                (typeof NSQLiteTables)[number]
            >({
                table: "users",
                targetId: newly_inserted_user?.id,
            });

            throw new Error(`Couldn't set Newly inserted user username.`);
        }

        if (user?.id) {
            console.log("newly_inserted_user", newly_inserted_user);

            await setupDeploymentUser({ user_id: newly_inserted_user.id });

            return res.json({
                success: true,
                singleRes: newly_inserted_user,
            });
        } else {
            const logged_in_user = await loginUser({
                res,
                user_id: newly_inserted_user.id,
                req,
            });

            return res.json(logged_in_user);
        }
    } catch (error: any) {
        return res.json({
            success: false,
            msg: error.message,
        });
    }
}
