<script lang="ts">
	import { untrack } from "svelte";
	import { now as tidNow } from "@atcute/tid";
	import Button from "$lib/components/ui/Button.svelte";
	import Spinner from "$lib/components/ui/Spinner.svelte";
	import ErrorAlert from "$lib/components/ui/Error.svelte";
	import ArrowUp from "$icon/arrow-up";
	import X from "$icon/x";
	import { getAuth } from "$lib/auth.svelte";
	import { putString } from "$lib/api/strings";
	import type { StringRecord } from "$lib/api/records";

	interface Props {
		mode?: "create" | "edit";
		rkey?: string;
		createdAt?: string;
		filename?: string;
		description?: string;
		content?: string;
		onsaved: (rkey: string) => void;
		oncancel?: () => void;
	}

	let {
		mode = "create",
		rkey,
		createdAt,
		filename: initialFilename = "",
		description: initialDescription = "",
		content: initialContent = "",
		onsaved,
		oncancel
	}: Props = $props();

	const auth = getAuth();

	let filename = $state(untrack(() => initialFilename));
	let description = $state(untrack(() => initialDescription));
	let content = $state(untrack(() => initialContent));
	let isPublishing = $state(false);
	let error = $state<string | null>(null);

	const lineCount = $derived(content === "" ? 0 : content.split("\n").length);
	const byteCount = $derived(new TextEncoder().encode(content).length);

	const handleSubmit = async (e: SubmitEvent) => {
		e.preventDefault();
		const agent = auth.agent;
		if (!agent || isPublishing) return;
		isPublishing = true;
		error = null;
		try {
			const targetRkey = rkey ?? tidNow();
			const record: StringRecord = {
				$type: "sh.tangled.string",
				filename,
				description,
				contents: content,
				createdAt: createdAt ?? new Date().toISOString()
			};
			await putString(agent, targetRkey, record);
			onsaved(targetRkey);
		} catch (err) {
			error = err instanceof Error ? err.message : "Failed to publish string";
		} finally {
			isPublishing = false;
		}
	};
</script>

<div class="rounded border border-border-default bg-background-default">
	<form onsubmit={handleSubmit}>
		<div class="flex flex-col gap-2 p-4">
			<div class="flex flex-col gap-2 md:flex-row">
				<input
					type="text"
					id="filename"
					name="filename"
					placeholder="Filename"
					required
					bind:value={filename}
					disabled={isPublishing}
					class="rounded border border-border-default bg-background-default px-2 py-2 text-sm text-foreground-default placeholder:text-foreground-placeholder focus:ring-1 focus:ring-border-strong focus:outline-none disabled:opacity-50 md:max-w-64"
				/>
				<input
					type="text"
					id="description"
					name="description"
					placeholder="Description ..."
					maxlength={280}
					bind:value={description}
					disabled={isPublishing}
					class="flex-1 rounded border border-border-default bg-background-default px-2 py-2 text-sm text-foreground-default placeholder:text-foreground-placeholder focus:ring-1 focus:ring-border-strong focus:outline-none disabled:opacity-50"
				/>
			</div>

			<textarea
				id="content"
				name="content"
				placeholder="Paste your string here!"
				required
				rows={20}
				spellcheck={false}
				bind:value={content}
				disabled={isPublishing}
				class="w-full resize-y rounded border border-border-default bg-background-default px-2 py-2 font-mono text-sm text-foreground-default placeholder:text-foreground-placeholder focus:ring-1 focus:ring-border-strong focus:outline-none disabled:opacity-50"
			></textarea>
		</div>

		<div class="flex items-center justify-between px-4 py-3">
			<div class="text-sm text-foreground-subtle">
				<span>{lineCount} line{lineCount !== 1 ? "s" : ""}</span>
				<span class="px-1 select-none">·</span>
				<span>{byteCount} byte{byteCount !== 1 ? "s" : ""}</span>
			</div>

			<div class="flex items-center gap-2">
				{#if mode === "edit"}
					<Button
						type="button"
						variant="default"
						icon={X}
						disabled={isPublishing}
						onclick={oncancel}
					>
						Cancel
					</Button>
				{/if}
				<Button
					type="submit"
					variant="primary"
					icon={isPublishing ? Spinner : ArrowUp}
					disabled={isPublishing}
				>
					Publish
				</Button>
			</div>
		</div>

		{#if error}
			<div class="px-4 pb-4">
				<ErrorAlert label={error} />
			</div>
		{/if}
	</form>
</div>
