import { APIError } from "better-auth";
import { count, eq, sql } from "drizzle-orm";
import { Router } from "express";
import z from "zod";
import { db } from "../db/db.controller.js";
import { user } from "../db/schema/auth.schema.js";
import { auth } from "../utils/auth.utils.js";
import { apiReturn } from "../utils/returnHelper.utils.js";

const r = Router();

const registerSchema = z.object({
	email: z.email(),
	name: z.string().min(2).max(100),
	password: z.string().min(8, "Password must be at least 8 characters"),
	username: z
		.string()
		.min(3)
		.max(32)
		.regex(/^[a-zA-Z0-9._]+$/, "Only alphanumeric, _, and ."),
	displayUsername: z
		.string()
		.min(2)
		.max(100)
		.optional()
		.describe("if you leave blank it will be the same as your username"),
	role: z
		.enum(["user"])
		.optional()
		.describe("What roles are available to use."),
	data: z
		.record(z.string(), z.unknown())
		.optional()
		.describe(
			"This allows us to add extra fields to the data to parse against",
		),
});

r.post("/", async (req, res) => {
	// check if we are the first user so we can add as system admin to all modules
	const totalUsers = await db.select({ count: count() }).from(user);
	const userCount = totalUsers[0]?.count ?? 0;
	try {
		// validate the body is correct before accepting it
		let validated = registerSchema.parse(req.body);

		validated = {
			...validated,
			data: { lastLogin: new Date(Date.now()) },
			username: validated.username,
		};

		// Call Better Auth signUp
		const newUser = await auth.api.signUpEmail({
			body: validated,
		});

		// if we have no users yet lets make this new one the admin
		if (userCount === 0) {
			// make this user an admin
			await db
				.update(user)
				.set({ role: "admin", updatedAt: sql`NOW()` })
				.where(eq(user.id, newUser.user.id));
		}

		apiReturn(res, {
			success: true,
			level: "info", //connect.success ? "info" : "error",
			module: "routes",
			subModule: "auth",
			message: `${validated.username} was just created`,
			data: [newUser],
			status: 200, //connect.success ? 200 : 400,
		});
	} catch (err) {
		if (err instanceof z.ZodError) {
			const flattened = z.flattenError(err);
			// return res.status(400).json({
			// 	error: "Validation failed",
			// 	details: flattened,
			// });

			return apiReturn(res, {
				success: false,
				level: "error", //connect.success ? "info" : "error",
				module: "routes",
				subModule: "auth",
				message: "Validation failed",
				data: [flattened.fieldErrors],
				status: 400, //connect.success ? 200 : 400,
			});
		}

		if (err instanceof APIError) {
			return apiReturn(res, {
				success: false,
				level: "error", //connect.success ? "info" : "error",
				module: "routes",
				subModule: "auth",
				message: err.message,
				data: [err.status],
				status: 400, //connect.success ? 200 : 400,
			});
		}

		return apiReturn(res, {
			success: false,
			level: "error", //connect.success ? "info" : "error",
			module: "routes",
			subModule: "auth",
			message: "Internal Server Error creating user",
			data: [err],
			status: 400, //connect.success ? 200 : 400,
		});
	}

	// apiReturn(res, {
	// 	success: true,
	// 	level: "info", //connect.success ? "info" : "error",
	// 	module: "routes",
	// 	subModule: "auth",
	// 	message: "Testing route",
	// 	data: [],
	// 	status: 200, //connect.success ? 200 : 400,
	// });
});
export default r;
