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

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

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

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

	test("creates and edits a guest byline in admin", async ({ admin, page }) => {
		const unique = Date.now();
		const initialName = `Guest Byline ${unique}`;
		const updatedName = `Guest Byline Updated ${unique}`;

		await admin.goto("/bylines");
		await admin.waitForShell();
		await admin.waitForLoading();

		await page.getByRole("button", { name: "New" }).click();
		await page.getByLabel("Display name").fill(initialName);
		await page.getByLabel("Slug").fill(`guest-byline-${unique}`);
		await page.getByRole("switch", { name: "Guest byline" }).click();
		await page.getByRole("button", { name: "Create" }).click();

		await expect(page.getByRole("button", { name: initialName })).toBeVisible({ timeout: 5000 });

		await page.getByRole("button", { name: initialName }).click();
		await page.getByLabel("Display name").fill(updatedName);
		await page.getByRole("button", { name: "Save" }).click();

		await expect(page.getByRole("button", { name: updatedName })).toBeVisible({ timeout: 5000 });
	});

	test("assigns and reorders bylines, preserves bylines on ownership change", async ({
		admin,
		page,
		serverInfo,
	}) => {
		const unique = Date.now();
		const primaryName = `Primary Writer ${unique}`;
		const secondaryName = `Secondary Writer ${unique}`;
		const headers = apiHeaders(serverInfo.token, serverInfo.baseUrl);

		const createByline = async (displayName: string, slug: string) => {
			const response = await fetch(`${serverInfo.baseUrl}/_emdash/api/admin/bylines`, {
				method: "POST",
				headers,
				body: JSON.stringify({
					displayName,
					slug,
					isGuest: true,
				}),
			});
			expect(response.ok).toBe(true);
			const body: any = await response.json();
			return body.data.id as string;
		};

		const firstBylineId = await createByline(primaryName, `primary-writer-${unique}`);
		const secondBylineId = await createByline(secondaryName, `secondary-writer-${unique}`);

		await admin.goToNewContent("posts");
		await admin.waitForLoading();
		await admin.fillField("title", `Byline E2E Post ${unique}`);
		await admin.clickSave();
		await expect(page).toHaveURL(CONTENT_EDIT_URL_PATTERN, { timeout: 10000 });

		const contentId = page.url().split("/").pop();
		expect(contentId).toBeTruthy();
		await admin.waitForLoading();

		// Scope the byline select to the Bylines section to avoid hitting the Ownership combobox
		const bylinesSidebar = page
			.getByRole("heading", { name: "Bylines" })
			.locator("xpath=ancestor::div[contains(@class,'p-4')]")
			.first();
		const bylineSelect = bylinesSidebar.locator("select").first();
		await bylineSelect.selectOption({ value: firstBylineId });
		await bylinesSidebar.getByRole("button", { name: "Add" }).click();

		await bylineSelect.selectOption({ value: secondBylineId });
		await bylinesSidebar.getByRole("button", { name: "Add" }).click();

		await page.getByLabel("Role label").nth(1).fill("Co-author");
		await page.getByRole("button", { name: "Up" }).nth(1).click();

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

		await expect(bylinesSidebar.locator("p.text-sm.font-medium").first()).toContainText(
			secondaryName,
		);

		const ownershipUpdateResponse = await fetch(
			`${serverInfo.baseUrl}/_emdash/api/content/posts/${contentId as string}`,
			{
				method: "PUT",
				headers,
				body: JSON.stringify({ authorId: null }),
			},
		);
		expect(ownershipUpdateResponse.ok).toBe(true);

		await page.reload();
		await admin.waitForShell();
		await admin.waitForLoading();

		const bylineSectionAfterReload = page
			.getByRole("heading", { name: "Bylines" })
			.locator("xpath=ancestor::div[contains(@class,'p-4')]")
			.first();

		await expect(bylineSectionAfterReload.locator("p.text-sm.font-medium").first()).toContainText(
			secondaryName,
		);

		const contentResponse = await fetch(
			`${serverInfo.baseUrl}/_emdash/api/content/posts/${contentId as string}`,
			{ headers },
		);
		expect(contentResponse.ok).toBe(true);
		const contentBody: any = await contentResponse.json();
		const item = contentBody.data?.item;

		expect(item.byline?.displayName).toBe(secondaryName);
		expect(item.bylines).toHaveLength(2);
		expect(item.bylines[0]?.byline?.displayName).toBe(secondaryName);
		expect(item.bylines[1]?.byline?.displayName).toBe(primaryName);
		const secondaryCredit = item.bylines.find(
			(credit: any) => credit?.byline?.displayName === secondaryName,
		);
		expect(secondaryCredit?.roleLabel).toBe("Co-author");
	});
});
