import type { Bookmark, Tag } from "@markone/core"
import { useId, useRef } from "react"
import { useBookmarkTags, useUpdateBookmark } from "~/bookmark/api"
import { Button } from "~/components/button"
import { Dialog, DialogActionRow, DialogBody, DialogTitle } from "~/components/dialog"
import { FormField } from "~/components/form-field"
import { LoadingSpinner } from "~/components/loading-spinner"
import { Message, MessageVariant } from "~/components/message.tsx"
import { TagsInput, type TagsInputRef } from "~/components/tags-input"
import { useBookmarkPageStore } from "../-store"

function EditBookmarkDialog({ bookmark }: { bookmark: Bookmark }) {
	const closeDialog = useBookmarkPageStore((state) => state.closeDialog)
	const { data: tags, status } = useBookmarkTags(bookmark)
	const editFormId = useId()

	function content() {
		switch (status) {
			case "pending":
				return (
					<p>
						Loading <LoadingSpinner />
					</p>
				)
			case "success":
				return <EditForm formId={editFormId} bookmark={bookmark} tags={tags} />
			case "error":
				return null
		}
	}

	return (
		<Dialog>
			<DialogTitle>EDIT BOOKMARK</DialogTitle>
			<DialogBody>{content()}</DialogBody>
			<DialogActionRow>
				<Button type="submit" form={editFormId} disabled={status !== "success"}>
					<span className="underline">S</span>AVE
				</Button>
				<Button disabled={status !== "success"} onClick={closeDialog}>
					<span className="underline">C</span>ANCEL
				</Button>
			</DialogActionRow>
		</Dialog>
	)
}

function EditForm({ formId, bookmark, tags }: { formId: string; bookmark: Bookmark; tags: Tag[] }) {
	const tagsInputRef = useRef<TagsInputRef>(null)
	const updateBookmarkMutation = useUpdateBookmark(bookmark)
	const closeDialog = useBookmarkPageStore((state) => state.closeDialog)

	async function onSubmit(event: React.FormEvent<HTMLFormElement>) {
		if (tagsInputRef.current) {
			event.preventDefault()
			const form = new FormData(event.currentTarget)
			const title = form.get("title")
			const tags = tagsInputRef.current.tags
			if (title && typeof title === "string") {
				try {
					await updateBookmarkMutation.mutateAsync({
						title,
						tags,
					})
					closeDialog()
				} catch {}
			}
		}
	}

	function message() {
		switch (updateBookmarkMutation.status) {
			case "pending":
				return (
					<p>
						Saving changes <LoadingSpinner />
					</p>
				)
			case "error":
				return <Message variant={MessageVariant.Error}>Error updating the bookmark!</Message>
			default:
				return null
		}
	}

	return (
		<>
			{message()}
			<form id={formId} onSubmit={onSubmit}>
				<FormField
					type="text"
					name="title"
					label="TITLE"
					className="w-full"
					defaultValue={bookmark.title}
					labelClassName="bg-stone-300 dark:bg-stone-800"
				/>
				<TagsInput ref={tagsInputRef} initialValue={tags.map((tag) => tag.name).join(" ")} />
			</form>
		</>
	)
}

export { EditBookmarkDialog }
