/**
 * Field Widget E2E Tests (Playwright)
 *
 * Tests plugin field widgets in the admin UI:
 * - Color picker widget renders for fields with widget: "color:picker"
 * - Widget is interactive (color input, hex input, presets)
 * - Content saves and loads with widget field values
 * - Widget falls back to default renderer when plugin is not active
 * - Manifest includes widget metadata
 *
 * The e2e fixture has the color plugin configured with a "theme_color"
 * field (type: string, widget: "color:picker") on the posts collection.
 */

import { test, expect } from "../fixtures";

const CONTENT_EDIT_URL_PATTERN = /\/content\/posts\/[A-Z0-9]+$/;

test.describe("Field Widgets", () => {
	test.beforeEach(async ({ admin }) => {
		await admin.devBypassAuth();
	});

	test.describe("Color Picker Widget Rendering", () => {
		test("renders color picker widget on new post form", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			// The color picker widget should be visible (has data-testid)
			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });

			// Should have a color input
			const colorInput = admin.page.locator('[data-testid="color-input"]');
			await expect(colorInput).toBeVisible();
			await expect(colorInput).toHaveAttribute("type", "color");

			// Should have a hex text input
			const hexInput = admin.page.locator('[data-testid="color-hex-input"]');
			await expect(hexInput).toBeVisible();

			// Should have a preview swatch
			const preview = admin.page.locator('[data-testid="color-preview"]');
			await expect(preview).toBeVisible();

			// Should have preset color buttons
			const presets = admin.page.locator('[data-testid="color-presets"]');
			await expect(presets).toBeVisible();
			const presetButtons = presets.locator("button");
			await expect(presetButtons).toHaveCount(10);
		});

		test("shows field label for color widget", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			// The label "Theme Color" should be visible
			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });
			await expect(widget.locator("label")).toContainText("Theme Color");
		});

		test("other fields render with default editors", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			// Title field should use standard input (not a widget)
			const titleInput = admin.page.locator("#field-title");
			await expect(titleInput).toBeVisible();
			// Should be a plain input, not a color picker widget
			await expect(admin.page.locator('[data-testid="color-picker-widget"]')).toHaveCount(1);
			await expect(
				titleInput.locator("..").locator('[data-testid="color-picker-widget"]'),
			).toHaveCount(0);
		});
	});

	test.describe("Color Picker Interaction", () => {
		test("can type a hex value", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			const hexInput = admin.page.locator('[data-testid="color-hex-input"]');
			await expect(hexInput).toBeVisible({ timeout: 10000 });
			await hexInput.fill("#ff6600");
			await expect(hexInput).toHaveValue("#ff6600");
		});

		test("clicking a preset updates the value", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });

			// Click the red preset (#ef4444)
			const redPreset = admin.page.locator('[data-testid="color-preset-ef4444"]');
			await expect(redPreset).toBeVisible();
			await redPreset.click();

			// Hex input should update
			const hexInput = admin.page.locator('[data-testid="color-hex-input"]');
			await expect(hexInput).toHaveValue("#ef4444");
		});

		test("clicking different presets changes the value", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });
			const hexInput = admin.page.locator('[data-testid="color-hex-input"]');

			// Click blue preset
			await admin.page.locator('[data-testid="color-preset-3b82f6"]').click();
			await expect(hexInput).toHaveValue("#3b82f6");

			// Click green preset
			await admin.page.locator('[data-testid="color-preset-22c55e"]').click();
			await expect(hexInput).toHaveValue("#22c55e");
		});
	});

	test.describe("Save and Load Widget Values", () => {
		test("saves content with color value and loads it back", async ({ admin }) => {
			// Create a post with a color
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			// Wait for widget to render
			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });

			// Fill title
			await admin.fillField("title", "Color Widget Test Post");

			// Set color via hex input
			const hexInput = admin.page.locator('[data-testid="color-hex-input"]');
			await hexInput.fill("#ff6600");

			// Save
			await admin.clickSave();
			await admin.waitForSaveComplete();

			// Should redirect to edit page
			await expect(admin.page).toHaveURL(CONTENT_EDIT_URL_PATTERN, {
				timeout: 10000,
			});

			// Reload the page to verify the value persisted
			await admin.page.reload();
			await admin.waitForLoading();

			// Wait for widget and check value
			await expect(widget).toBeVisible({ timeout: 10000 });
			const reloadedHex = admin.page.locator('[data-testid="color-hex-input"]');
			await expect(reloadedHex).toHaveValue("#ff6600");
		});

		test("saves content with preset color value", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });

			await admin.fillField("title", "Preset Color Post");

			// Click purple preset
			await admin.page.locator('[data-testid="color-preset-8b5cf6"]').click();

			await admin.clickSave();
			await admin.waitForSaveComplete();

			await expect(admin.page).toHaveURL(CONTENT_EDIT_URL_PATTERN, {
				timeout: 10000,
			});

			// Reload and verify
			await admin.page.reload();
			await admin.waitForLoading();
			await expect(widget).toBeVisible({ timeout: 10000 });
			await expect(admin.page.locator('[data-testid="color-hex-input"]')).toHaveValue("#8b5cf6");
		});

		test("saves content without color value", async ({ admin }) => {
			await admin.goToNewContent("posts");
			await admin.waitForLoading();

			const widget = admin.page.locator('[data-testid="color-picker-widget"]');
			await expect(widget).toBeVisible({ timeout: 10000 });

			// Just set title, don't touch color
			await admin.fillField("title", "No Color Post");

			await admin.clickSave();
			await admin.waitForSaveComplete();

			// Should save successfully
			await expect(admin.page).toHaveURL(CONTENT_EDIT_URL_PATTERN, {
				timeout: 10000,
			});
		});
	});

	test.describe("Manifest API", () => {
		test("manifest includes widget property on theme_color field", async ({ page }) => {
			const res = await page.request.get("/_emdash/api/manifest", {
				headers: { "X-EmDash-Request": "1" },
			});
			expect(res.ok()).toBe(true);
			const body = await res.json();
			const manifest = body.data;

			// Check field has widget
			const postFields = manifest.collections.posts.fields;
			expect(postFields.theme_color).toBeDefined();
			expect(postFields.theme_color.widget).toBe("color:picker");
			expect(postFields.theme_color.kind).toBe("string");

			// Other fields should not have widget
			expect(postFields.title.widget).toBeUndefined();
		});

		test("manifest includes color plugin with fieldWidgets", async ({ page }) => {
			const res = await page.request.get("/_emdash/api/manifest", {
				headers: { "X-EmDash-Request": "1" },
			});
			const body = await res.json();
			const manifest = body.data;

			// Check plugin manifest
			expect(manifest.plugins.color).toBeDefined();
			expect(manifest.plugins.color.enabled).toBe(true);
			expect(manifest.plugins.color.fieldWidgets).toBeDefined();
			expect(manifest.plugins.color.fieldWidgets).toHaveLength(1);
			expect(manifest.plugins.color.fieldWidgets[0].name).toBe("picker");
			expect(manifest.plugins.color.fieldWidgets[0].label).toBe("Color Picker");
			expect(manifest.plugins.color.fieldWidgets[0].fieldTypes).toEqual(["string"]);
		});
	});
});
