import { LoaderIcon, PencilIcon, XIcon } from "lucide-solid"
import { useMutation, useQueryClient } from "@tanstack/solid-query"
import { createSignal, Show } from "solid-js"
import { client } from "../apiclient.ts"
import { Bookmark } from "../../server/utils/bookmarks.ts"
import "./BookmarkEditModal.css"
import "./ui/button.css"
import { useWebHaptics } from "../utils/haptics.ts"

interface BookmarkEditModalProps {
    bookmark: Bookmark & { id: string }
}

export function BookmarkEditModal(props: BookmarkEditModalProps) {
    const haptics = useWebHaptics()

    const queryClient = useQueryClient()
    const [title, setTitle] = createSignal(props.bookmark.title)
    const [description, setDescription] = createSignal(
        props.bookmark.description,
    )

    const editBookmark = useMutation(() => ({
        mutationFn: async () => {
            const res = await client.api.v1.bookmarks[":id"].$put({
                param: { id: props.bookmark.id },
                json: {
                    title: title().trim(),
                    description: description().trim(),
                },
            })
            if (!res.ok) {
                const data = await res.json()
                haptics.trigger([
                    { duration: 40, intensity: 0.7 },
                    { delay: 40, duration: 40, intensity: 0.7 },
                    { delay: 40, duration: 40, intensity: 0.9 },
                    { delay: 40, duration: 50, intensity: 0.6 },
                ])
                throw new Error(
                    "error" in data ? data.error : "Failed to update bookmark",
                )
            }
            return await res.json()
        },
        onSuccess: async () => {
            await queryClient.invalidateQueries({
                queryKey: [client.api.v1.bookmarks.all.$url().pathname],
            })
            // Close the modal
            const dialog = document.getElementById(
                `edit-${props.bookmark.id}`,
            ) as HTMLDialogElement | null
            dialog?.requestClose()
        },
    }))

    const handleSubmit = (e: SubmitEvent) => {
        e.preventDefault()
        const titleValue = title().trim()
        if (titleValue) {
            editBookmark.mutate()
        }
    }

    return (
        <>
            <button
                type="button"
                command="show-modal"
                commandfor={`edit-${props.bookmark.id}`}
                class="bookmark-edit button-icon button-ghost"
                onClick={() => haptics.trigger()}
            >
                <PencilIcon size={16} />
            </button>
            <dialog
                id={`edit-${props.bookmark.id}`}
                class="bookmark-edit-modal"
            >
                <div class="title">
                    <h2>Edit bookmark</h2>

                    <button
                        type="button"
                        commandfor={`edit-${props.bookmark.id}`}
                        command="close"
                        class="button-ghost button-icon"
                    >
                        <XIcon size={16} />
                    </button>
                </div>

                <form onSubmit={handleSubmit} class="edit-form">
                    <div class="input-group">
                        <label for={`title-${props.bookmark.id}`}>Title</label>
                        <input
                            id={`title-${props.bookmark.id}`}
                            type="text"
                            required
                            value={title()}
                            onInput={(e) => setTitle(e.currentTarget.value)}
                            disabled={editBookmark.isPending}
                            maxlength="200"
                        />
                    </div>

                    <div class="input-group">
                        <label for={`description-${props.bookmark.id}`}>
                            Description
                        </label>
                        <textarea
                            id={`description-${props.bookmark.id}`}
                            value={description()}
                            onInput={(e) =>
                                setDescription(e.currentTarget.value)}
                            disabled={editBookmark.isPending}
                            maxlength="500"
                        />
                    </div>

                    <button
                        type="submit"
                        class="button"
                        disabled={editBookmark.isPending || !title()?.trim()}
                    >
                        <Show
                            when={!editBookmark.isPending}
                            fallback={
                                <>
                                    <LoaderIcon size={16} class="spinner" />
                                    Saving...
                                </>
                            }
                        >
                            Save changes
                        </Show>
                    </button>
                </form>

                <Show when={editBookmark.isError}>
                    <div class="error-message">
                        {editBookmark.error?.message ??
                            "Failed to update bookmark"}
                    </div>
                </Show>
            </dialog>
        </>
    )
}
