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

	const diff: NiceDiff = {
		commit: {
			this: "0123456789abcdef0123456789abcdef01234567",
			parent: "abcdef0123456789abcdef0123456789abcdef01",
			author: { Name: "dawn", Email: "dawn@example.test", When: "2026-07-28T09:00:00Z" },
			committer: { Name: "cheri", Email: "cheri@example.test", When: "2026-07-28T10:00:00Z" },
			message:
				"add a storybook fixture\n\nthis body is hidden until the disclosure button is pressed.\n\nCo-authored-by: riley <riley@example.test>",
			change_id: "kqpuwoxzrnvs"
		},
		stat: { insertions: 2, deletions: 1, files_changed: 2 },
		diff: [
			{
				name: { old: "src/colors.ts", new: "src/colors.ts" },
				text_fragments: [
					{
						OldPosition: 1,
						OldLines: 3,
						NewPosition: 1,
						NewLines: 4,
						LinesAdded: 2,
						LinesDeleted: 1,
						Lines: [
							{ Op: 0, Line: "export const palette = {\n" },
							{ Op: 1, Line: '\tbackground: "white",\n' },
							{ Op: 2, Line: '\tbackground: "oklch(0.98 0 0)",\n' },
							{ Op: 2, Line: '\tforeground: "oklch(0.2 0 0)",\n' },
							{ Op: 0, Line: "};\n" }
						]
					}
				]
			},
			{
				name: { old: "assets/logo.png", new: "assets/logo.png" },
				is_binary: true
			}
		]
	};

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

	const shadowText = (canvasElement: HTMLElement) =>
		[...canvasElement.querySelectorAll("diffs-container")]
			.map((host) => host.shadowRoot?.textContent ?? "")
			.join("\n");

	const fullCommit = async ({ canvas, canvasElement }: PlayContext) => {
		await expect(canvas.getByText("add a storybook fixture")).toBeVisible();
		await expect(canvas.getByText("co-author")).toBeVisible();
		await expect(canvas.getByText("committer")).toBeVisible();

		await expect(canvas.getByRole("link", { name: ".patch" })).toHaveAttribute(
			"href",
			"/dawn/tangled/commit/0123456789abcdef0123456789abcdef01234567.patch"
		);

		// the filename is in the light-dom card header, the diff body in the
		// shadow root
		await expect(canvas.getByText("src/colors.ts")).toBeVisible();
		await waitFor(() => expect(shadowText(canvasElement)).toContain("palette"));
		await expect(
			canvas.getByText("This is a binary file and will not be displayed.")
		).toBeVisible();
	};

	const hidesDownloadsForShortRef = async ({ canvas }: PlayContext) => {
		await expect(canvas.getByText("add a storybook fixture")).toBeVisible();
		await expect(canvas.queryByRole("link", { name: ".patch" })).toBeNull();
		await expect(canvas.queryByRole("link", { name: ".diff" })).toBeNull();
	};

	const { Story } = defineMeta({
		title: "Repo/CommitView",
		component: CommitView,
		tags: ["autodocs"],
		args: {
			ownerHandle: "dawn",
			repoName: "tangled",
			ref: "0123456789abcdef0123456789abcdef01234567",
			commit: toCommitDetail(diff.commit!),
			parent: diff.commit?.parent ?? "",
			changeId: diff.commit?.change_id ?? "",
			files: diff.diff ?? [],
			stat: diff.stat
		}
	});
</script>

<Story name="Full commit" play={fullCommit} />

<Story name="Split" args={{ diffStyle: "split" }} />

<Story name="Branch ref" args={{ ref: "main" }} play={hidesDownloadsForShortRef} />
