import { sql } from "drizzle-orm";
import { drizzle } from "drizzle-orm/postgres-js";
import { migrate } from "drizzle-orm/postgres-js/migrator";
import postgres from "postgres";
import * as schema from "../src/db/schema";

const DATABASE_URL =
	process.env.DATABASE_URL ||
	"postgresql://gearbox:gearbox@localhost:5432/gearbox";

export async function seedTestDatabase() {
	const client = postgres(DATABASE_URL, { max: 1 });
	const db = drizzle(client, { schema });

	// Run migrations
	await migrate(db, { migrationsFolder: "./drizzle-pg" });

	// Clean all tables for a fresh seed
	const tables = [
		"setup_items",
		"setups",
		"thread_candidates",
		"threads",
		"items",
		"global_item_tags",
		"global_items",
		"tags",
		"oauth_tokens",
		"oauth_codes",
		"oauth_clients",
		"api_keys",
		"settings",
		"categories",
		"users",
	];
	for (const t of tables) {
		await db.execute(sql.raw(`TRUNCATE TABLE "${t}" RESTART IDENTITY CASCADE`));
	}

	// ── User ──
	const [user] = await db
		.insert(schema.users)
		.values({ logtoSub: "e2e-test-user" })
		.returning();
	const userId = user.id;

	// ── Categories ──
	const [uncategorized] = await db
		.insert(schema.categories)
		.values({ name: "Uncategorized", icon: "package", userId })
		.returning();

	const [shelter] = await db
		.insert(schema.categories)
		.values({ name: "Shelter", icon: "tent", userId })
		.returning();

	const [sleep] = await db
		.insert(schema.categories)
		.values({ name: "Sleep System", icon: "moon", userId })
		.returning();

	const [cook] = await db
		.insert(schema.categories)
		.values({ name: "Cook Kit", icon: "flame", userId })
		.returning();

	// ── Items ──
	const [tent] = await db
		.insert(schema.items)
		.values({
			name: "Zpacks Duplex",
			weightGrams: 539,
			priceCents: 67900,
			categoryId: shelter.id,
			userId,
			notes: "DCF shelter, 2-person",
		})
		.returning();

	await db.insert(schema.items).values({
		name: "Borah Gear Tarp",
		weightGrams: 156,
		priceCents: 11000,
		categoryId: shelter.id,
		userId,
	});

	const [quilt] = await db
		.insert(schema.items)
		.values({
			name: "Enlightened Equipment Enigma 20",
			weightGrams: 595,
			priceCents: 34000,
			categoryId: sleep.id,
			userId,
			notes: "20F quilt",
		})
		.returning();

	const [pad] = await db
		.insert(schema.items)
		.values({
			name: "Therm-a-Rest NeoAir XLite",
			weightGrams: 354,
			priceCents: 20999,
			categoryId: sleep.id,
			userId,
		})
		.returning();

	const [stove] = await db
		.insert(schema.items)
		.values({
			name: "BRS-3000T Stove",
			weightGrams: 25,
			priceCents: 2000,
			categoryId: cook.id,
			userId,
		})
		.returning();

	await db.insert(schema.items).values({
		name: "Toaks 750ml Pot",
		weightGrams: 103,
		priceCents: 3000,
		categoryId: cook.id,
		userId,
	});

	// ── Active Thread with 3 Candidates ──
	const [activeThread] = await db
		.insert(schema.threads)
		.values({
			name: "New Backpack",
			status: "active",
			categoryId: uncategorized.id,
			userId,
		})
		.returning();

	await db.insert(schema.threadCandidates).values({
		threadId: activeThread.id,
		name: "ULA Circuit",
		weightGrams: 1077,
		priceCents: 27500,
		categoryId: uncategorized.id,
		pros: "Great hip belt\nLarge capacity",
		cons: "Heavier than competitors",
		sortOrder: 1000,
		status: "researching",
	});

	await db.insert(schema.threadCandidates).values({
		threadId: activeThread.id,
		name: "Gossamer Gear Mariposa",
		weightGrams: 737,
		priceCents: 28500,
		categoryId: uncategorized.id,
		pros: "Very lightweight\nGood ventilation",
		cons: "Smaller hip belt pockets",
		sortOrder: 2000,
		status: "researching",
	});

	await db.insert(schema.threadCandidates).values({
		threadId: activeThread.id,
		name: "Granite Gear Crown2 38",
		weightGrams: 850,
		priceCents: 18000,
		categoryId: uncategorized.id,
		sortOrder: 3000,
		status: "ordered",
	});

	// ── Resolved Thread ──
	const [resolvedThread] = await db
		.insert(schema.threads)
		.values({
			name: "Camp Stove",
			status: "resolved",
			categoryId: cook.id,
			userId,
			resolvedCandidateId: 1,
		})
		.returning();

	await db.insert(schema.threadCandidates).values({
		threadId: resolvedThread.id,
		name: "BRS-3000T",
		weightGrams: 25,
		priceCents: 2000,
		categoryId: cook.id,
		sortOrder: 1000,
		status: "arrived",
	});

	// ── Setup with Items ──
	const [setup] = await db
		.insert(schema.setups)
		.values({ name: "Weekend Overnighter", userId })
		.returning();

	await db.insert(schema.setupItems).values([
		{ setupId: setup.id, itemId: tent.id, classification: "base" },
		{ setupId: setup.id, itemId: quilt.id, classification: "base" },
		{ setupId: setup.id, itemId: pad.id, classification: "base" },
		{ setupId: setup.id, itemId: stove.id, classification: "consumable" },
	]);

	// ── API Key for E2E Authentication ──
	const rawKey = "e2e-test-api-key-for-gearbox-testing";
	const keyHash = await Bun.password.hash(rawKey);
	const keyPrefix = rawKey.slice(0, 8);
	await db
		.insert(schema.apiKeys)
		.values({ name: "E2E Test Key", keyHash, keyPrefix, userId });

	// ── Settings ──
	await db.insert(schema.settings).values([
		{ key: "weightUnit", value: "g", userId },
		{ key: "currency", value: "USD", userId },
		{ key: "onboardingComplete", value: "true", userId },
	]);

	await client.end();
	console.log("E2E test database seeded via", DATABASE_URL);
}
