import { UserRoleMap } from "@pkg/logic/domains/user/data";
import { auth } from "@pkg/logic/domains/auth/config.base";
import { account, user } from "@pkg/db/schema/better.auth.schema";
import type { RequestHandler } from "./$types";
import { settings } from "@pkg/settings";
import { logger } from "@pkg/logger";
import { db, eq, or } from "@pkg/db";
import { nanoid } from "nanoid";
import * as v from "valibot";

function isAuthorized(authHeader?: string | null) {
    if (!authHeader) return false;
    const authToken = authHeader.toString().replace("Bearer ", "");
    return authToken === settings.debugKey;
}

export const GET: RequestHandler = async ({ request }) => {
    if (!isAuthorized(request.headers.get("Authorization"))) {
        return new Response("Unauthorized", { status: 401 });
    }
    const users = await db.query.user.findMany({});
    return new Response(JSON.stringify({ users }), { status: 200 });
};

export const PUT: RequestHandler = async ({ request }) => {
    if (!isAuthorized(request.headers.get("Authorization"))) {
        return new Response("Unauthorized", { status: 401 });
    }

    const data = await request.json();

    if (!data.username) {
        return new Response("Invalid data", { status: 400 });
    }

    await db
        .update(user)
        .set({ role: UserRoleMap.admin })
        .where(eq(user.username, data.username))
        .execute();

    return new Response("Not implemented", { status: 200 });
};

export const POST: RequestHandler = async ({ request }) => {
    if (!isAuthorized(request.headers.get("Authorization"))) {
        return new Response("Unauthorized", { status: 401 });
    }
    const data = await request.json();
    const _schema = v.object({
        username: v.string(),
        password: v.pipe(v.string(), v.minLength(6)),
        email: v.optional(v.string()),
        usertype: v.optional(v.enum(UserRoleMap)),
    });
    const res = v.safeParse(_schema, data);
    if (!res.success) {
        return new Response("Invalid data", { status: 400 });
    }
    const resData = res.output;
    const email = resData.email ?? `${resData.username}@debug.local`;
    const usertype = resData.usertype ?? UserRoleMap.admin;

    const existingUser = await db.query.user
        .findFirst({
            where: or(eq(user.username, resData.username), eq(user.email, email)),
            columns: { id: true },
        })
        .execute();

    if (existingUser?.id) {
        return new Response("User already exists", { status: 409 });
    }

    logger.info(
        `Creating debug user ${resData.username} | ${email} (${usertype})`,
    );

    const userId = nanoid();
    const accountId = nanoid();
    const hashedPassword = await auth.$context.then((ctx) =>
        ctx.password.hash(resData.password),
    );

    await db.transaction(async (tx) => {
        await tx
            .insert(user)
            .values({
                id: userId,
                username: resData.username,
                email,
                emailVerified: true,
                name: resData.username,
                role: usertype,
                createdAt: new Date(),
                updatedAt: new Date(),
            })
            .execute();

        await tx
            .insert(account)
            .values({
                id: accountId,
                accountId: userId,
                providerId: "credential",
                userId,
                password: hashedPassword,
                createdAt: new Date(),
                updatedAt: new Date(),
            })
            .execute();
    });

    logger.info("Debug user created with credential account", {
        userId,
        username: resData.username,
        email,
    });

    return new Response(
        JSON.stringify({
            id: userId,
            username: resData.username,
            email,
            role: usertype,
        }),
        { status: 200 },
    );
};
