import { NextApiRequest } from "next";
import { User } from "../types";
import { IncomingMessage } from "http";
import { getCookie } from "./cookies-actions";
import { APIResponseObject } from "@moduletrace/datasquirel/dist/package-shared/types";
import decrypt from "@moduletrace/datasquirel/dist/package-shared/functions/dsql/decrypt";
import { EJSON } from "../exports/client-exports";
import grabCookieNames from "./grab-cookie-names";

type Params = {
    req?:
        | NextApiRequest
        | (IncomingMessage & { cookies: Partial<{ [key: string]: string }> });
    bun_req?: Request;
};

export default async function userAuth({
    req,
    bun_req,
}: Params): Promise<APIResponseObject<User>> {
    try {
        const { auth_key_cookie_name, csrf_cookie_name } = grabCookieNames();
        const cookie_string =
            req?.headers.cookie || bun_req?.headers.get("cookie");

        if (!cookie_string) {
            return {
                success: false,
                msg: `Couldn't grab cookie string`,
            };
        }
        const key = getCookie(cookie_string, auth_key_cookie_name);

        if (!key) {
            return {
                success: false,
                msg: `No ${auth_key_cookie_name} found in request object.`,
            };
        }

        const decrypted_key = decrypt({ encryptedString: key });
        const decrypted_object = EJSON.parse(decrypted_key) as User | undefined;

        if (!decrypted_object?.id) {
            return {
                success: false,
                msg: `Invalid Auth Key`,
            };
        }

        const csrf = getCookie(cookie_string, csrf_cookie_name);

        if (!csrf) {
            return {
                success: false,
                msg: `No ${csrf_cookie_name} found in request object.`,
            };
        }

        if (csrf !== decrypted_object.csrf_k) {
            return {
                success: false,
                msg: `CSRF mismatch`,
            };
        }

        return {
            success: true,
            singleRes: decrypted_object,
        };
    } catch (error) {
        return { success: false };
    }
}
