/**
 * Allowed Domains E2E Tests
 *
 * Tests self-signup domain management in admin settings.
 * Available at /settings/allowed-domains.
 *
 * Uses API to add/remove domains as needed, verifies UI reflects changes.
 */

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

// API helper
function apiHeaders(token: string, baseUrl: string) {
	return {
		"Content-Type": "application/json",
		Authorization: `Bearer ${token}`,
		"X-EmDash-Request": "1",
		Origin: baseUrl,
	};
}

test.describe("Allowed Domains Settings", () => {
	let headers: Record<string, string>;
	let baseUrl: string;

	test.beforeEach(async ({ admin, serverInfo }) => {
		await admin.devBypassAuth();
		baseUrl = serverInfo.baseUrl;
		headers = apiHeaders(serverInfo.token, baseUrl);

		// Clean up any leftover test domains from previous runs
		const res = await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains`, { headers });
		if (res.ok) {
			const data: any = await res.json();
			const domains = data.data?.domains ?? [];
			for (const d of domains) {
				if (d.domain.includes("e2e-test")) {
					await fetch(
						`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(d.domain)}`,
						{ method: "DELETE", headers },
					).catch(() => {});
				}
			}
		}
	});

	test("renders the allowed domains settings page", async ({ admin, page }) => {
		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		// Should show the page title
		await expect(page.locator("h1").first()).toContainText("Self-Signup Domains");

		// Should show the "Allowed Domains" section heading
		await expect(page.locator("h2", { hasText: "Allowed Domains" })).toBeVisible({
			timeout: 10000,
		});

		// Should have an "Add Domain" button
		await expect(page.getByRole("button", { name: "Add Domain" })).toBeVisible();
	});

	test("shows empty state when no domains configured", async ({ admin, page }) => {
		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		// Should show empty state message (unless domains were pre-configured)
		const emptyState = page.locator("text=No domains configured");

		// Check if there's already domain data or empty state
		const hasEmptyState = await emptyState.isVisible({ timeout: 5000 }).catch(() => false);
		if (hasEmptyState) {
			await expect(emptyState).toBeVisible();
		}
		// Either way, the Add Domain button should be there
		await expect(page.getByRole("button", { name: "Add Domain" })).toBeVisible();
	});

	test("adds a new domain via the UI", async ({ admin, page }) => {
		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		const testDomain = `e2e-test-${Date.now()}.example.com`;

		// Click "Add Domain" to open the inline form
		await page.getByRole("button", { name: "Add Domain" }).click();

		// The add form should appear with a domain input
		const domainInput = page.getByLabel("Domain");
		await expect(domainInput).toBeVisible({ timeout: 5000 });

		// Fill in the domain
		await domainInput.fill(testDomain);

		// Click "Add Domain" submit button (different from the trigger button)
		const submitButton = page.getByRole("button", { name: "Add Domain" });
		await submitButton.click();

		// Wait for the domain to appear in the list
		await expect(page.locator(`.font-medium`, { hasText: testDomain })).toBeVisible({
			timeout: 10000,
		});

		// Should show a success status message
		const successMsg = page.locator("text=Domain added successfully");
		await expect(successMsg).toBeVisible({ timeout: 5000 });

		// Clean up via API
		await fetch(
			`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
			{ method: "DELETE", headers },
		).catch(() => {});
	});

	test("removes a domain via the UI", async ({ admin, page }) => {
		const testDomain = `e2e-test-delete-${Date.now()}.example.com`;

		// Create domain via API first
		await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains`, {
			method: "POST",
			headers,
			body: JSON.stringify({ domain: testDomain, defaultRole: 30 }),
		});

		// Navigate to the page
		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		// Verify the domain is visible
		await expect(page.locator(`.font-medium`, { hasText: testDomain })).toBeVisible({
			timeout: 10000,
		});

		// Click the delete button for this domain
		const deleteButton = page.getByRole("button", { name: `Delete ${testDomain}` });
		await deleteButton.click();

		// The confirmation dialog should appear
		const dialog = page.locator('[role="dialog"]');
		await expect(dialog).toBeVisible({ timeout: 5000 });
		await expect(dialog.getByRole("heading", { name: "Remove Domain" })).toBeVisible();

		// Confirm deletion
		await dialog.getByRole("button", { name: "Remove Domain" }).click();

		// Domain should disappear from the list
		await expect(page.locator(`.font-medium`, { hasText: testDomain })).not.toBeVisible({
			timeout: 10000,
		});

		// Should show a success status message
		const successMsg = page.locator("text=Domain removed");
		await expect(successMsg).toBeVisible({ timeout: 5000 });
	});

	test("cancel delete keeps the domain", async ({ admin, page }) => {
		const testDomain = `e2e-test-keep-${Date.now()}.example.com`;

		// Create domain via API
		await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains`, {
			method: "POST",
			headers,
			body: JSON.stringify({ domain: testDomain, defaultRole: 30 }),
		});

		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		// Verify domain is visible
		await expect(page.locator(`.font-medium`, { hasText: testDomain })).toBeVisible({
			timeout: 10000,
		});

		// Click delete
		await page.getByRole("button", { name: `Delete ${testDomain}` }).click();

		// Dialog appears
		const dialog = page.locator('[role="dialog"]');
		await expect(dialog).toBeVisible({ timeout: 5000 });

		// Cancel
		await dialog.getByRole("button", { name: "Cancel" }).click();

		// Dialog should close
		await expect(dialog).not.toBeVisible({ timeout: 5000 });

		// Domain should still be there
		await expect(page.locator(`.font-medium`, { hasText: testDomain })).toBeVisible();

		// Clean up
		await fetch(
			`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
			{ method: "DELETE", headers },
		).catch(() => {});
	});

	test("toggling enabled/disabled updates the domain", async ({ admin, page }) => {
		const testDomain = `e2e-test-toggle-${Date.now()}.example.com`;

		// Create domain via API
		await fetch(`${baseUrl}/_emdash/api/admin/allowed-domains`, {
			method: "POST",
			headers,
			body: JSON.stringify({ domain: testDomain, defaultRole: 30 }),
		});

		await admin.goto("/settings/allowed-domains");
		await admin.waitForShell();
		await admin.waitForLoading();

		// Find the domain row
		const domainRow = page.locator("div.flex.items-center.justify-between").filter({
			hasText: testDomain,
		});
		await expect(domainRow).toBeVisible({ timeout: 10000 });

		// Find the switch toggle in the row and click it
		const toggle = domainRow.locator("button[role='switch']");
		await toggle.click();

		// Wait for the update to complete -- success message should appear
		const statusMsg = page.locator("text=Domain updated");
		await expect(statusMsg).toBeVisible({ timeout: 5000 });

		// Clean up
		await fetch(
			`${baseUrl}/_emdash/api/admin/allowed-domains/${encodeURIComponent(testDomain)}`,
			{ method: "DELETE", headers },
		).catch(() => {});
	});
});
