<script module lang="ts">
	import { defineMeta, type StoryContext } from "@storybook/addon-svelte-csf";
	import { expect } from "storybook/test";
	import type { CommitDetail } from "$lib/api/repo";
	import CommitHeader from "./CommitHeader.svelte";

	const fullCommit: CommitDetail = {
		hash: "0123456789abcdef0123456789abcdef01234567",
		shortHash: "01234567",
		subject: "add a storybook fixture",
		body: "the appview shows the body directly, no expander.\n\nit keeps line breaks too.",
		authorName: "dawn",
		authorEmail: "dawn@example.test",
		authorWhen: "2026-07-28T09:00:00Z",
		committerName: "cheri",
		committerEmail: "cheri@example.test",
		committerWhen: "2026-07-28T10:00:00Z",
		// the api layer already dedupes repeated trailers
		coAuthors: [{ name: "riley", email: "riley@example.test" }]
	};

	const minimalCommit: CommitDetail = {
		hash: "abcdef0123456789abcdef0123456789abcdef01",
		shortHash: "abcdef01",
		subject: "document the repository view",
		body: "",
		authorName: "dawn",
		authorEmail: "dawn@example.test",
		authorWhen: "2026-07-27T09:00:00Z",
		committerName: "dawn",
		committerEmail: "dawn@example.test",
		committerWhen: "2026-07-27T09:00:00Z",
		coAuthors: []
	};

	const noEmails: CommitDetail = {
		...minimalCommit,
		subject: "signed off without an address",
		authorEmail: "",
		committerEmail: ""
	};

	type PlayContext = Pick<
		StoryContext<Record<string, unknown>>,
		"canvas" | "canvasElement" | "userEvent"
	>;

	const fullMetadata = async ({ canvas, canvasElement }: PlayContext) => {
		await expect(canvas.queryByRole("button")).toBeNull();
		await expect(canvas.getByText(/the appview shows the body directly/)).toBeVisible();
		await expect(canvas.getByText(/it keeps line breaks too/)).toBeVisible();

		const author = canvas.getByRole("link", { name: "dawn" });
		await expect(author).toHaveAttribute("href", "mailto:dawn@example.test");
		await expect(canvasElement.querySelector("svg")).not.toBeNull();

		await expect(canvas.getAllByText("co-author")).toHaveLength(1);
		await expect(canvas.getByRole("link", { name: "riley" })).toHaveAttribute(
			"href",
			"mailto:riley@example.test"
		);
		await expect(canvas.getByText("committer")).toBeVisible();
		await expect(canvas.getByText("cheri")).toBeVisible();

		await expect(canvas.getByText(/\(.*2026.*\)/)).toBeInTheDocument();

		await expect(canvas.getByText("change-id")).toBeVisible();

		// anchored so the commit's own hash doesn't match too
		const parent = canvas.getByRole("link", { name: /^abcdef01/ });
		await expect(parent).toHaveAttribute(
			"href",
			"/dawn/tangled/commit/abcdef0123456789abcdef0123456789abcdef01"
		);
	};

	const hidesAbsentRows = async ({ canvas }: PlayContext) => {
		await expect(canvas.getByText("author")).toBeVisible();
		await expect(canvas.queryByText("committer")).toBeNull();
		await expect(canvas.queryByText("parent")).toBeNull();
		await expect(canvas.queryByText("change-id")).toBeNull();
		await expect(canvas.queryByRole("button")).toBeNull();
	};

	const namesStayWithoutMailto = async ({ canvas }: PlayContext) => {
		await expect(canvas.getByText("dawn")).toBeVisible();
		await expect(canvas.queryByRole("link", { name: "dawn" })).toBeNull();
	};

	const { Story } = defineMeta({
		title: "Repo/CommitHeader",
		component: CommitHeader,
		tags: ["autodocs"],
		args: {
			ownerHandle: "dawn",
			repoName: "tangled",
			commit: fullCommit,
			parent: "abcdef0123456789abcdef0123456789abcdef01",
			changeId: "kqpuwoxzrnvs"
		}
	});
</script>

<Story name="Full metadata" play={fullMetadata} />

<Story
	name="Minimal commit"
	args={{ commit: minimalCommit, parent: "", changeId: "" }}
	play={hidesAbsentRows}
/>

<Story
	name="No emails"
	args={{ commit: noEmails, parent: "", changeId: "" }}
	play={namesStayWithoutMailto}
/>
