import type { Kysely } from "kysely";
import { describe, it, expect, beforeEach, afterEach } from "vitest";

import { BylineRepository } from "../../../src/database/repositories/byline.js";
import { ContentRepository } from "../../../src/database/repositories/content.js";
import { RedirectRepository } from "../../../src/database/repositories/redirect.js";
import { TaxonomyRepository } from "../../../src/database/repositories/taxonomy.js";
import type { Database } from "../../../src/database/types.js";
import { SchemaRegistry } from "../../../src/schema/registry.js";
import { applySeed } from "../../../src/seed/apply.js";
import type { SeedFile } from "../../../src/seed/types.js";
import { setupTestDatabase, teardownTestDatabase } from "../../utils/test-db.js";

describe("applySeed", () => {
	let db: Kysely<Database>;

	beforeEach(async () => {
		db = await setupTestDatabase();
	});

	afterEach(async () => {
		await teardownTestDatabase(db);
	});

	describe("validation", () => {
		it("should reject invalid seed file", async () => {
			const invalidSeed = { version: "99" } as SeedFile;

			await expect(applySeed(db, invalidSeed)).rejects.toThrow("Invalid seed file");
		});

		it("should accept minimal valid seed", async () => {
			const seed: SeedFile = { version: "1" };

			const result = await applySeed(db, seed);

			expect(result.collections.created).toBe(0);
			expect(result.settings.applied).toBe(0);
		});
	});

	describe("settings", () => {
		it("should apply site settings", async () => {
			const seed: SeedFile = {
				version: "1",
				settings: {
					siteTitle: "Test Site",
					tagline: "A test site",
				},
			};

			const result = await applySeed(db, seed);

			expect(result.settings.applied).toBe(2);

			// Verify settings were saved
			const row = await db
				.selectFrom("options")
				.selectAll()
				.where("name", "=", "site:siteTitle")
				.executeTakeFirst();

			expect(row?.value).toBe('"Test Site"');
		});
	});

	describe("collections", () => {
		it("should create collections and fields", async () => {
			const seed: SeedFile = {
				version: "1",
				collections: [
					{
						slug: "posts",
						label: "Posts",
						labelSingular: "Post",
						fields: [
							{ slug: "title", label: "Title", type: "string", required: true },
							{ slug: "content", label: "Content", type: "portableText" },
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.collections.created).toBe(1);
			expect(result.fields.created).toBe(2);

			// Verify collection exists
			const registry = new SchemaRegistry(db);
			const collection = await registry.getCollection("posts");
			expect(collection).not.toBeNull();
			expect(collection?.label).toBe("Posts");
		});

		it("should skip existing collections", async () => {
			// Create collection first
			const registry = new SchemaRegistry(db);
			await registry.createCollection({
				slug: "posts",
				label: "Existing Posts",
			});

			const seed: SeedFile = {
				version: "1",
				collections: [
					{
						slug: "posts",
						label: "New Posts",
						fields: [{ slug: "title", label: "Title", type: "string" }],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.collections.created).toBe(0);
			expect(result.collections.skipped).toBe(1);
			expect(result.fields.skipped).toBe(1);

			// Original label should be preserved
			const collection = await registry.getCollection("posts");
			expect(collection?.label).toBe("Existing Posts");
		});

		it("should create multiple collections", async () => {
			const seed: SeedFile = {
				version: "1",
				collections: [
					{ slug: "posts", label: "Posts", fields: [] },
					{ slug: "pages", label: "Pages", fields: [] },
					{ slug: "products", label: "Products", fields: [] },
				],
			};

			const result = await applySeed(db, seed);

			expect(result.collections.created).toBe(3);
		});
	});

	describe("taxonomies", () => {
		it("should create taxonomy definitions", async () => {
			const seed: SeedFile = {
				version: "1",
				taxonomies: [
					{
						name: "topics",
						label: "Topics",
						hierarchical: true,
						collections: ["posts"],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.taxonomies.created).toBe(1);

			// Verify taxonomy exists
			const row = await db
				.selectFrom("_emdash_taxonomy_defs")
				.selectAll()
				.where("name", "=", "topics")
				.executeTakeFirst();

			expect(row).not.toBeNull();
			expect(row?.label).toBe("Topics");
			expect(row?.hierarchical).toBe(1);
		});

		it("should create flat taxonomy terms", async () => {
			const seed: SeedFile = {
				version: "1",
				taxonomies: [
					{
						name: "tags",
						label: "Tags",
						hierarchical: false,
						collections: ["posts"],
						terms: [
							{ slug: "javascript", label: "JavaScript" },
							{ slug: "typescript", label: "TypeScript" },
							{ slug: "rust", label: "Rust" },
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.taxonomies.created).toBe(1);
			expect(result.taxonomies.terms).toBe(3);
		});

		it("should create hierarchical taxonomy terms with parents", async () => {
			const seed: SeedFile = {
				version: "1",
				taxonomies: [
					{
						name: "topics",
						label: "Topics",
						hierarchical: true,
						collections: ["posts"],
						terms: [
							{ slug: "tech", label: "Technology" },
							{ slug: "web", label: "Web Development", parent: "tech" },
							{ slug: "mobile", label: "Mobile Development", parent: "tech" },
							{ slug: "react", label: "React", parent: "web" },
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.taxonomies.terms).toBe(4);

			// Verify parent-child relationship
			const termRepo = new TaxonomyRepository(db);
			const webTerm = await termRepo.findBySlug("topics", "web");
			const techTerm = await termRepo.findBySlug("topics", "tech");

			expect(webTerm?.parentId).toBe(techTerm?.id);
		});

		it("should skip existing terms", async () => {
			// Create taxonomy and term first
			await db
				.insertInto("_emdash_taxonomy_defs")
				.values({
					id: "def-1",
					name: "tags",
					label: "Tags",
					hierarchical: 0,
					collections: JSON.stringify(["posts"]),
				})
				.execute();

			const termRepo = new TaxonomyRepository(db);
			await termRepo.create({
				name: "tags",
				slug: "javascript",
				label: "Existing JS",
			});

			const seed: SeedFile = {
				version: "1",
				taxonomies: [
					{
						name: "tags",
						label: "Tags",
						hierarchical: false,
						collections: ["posts"],
						terms: [
							{ slug: "javascript", label: "New JavaScript" },
							{ slug: "typescript", label: "TypeScript" },
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			// Definition already exists, so not created
			expect(result.taxonomies.created).toBe(0);
			// Only typescript is new
			expect(result.taxonomies.terms).toBe(1);

			// Original label should be preserved
			const term = await termRepo.findBySlug("tags", "javascript");
			expect(term?.label).toBe("Existing JS");
		});
	});

	describe("menus", () => {
		it("should create menus with items", async () => {
			const seed: SeedFile = {
				version: "1",
				menus: [
					{
						name: "main",
						label: "Main Navigation",
						items: [
							{ type: "custom", label: "Home", url: "/" },
							{ type: "custom", label: "About", url: "/about" },
							{ type: "custom", label: "Contact", url: "/contact" },
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.menus.created).toBe(1);
			expect(result.menus.items).toBe(3);

			// Verify menu exists
			const menu = await db
				.selectFrom("_emdash_menus")
				.selectAll()
				.where("name", "=", "main")
				.executeTakeFirst();

			expect(menu).not.toBeNull();
			expect(menu?.label).toBe("Main Navigation");
		});

		it("should create nested menu items", async () => {
			const seed: SeedFile = {
				version: "1",
				menus: [
					{
						name: "main",
						label: "Main",
						items: [
							{
								type: "custom",
								label: "Products",
								url: "/products",
								children: [
									{
										type: "custom",
										label: "Software",
										url: "/products/software",
									},
									{
										type: "custom",
										label: "Hardware",
										url: "/products/hardware",
									},
								],
							},
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.menus.items).toBe(3); // 1 parent + 2 children

			// Verify parent-child relationship
			const items = await db.selectFrom("_emdash_menu_items").selectAll().execute();

			const parent = items.find((i) => i.label === "Products");
			const child = items.find((i) => i.label === "Software");

			expect(child?.parent_id).toBe(parent?.id);
		});

		it("should replace items in existing menu", async () => {
			// Create menu with items first
			await db
				.insertInto("_emdash_menus")
				.values({
					id: "menu-1",
					name: "main",
					label: "Main",
					created_at: new Date().toISOString(),
					updated_at: new Date().toISOString(),
				})
				.execute();

			await db
				.insertInto("_emdash_menu_items")
				.values({
					id: "item-1",
					menu_id: "menu-1",
					parent_id: null,
					sort_order: 0,
					type: "custom",
					label: "Old Item",
					custom_url: "/old",
					created_at: new Date().toISOString(),
				})
				.execute();

			const seed: SeedFile = {
				version: "1",
				menus: [
					{
						name: "main",
						label: "Main",
						items: [{ type: "custom", label: "New Item", url: "/new" }],
					},
				],
			};

			const result = await applySeed(db, seed);

			// Menu not created (existed), but items are replaced
			expect(result.menus.created).toBe(0);
			expect(result.menus.items).toBe(1);

			// Old item should be gone
			const items = await db
				.selectFrom("_emdash_menu_items")
				.selectAll()
				.where("menu_id", "=", "menu-1")
				.execute();

			expect(items).toHaveLength(1);
			expect(items[0].label).toBe("New Item");
		});
	});

	describe("widget areas", () => {
		it("should create widget areas with widgets", async () => {
			const seed: SeedFile = {
				version: "1",
				widgetAreas: [
					{
						name: "sidebar",
						label: "Sidebar",
						description: "The main sidebar",
						widgets: [
							{
								type: "content",
								title: "About",
								content: [{ _type: "block", children: [{ text: "About us" }] }],
							},
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.widgetAreas.created).toBe(1);
			expect(result.widgetAreas.widgets).toBe(1);

			// Verify area exists
			const area = await db
				.selectFrom("_emdash_widget_areas")
				.selectAll()
				.where("name", "=", "sidebar")
				.executeTakeFirst();

			expect(area).not.toBeNull();
			expect(area?.description).toBe("The main sidebar");
		});

		it("should create menu widgets", async () => {
			const seed: SeedFile = {
				version: "1",
				widgetAreas: [
					{
						name: "footer",
						label: "Footer",
						widgets: [{ type: "menu", title: "Footer Nav", menuName: "footer-menu" }],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.widgetAreas.widgets).toBe(1);

			const widget = await db.selectFrom("_emdash_widgets").selectAll().executeTakeFirst();

			expect(widget?.type).toBe("menu");
			expect(widget?.menu_name).toBe("footer-menu");
		});

		it("should create component widgets", async () => {
			const seed: SeedFile = {
				version: "1",
				widgetAreas: [
					{
						name: "sidebar",
						label: "Sidebar",
						widgets: [
							{
								type: "component",
								componentId: "recent-posts",
								props: { count: 5, showDate: true },
							},
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.widgetAreas.widgets).toBe(1);

			const widget = await db.selectFrom("_emdash_widgets").selectAll().executeTakeFirst();

			expect(widget?.type).toBe("component");
			expect(widget?.component_id).toBe("recent-posts");
			expect(JSON.parse(widget?.component_props ?? "{}")).toEqual({
				count: 5,
				showDate: true,
			});
		});

		it("should replace widgets in existing area", async () => {
			// Create area with widget first
			await db
				.insertInto("_emdash_widget_areas")
				.values({
					id: "area-1",
					name: "sidebar",
					label: "Sidebar",
					description: null,
				})
				.execute();

			await db
				.insertInto("_emdash_widgets")
				.values({
					id: "widget-1",
					area_id: "area-1",
					sort_order: 0,
					type: "content",
					title: "Old Widget",
					content: null,
					menu_name: null,
					component_id: null,
					component_props: null,
				})
				.execute();

			const seed: SeedFile = {
				version: "1",
				widgetAreas: [
					{
						name: "sidebar",
						label: "Sidebar",
						widgets: [{ type: "content", title: "New Widget" }],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.widgetAreas.created).toBe(0);
			expect(result.widgetAreas.widgets).toBe(1);

			// Old widget should be gone
			const widgets = await db
				.selectFrom("_emdash_widgets")
				.selectAll()
				.where("area_id", "=", "area-1")
				.execute();

			expect(widgets).toHaveLength(1);
			expect(widgets[0]!.title).toBe("New Widget");
		});
	});

	describe("redirects", () => {
		it("should create redirects", async () => {
			const seed: SeedFile = {
				version: "1",
				redirects: [
					{ source: "/old-about", destination: "/about" },
					{
						source: "/temp",
						destination: "/new-temp",
						type: 302,
						enabled: false,
						groupName: "migration",
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.redirects.created).toBe(2);
			expect(result.redirects.skipped).toBe(0);

			const redirects = await db
				.selectFrom("_emdash_redirects")
				.selectAll()
				.orderBy("source", "asc")
				.execute();

			expect(redirects).toHaveLength(2);
			expect(redirects[0]!.source).toBe("/old-about");
			expect(redirects[0]!.destination).toBe("/about");
			expect(redirects[0]!.type).toBe(301);
			expect(redirects[0]!.enabled).toBe(1);
			expect(redirects[1]!.source).toBe("/temp");
			expect(redirects[1]!.type).toBe(302);
			expect(redirects[1]!.enabled).toBe(0);
			expect(redirects[1]!.group_name).toBe("migration");
		});

		it("should skip redirects when source already exists", async () => {
			const redirectRepo = new RedirectRepository(db);
			await redirectRepo.create({
				source: "/old-about",
				destination: "/existing-about",
			});

			const seed: SeedFile = {
				version: "1",
				redirects: [
					{ source: "/old-about", destination: "/about" },
					{ source: "/old-contact", destination: "/contact" },
				],
			};

			const result = await applySeed(db, seed);

			expect(result.redirects.created).toBe(1);
			expect(result.redirects.skipped).toBe(1);

			const existing = await redirectRepo.findBySource("/old-about");
			expect(existing?.destination).toBe("/existing-about");

			const created = await redirectRepo.findBySource("/old-contact");
			expect(created?.destination).toBe("/contact");
		});
	});

	describe("content", () => {
		it("should create bylines and assign ordered credits to content", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			const seed: SeedFile = {
				version: "1",
				bylines: [
					{ id: "editorial", slug: "editorial", displayName: "Editorial" },
					{ id: "guest", slug: "guest-writer", displayName: "Guest Writer", isGuest: true },
				],
				content: {
					posts: [
						{
							id: "post-1",
							slug: "hello",
							data: { title: "Hello World" },
							bylines: [{ byline: "editorial" }, { byline: "guest", roleLabel: "Guest essay" }],
						},
					],
				},
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.bylines.created).toBe(2);
			expect(result.content.created).toBe(1);

			const contentRepo = new ContentRepository(db);
			const bylineRepo = new BylineRepository(db);
			const entry = await contentRepo.findBySlug("posts", "hello");
			expect(entry).not.toBeNull();

			const credits = await bylineRepo.getContentBylines("posts", entry!.id);
			expect(credits).toHaveLength(2);
			expect(credits[0]?.byline.slug).toBe("editorial");
			expect(credits[1]?.byline.slug).toBe("guest-writer");
			expect(credits[1]?.roleLabel).toBe("Guest essay");
			expect(entry?.primaryBylineId).toBe(credits[0]?.byline.id);
		});

		it("should not create content by default", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			const seed: SeedFile = {
				version: "1",
				content: {
					posts: [{ id: "post-1", slug: "hello", data: { title: "Hello World" } }],
				},
			};

			const result = await applySeed(db, seed);

			expect(result.content.created).toBe(0);

			const contentRepo = new ContentRepository(db);
			const entries = await contentRepo.findMany("posts", {});
			expect(entries.items).toHaveLength(0);
		});

		it("should create content when includeContent is true", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			const seed: SeedFile = {
				version: "1",
				content: {
					posts: [
						{ id: "post-1", slug: "hello", data: { title: "Hello World" } },
						{ id: "post-2", slug: "goodbye", data: { title: "Goodbye World" } },
					],
				},
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.content.created).toBe(2);

			const contentRepo = new ContentRepository(db);
			const entry = await contentRepo.findBySlug("posts", "hello");
			expect(entry?.data.title).toBe("Hello World");
		});

		it("should skip existing content entries", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			const contentRepo = new ContentRepository(db);
			await contentRepo.create({
				type: "posts",
				slug: "hello",
				data: { title: "Existing" },
			});

			const seed: SeedFile = {
				version: "1",
				content: {
					posts: [
						{ id: "post-1", slug: "hello", data: { title: "New Title" } },
						{ id: "post-2", slug: "world", data: { title: "World" } },
					],
				},
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.content.created).toBe(1);
			expect(result.content.skipped).toBe(1);

			// Original should be preserved
			const entry = await contentRepo.findBySlug("posts", "hello");
			expect(entry?.data.title).toBe("Existing");
		});

		it("should resolve $ref: references between content", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});
			await registry.createField("posts", {
				slug: "related_post",
				label: "Related Post",
				type: "reference",
			});

			const seed: SeedFile = {
				version: "1",
				content: {
					posts: [
						{ id: "post-1", slug: "first", data: { title: "First" } },
						{
							id: "post-2",
							slug: "second",
							data: { title: "Second", related_post: "$ref:post-1" },
						},
					],
				},
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.content.created).toBe(2);

			const contentRepo = new ContentRepository(db);
			const first = await contentRepo.findBySlug("posts", "first");
			const second = await contentRepo.findBySlug("posts", "second");

			// The reference should be resolved to the real ID
			expect(second?.data.related_post).toBe(first?.id);
		});

		it("should assign taxonomy terms to content", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "posts", label: "Posts" });
			await registry.createField("posts", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			// Create taxonomy
			await db
				.insertInto("_emdash_taxonomy_defs")
				.values({
					id: "def-1",
					name: "tags",
					label: "Tags",
					hierarchical: 0,
					collections: JSON.stringify(["posts"]),
				})
				.execute();

			const termRepo = new TaxonomyRepository(db);
			await termRepo.create({ name: "tags", slug: "javascript", label: "JS" });
			await termRepo.create({ name: "tags", slug: "typescript", label: "TS" });

			const seed: SeedFile = {
				version: "1",
				content: {
					posts: [
						{
							id: "post-1",
							slug: "hello",
							data: { title: "Hello" },
							taxonomies: { tags: ["javascript", "typescript"] },
						},
					],
				},
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.content.created).toBe(1);

			// Check taxonomy assignments
			const contentRepo = new ContentRepository(db);
			const entry = await contentRepo.findBySlug("posts", "hello");

			const assignments = await db
				.selectFrom("content_taxonomies")
				.selectAll()
				.where("entry_id", "=", entry!.id)
				.execute();

			expect(assignments).toHaveLength(2);
		});
	});

	describe("apply order", () => {
		it("should create content before menus so refs resolve", async () => {
			const registry = new SchemaRegistry(db);
			await registry.createCollection({ slug: "pages", label: "Pages" });
			await registry.createField("pages", {
				slug: "title",
				label: "Title",
				type: "string",
			});

			const seed: SeedFile = {
				version: "1",
				content: {
					pages: [{ id: "about-page", slug: "about", data: { title: "About Us" } }],
				},
				menus: [
					{
						name: "main",
						label: "Main",
						items: [
							{
								type: "page",
								label: "About",
								ref: "about-page",
								collection: "pages",
							},
						],
					},
				],
			};

			const result = await applySeed(db, seed, { includeContent: true });

			expect(result.content.created).toBe(1);
			expect(result.menus.items).toBe(1);

			// Menu item should reference the content
			const contentRepo = new ContentRepository(db);
			const aboutPage = await contentRepo.findBySlug("pages", "about");

			const menuItem = await db.selectFrom("_emdash_menu_items").selectAll().executeTakeFirst();

			expect(menuItem?.reference_id).toBe(aboutPage?.id);
		});
	});

	describe("sections", () => {
		it("should create sections", async () => {
			const seed: SeedFile = {
				version: "1",
				sections: [
					{
						slug: "hero-centered",
						title: "Centered Hero",
						description: "A centered hero section",
						keywords: ["hero", "banner"],
						content: [
							{
								_type: "block",
								style: "h1",
								children: [{ _type: "span", text: "Welcome" }],
							},
						],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.sections.created).toBe(1);
			expect(result.sections.skipped).toBe(0);

			// Verify section exists
			const section = await db
				.selectFrom("_emdash_sections")
				.selectAll()
				.where("slug", "=", "hero-centered")
				.executeTakeFirst();

			expect(section).not.toBeNull();
			expect(section?.title).toBe("Centered Hero");
			expect(section?.description).toBe("A centered hero section");
			expect(section?.source).toBe("theme");
			expect(JSON.parse(section?.keywords ?? "[]")).toEqual(["hero", "banner"]);
		});

		it("should skip existing sections", async () => {
			// Create section first
			await db
				.insertInto("_emdash_sections")
				.values({
					id: "sec-1",
					slug: "hero-centered",
					title: "Existing Hero",
					description: null,
					keywords: null,
					content: "[]",
					preview_media_id: null,
					source: "theme",
					theme_id: "hero-centered",
					created_at: new Date().toISOString(),
					updated_at: new Date().toISOString(),
				})
				.execute();

			const seed: SeedFile = {
				version: "1",
				sections: [
					{
						slug: "hero-centered",
						title: "New Hero",
						content: [],
					},
					{
						slug: "cta-newsletter",
						title: "Newsletter CTA",
						content: [],
					},
				],
			};

			const result = await applySeed(db, seed);

			expect(result.sections.created).toBe(1);
			expect(result.sections.skipped).toBe(1);

			// Original title should be preserved
			const section = await db
				.selectFrom("_emdash_sections")
				.selectAll()
				.where("slug", "=", "hero-centered")
				.executeTakeFirst();

			expect(section?.title).toBe("Existing Hero");
		});
	});

	describe("idempotency", () => {
		it("should be safe to run multiple times", async () => {
			const seed: SeedFile = {
				version: "1",
				settings: { siteTitle: "Test Site" },
				collections: [
					{
						slug: "posts",
						label: "Posts",
						fields: [{ slug: "title", label: "Title", type: "string" }],
					},
				],
				taxonomies: [
					{
						name: "tags",
						label: "Tags",
						hierarchical: false,
						collections: ["posts"],
						terms: [{ slug: "test", label: "Test" }],
					},
				],
				menus: [
					{
						name: "main",
						label: "Main",
						items: [{ type: "custom", label: "Home", url: "/" }],
					},
				],
				widgetAreas: [
					{
						name: "sidebar",
						label: "Sidebar",
						widgets: [{ type: "content", title: "About" }],
					},
				],
				redirects: [{ source: "/legacy-post", destination: "/posts/test" }],
			};

			// First application
			const result1 = await applySeed(db, seed);
			expect(result1.collections.created).toBe(1);
			expect(result1.taxonomies.created).toBe(1);
			expect(result1.menus.created).toBe(1);
			expect(result1.widgetAreas.created).toBe(1);
			expect(result1.redirects.created).toBe(1);

			// Second application - should skip existing
			const result2 = await applySeed(db, seed);
			expect(result2.collections.created).toBe(0);
			expect(result2.collections.skipped).toBe(1);
			expect(result2.taxonomies.created).toBe(0);
			// Menus and widgets replace items but don't duplicate
			expect(result2.menus.created).toBe(0);
			expect(result2.widgetAreas.created).toBe(0);
			expect(result2.redirects.created).toBe(0);
			expect(result2.redirects.skipped).toBe(1);
		});
	});
});
