import { and, asc, eq } from "drizzle-orm";
import type { db as prodDb } from "../../db/index.ts";
import { categories, items } from "../../db/schema.ts";

type Db = typeof prodDb;

export async function getOrCreateUncategorized(db: Db, userId: number) {
	const [existing] = await db
		.select()
		.from(categories)
		.where(
			and(eq(categories.userId, userId), eq(categories.name, "Uncategorized")),
		);
	if (existing) return existing;

	const [created] = await db
		.insert(categories)
		.values({ name: "Uncategorized", icon: "package", userId })
		.returning();
	return created;
}

export async function getAllCategories(db: Db, userId: number) {
	return db
		.select()
		.from(categories)
		.where(eq(categories.userId, userId))
		.orderBy(asc(categories.name));
}

export async function createCategory(
	db: Db,
	userId: number,
	data: { name: string; icon?: string },
) {
	const [row] = await db
		.insert(categories)
		.values({
			name: data.name,
			userId,
			...(data.icon ? { icon: data.icon } : {}),
		})
		.returning();
	return row;
}

export async function updateCategory(
	db: Db,
	userId: number,
	id: number,
	data: { name?: string; icon?: string },
) {
	const [existing] = await db
		.select({ id: categories.id })
		.from(categories)
		.where(and(eq(categories.id, id), eq(categories.userId, userId)));

	if (!existing) return null;

	const [row] = await db
		.update(categories)
		.set(data)
		.where(and(eq(categories.id, id), eq(categories.userId, userId)))
		.returning();
	return row;
}

export async function deleteCategory(
	db: Db,
	userId: number,
	id: number,
): Promise<{ success: boolean; error?: string }> {
	// Check if category exists and belongs to user
	const [existing] = await db
		.select({ id: categories.id, name: categories.name })
		.from(categories)
		.where(and(eq(categories.id, id), eq(categories.userId, userId)));

	if (!existing) {
		return { success: false, error: "Category not found" };
	}

	// Guard: cannot delete Uncategorized
	if (existing.name === "Uncategorized") {
		return {
			success: false,
			error: "Cannot delete the Uncategorized category",
		};
	}

	// Get the user's Uncategorized category for reassignment
	const uncategorized = await getOrCreateUncategorized(db, userId);

	// Reassign items to Uncategorized, then delete atomically
	await db.transaction(async (tx) => {
		await tx
			.update(items)
			.set({ categoryId: uncategorized.id })
			.where(eq(items.categoryId, id));

		await tx.delete(categories).where(eq(categories.id, id));
	});

	return { success: true };
}
