<script lang="ts">
	import { untrack } from "svelte";
	import { now as tidNow } from "@atcute/tid";
	import CirclePlus from "$icon/circle-plus";
	import Pencil from "$icon/pencil";
	import X from "$icon/x";
	import { putIssue } from "$lib/api/issue";
	import { getAuth } from "$lib/auth.svelte";
	import Button from "$lib/components/ui/Button.svelte";
	import ErrorAlert from "$lib/components/ui/Error.svelte";
	import Input from "$lib/components/ui/Input.svelte";
	import MarkdownEditor from "$lib/components/ui/MarkdownEditor.svelte";
	import Spinner from "$lib/components/ui/Spinner.svelte";
	import { type MarkupContext } from "$lib/markup";
	import type { IssueRecord, RecordView } from "$lib/api/records";
	import { createAction } from "$lib/action.svelte";

	interface Props {
		repoDid: string;
		markup: MarkupContext;
		mode?: "create" | "edit";
		rkey?: string;
		createdAt?: string;
		title?: string;
		body?: string;
		submitLabel?: string;
		bodyPlaceholder?: string;
		onsaved: (saved: RecordView<IssueRecord>) => void;
		oncancel: () => void;
	}

	let {
		repoDid,
		markup,
		mode = "create",
		rkey,
		createdAt,
		title: initialTitle = "",
		body: initialBody = "",
		submitLabel,
		bodyPlaceholder = "Describe your issue. Markdown is supported.",
		onsaved,
		oncancel
	}: Props = $props();

	const auth = getAuth();

	let title = $state(untrack(() => initialTitle));
	let body = $state(untrack(() => initialBody));
	const submitText = $derived(submitLabel ?? (mode === "edit" ? "Save" : "Create issue"));
	const submitIcon = $derived(mode === "edit" ? Pencil : CirclePlus);

	const save = createAction(async (event: SubmitEvent) => {
		event.preventDefault();
		const agent = auth.agent;
		if (!agent || title.trim() === "") return;
		const targetRkey = rkey ?? tidNow();
		const record: IssueRecord = {
			$type: "sh.tangled.repo.issue",
			repo: repoDid as IssueRecord["repo"],
			title,
			body,
			createdAt: createdAt ?? new Date().toISOString()
		};
		const saved = await putIssue(agent, targetRkey, record);
		onsaved(saved);
	});
	const canSubmit = $derived(title.trim() !== "" && !save.loading);
</script>

<form onsubmit={save.run} class="flex flex-col gap-4">
	<div class="flex flex-col gap-1.5">
		<label for="issue-title" class="text-sm text-foreground-default">Title</label>
		<Input id="issue-title" name="title" required bind:value={title} disabled={save.loading} />
	</div>

	<div class="flex flex-col gap-1.5">
		<span class="text-sm text-foreground-default">Body</span>

		<MarkdownEditor
			id="issue-body"
			name="body"
			rows={12}
			placeholder={bodyPlaceholder}
			{markup}
			bind:value={body}
			disabled={save.loading}
		/>
	</div>

	<ErrorAlert label={save.error} />

	<div class="flex items-center justify-end gap-2">
		<Button type="button" variant="default" icon={X} disabled={save.loading} onclick={oncancel}>
			Cancel
		</Button>
		<Button
			type="submit"
			variant="primary"
			icon={save.loading ? Spinner : submitIcon}
			disabled={!canSubmit}
		>
			{submitText}
		</Button>
	</div>
</form>
