<script setup lang="ts">
import { useEditor, EditorContent } from '@tiptap/vue-3';
import StarterKit from '@tiptap/starter-kit';
import Link from '@tiptap/extension-link';
import Underline from '@tiptap/extension-underline';
import { watch, onBeforeUnmount } from 'vue';
import { cn } from '@/lib/utils';

const props = withDefaults(defineProps<{
    modelValue?: string;
    placeholder?: string;
    class?: string;
}>(), {
    modelValue: '',
    placeholder: 'Tulis deskripsi…',
});

const emit = defineEmits<{
    'update:modelValue': [value: string];
}>();

const editor = useEditor({
    content: props.modelValue,
    extensions: [
        StarterKit.configure({
            heading: { levels: [1, 2, 3] },
        }),
        Link.configure({
            openOnClick: false,
            HTMLAttributes: { rel: 'noopener noreferrer nofollow', target: '_blank' },
        }),
        Underline,
    ],
    editorProps: {
        attributes: {
            class: 'prose prose-sm min-h-[120px] max-w-none rounded-md rounded-t-none border border-input bg-background px-3 py-2 focus:outline-none focus:ring-1 focus:ring-ring [&_pre]:overflow-x-auto [&_pre]:max-w-full [&_code]:break-words [&_a]:break-all',
        },
    },
    onUpdate: ({ editor }) => {
        emit('update:modelValue', editor.getHTML());
    },
});

// Sync external changes (e.g. form reset / initial load) ke editor.
watch(
    () => props.modelValue,
    (value) => {
        if (! editor.value) return;
        const current = editor.value.getHTML();
        if (value !== current) {
            editor.value.commands.setContent(value ?? '', false);
        }
    },
);

onBeforeUnmount(() => {
    editor.value?.destroy();
});

const toggleLink = () => {
    if (! editor.value) return;
    const previousUrl = editor.value.getAttributes('link').href ?? '';
    const url = window.prompt('URL tujuan:', previousUrl);

    if (url === null) return; // dibatalkan

    if (url === '') {
        editor.value.chain().focus().extendMarkRange('link').unsetLink().run();
        return;
    }

    editor.value.chain().focus().extendMarkRange('link').setLink({ href: url }).run();
};
</script>

<template>
    <div :class="cn('w-full', props.class)">
        <div
            v-if="editor"
            class="flex flex-wrap items-center gap-1 rounded-md border border-input border-b-0 bg-muted/40 p-1"
        >
            <button
                type="button"
                @click="editor.chain().focus().toggleBold().run()"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('bold') ? 'bg-accent font-bold' : '']"
                title="Bold"
            >
                B
            </button>
            <button
                type="button"
                @click="editor.chain().focus().toggleItalic().run()"
                :class="['rounded p-1.5 text-sm italic transition hover:bg-accent', editor.isActive('italic') ? 'bg-accent' : '']"
                title="Italic"
            >
                I
            </button>
            <button
                type="button"
                @click="editor.chain().focus().toggleUnderline().run()"
                :class="['rounded p-1.5 text-sm underline transition hover:bg-accent', editor.isActive('underline') ? 'bg-accent' : '']"
                title="Underline"
            >
                U
            </button>

            <span class="mx-1 h-5 w-px bg-border" />

            <button
                v-for="lvl in [1, 2, 3]"
                :key="lvl"
                type="button"
                @click="editor.chain().focus().toggleHeading({ level: lvl }).run()"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('heading', { level: lvl }) ? 'bg-accent font-semibold' : '']"
                :title="`Heading ${lvl}`"
            >
                H{{ lvl }}
            </button>

            <span class="mx-1 h-5 w-px bg-border" />

            <button
                type="button"
                @click="editor.chain().focus().toggleBulletList().run()"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('bulletList') ? 'bg-accent' : '']"
                title="Bullet list"
            >
                •
            </button>
            <button
                type="button"
                @click="editor.chain().focus().toggleOrderedList().run()"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('orderedList') ? 'bg-accent' : '']"
                title="Numbered list"
            >
                1.
            </button>
            <button
                type="button"
                @click="editor.chain().focus().toggleBlockquote().run()"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('blockquote') ? 'bg-accent' : '']"
                title="Quote"
            >
                ❝
            </button>

            <span class="mx-1 h-5 w-px bg-border" />

            <button
                type="button"
                @click="toggleLink"
                :class="['rounded p-1.5 text-sm transition hover:bg-accent', editor.isActive('link') ? 'bg-accent underline' : '']"
                title="Link"
            >
                🔗
            </button>
            <button
                type="button"
                @click="editor.chain().focus().unsetAllMarks().clearNodes().run()"
                class="rounded p-1.5 text-sm transition hover:bg-accent"
                title="Clear formatting"
            >
                ⌫
            </button>
        </div>

        <EditorContent :editor="editor" />
    </div>
</template>
