import {EditorContent, useEditor} from '@tiptap/react';
import StarterKit from '@tiptap/starter-kit';
import Link from '@tiptap/extension-link';
import Underline from '@tiptap/extension-underline';
import TextAlign from '@tiptap/extension-text-align';
import Placeholder from '@tiptap/extension-placeholder';
import Image from '@tiptap/extension-image';
import {Table} from '@tiptap/extension-table';
import {TableCell} from '@tiptap/extension-table-cell';
import {TableHeader} from '@tiptap/extension-table-header';
import {TableRow} from '@tiptap/extension-table-row';
import {useEffect} from 'react';

type RichTextEditorProps = {
    value: string;
    onChange: (value: string) => void;
    placeholder?: string;
    disabled?: boolean;
};

type ToolbarButtonProps = {
    label: string;
    title: string;
    active?: boolean;
    disabled?: boolean;
    onClick: () => void;
};

const ToolbarButton = ({label, title, active = false, disabled = false, onClick}: ToolbarButtonProps) => (
    <button
        type="button"
        className={active ? 'active' : ''}
        title={title}
        aria-label={title}
        disabled={disabled}
        onClick={onClick}
    >
        {label}
    </button>
);

export const RichTextEditor = ({
                                   value,
                                   onChange,
                                   placeholder = '내용을 입력하세요.',
                                   disabled = false,
                               }: RichTextEditorProps) => {
    const editor = useEditor({
        editable: !disabled,
        extensions: [
            StarterKit,
            Underline,
            Link.configure({
                openOnClick: false,
                autolink: true,
                defaultProtocol: 'https',
            }),
            TextAlign.configure({
                types: ['heading', 'paragraph'],
            }),
            Placeholder.configure({
                placeholder,
            }),
            Image.configure({
                allowBase64: true,
            }),
            Table.configure({
                resizable: true,
            }),
            TableRow,
            TableHeader,
            TableCell,
        ],
        content: value || '',
        editorProps: {
            attributes: {
                class: 'rich_text_editor_body',
            },
        },
        onUpdate: ({editor}) => {
            onChange(editor.getHTML());
        },
    });

    useEffect(() => {
        if (!editor) {
            return;
        }

        editor.setEditable(!disabled);
    }, [disabled, editor]);

    useEffect(() => {
        if (!editor || value === editor.getHTML()) {
            return;
        }

        editor.commands.setContent(value || '', {emitUpdate: false});
    }, [editor, value]);

    if (!editor) {
        return null;
    }

    const setLink = () => {
        const previousUrl = editor.getAttributes('link').href as string | undefined;
        const url = window.prompt('링크 URL을 입력하세요.', previousUrl ?? '');

        if (url === null) {
            return;
        }

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

        editor.chain().focus().extendMarkRange('link').setLink({href: url.trim()}).run();
    };

    const addImage = () => {
        const url = window.prompt('이미지 URL을 입력하세요.');

        if (!url?.trim()) {
            return;
        }

        editor.chain().focus().setImage({src: url.trim()}).run();
    };

    return (
        <div className="rich_text_editor">
            <div className="rich_text_editor_toolbar">
                <ToolbarButton
                    label="H2"
                    title="제목"
                    active={editor.isActive('heading', {level: 2})}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleHeading({level: 2}).run()}
                />
                <ToolbarButton
                    label="B"
                    title="굵게"
                    active={editor.isActive('bold')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleBold().run()}
                />
                <ToolbarButton
                    label="I"
                    title="기울임"
                    active={editor.isActive('italic')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleItalic().run()}
                />
                <ToolbarButton
                    label="U"
                    title="밑줄"
                    active={editor.isActive('underline')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleUnderline().run()}
                />
                <ToolbarButton
                    label="S"
                    title="취소선"
                    active={editor.isActive('strike')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleStrike().run()}
                />
                <ToolbarButton
                    label="•"
                    title="글머리 기호"
                    active={editor.isActive('bulletList')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleBulletList().run()}
                />
                <ToolbarButton
                    label="1."
                    title="번호 목록"
                    active={editor.isActive('orderedList')}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().toggleOrderedList().run()}
                />
                <ToolbarButton
                    label="L"
                    title="왼쪽 정렬"
                    active={editor.isActive({textAlign: 'left'})}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().setTextAlign('left').run()}
                />
                <ToolbarButton
                    label="C"
                    title="가운데 정렬"
                    active={editor.isActive({textAlign: 'center'})}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().setTextAlign('center').run()}
                />
                <ToolbarButton
                    label="R"
                    title="오른쪽 정렬"
                    active={editor.isActive({textAlign: 'right'})}
                    disabled={disabled}
                    onClick={() => editor.chain().focus().setTextAlign('right').run()}
                />
                <ToolbarButton
                    label="Link"
                    title="링크"
                    active={editor.isActive('link')}
                    disabled={disabled}
                    onClick={setLink}
                />
                <ToolbarButton
                    label="Img"
                    title="이미지"
                    disabled={disabled}
                    onClick={addImage}
                />
                <ToolbarButton
                    label="Tbl"
                    title="표 삽입"
                    disabled={disabled}
                    onClick={() => editor.chain().focus().insertTable({rows: 3, cols: 3, withHeaderRow: true}).run()}
                />
                <ToolbarButton
                    label="Undo"
                    title="실행 취소"
                    disabled={disabled || !editor.can().undo()}
                    onClick={() => editor.chain().focus().undo().run()}
                />
                <ToolbarButton
                    label="Redo"
                    title="다시 실행"
                    disabled={disabled || !editor.can().redo()}
                    onClick={() => editor.chain().focus().redo().run()}
                />
            </div>
            <EditorContent editor={editor}/>
        </div>
    );
};
