import React, {useEffect, useRef, useState} from 'react';
import Quill from 'quill';
import 'quill/dist/quill.snow.css';

type Props = {
    value: string;
    mergeFields: string[];
    onChange: (value: string) => void;
};

export default function RichTextTemplateEditor({value, mergeFields, onChange}: Props): JSX.Element {
    const editorElement = useRef<HTMLDivElement | null>(null);
    const editor = useRef<any>(null);
    const onChangeRef = useRef(onChange);
    const syncing = useRef(false);
    const [mergeField, setMergeField] = useState('');

    useEffect(() => {
        onChangeRef.current = onChange;
    }, [onChange]);

    useEffect(() => {
        if (!editorElement.current || editor.current) return;
        const instance = new Quill(editorElement.current, {
            theme: 'snow',
            placeholder: 'Compose the template and insert matter merge fields…',
            modules: {
                toolbar: [
                    [{header: [1, 2, 3, false]}],
                    ['bold', 'italic', 'underline', 'strike'],
                    [{list: 'ordered'}, {list: 'bullet'}],
                    [{align: []}],
                    ['blockquote', 'link'],
                    ['clean'],
                ],
            },
        });
        instance.on('text-change', () => {
            if (!syncing.current) onChangeRef.current(instance.root.innerHTML);
        });
        editor.current = instance;

        return () => {
            instance.off('text-change');
            editor.current = null;
        };
    }, []);

    useEffect(() => {
        const instance = editor.current;
        if (!instance || instance.root.innerHTML === value) return;
        syncing.current = true;
        instance.clipboard.dangerouslyPasteHTML(value || '');
        syncing.current = false;
    }, [value]);

    function insertMergeField() {
        if (!mergeField || !editor.current) return;
        const range = editor.current.getSelection(true);
        const token = `{{${mergeField}}}`;
        editor.current.insertText(range?.index ?? editor.current.getLength() - 1, token, 'user');
        editor.current.setSelection((range?.index ?? editor.current.getLength() - 1) + token.length, 0);
        setMergeField('');
    }

    return <div>
        <div className="mb-2 flex gap-2">
            <select className="ti-form-input flex-1" value={mergeField} onChange={event => setMergeField(event.target.value)}>
                <option value="">Select a merge field</option>
                {mergeFields.map(field => <option key={field} value={field}>{`{{${field}}}`}</option>)}
            </select>
            <button type="button" className="ti-btn ti-btn-light" disabled={!mergeField} onClick={insertMergeField}>Insert field</button>
        </div>
        <div className="rounded-lg bg-white">
            <div ref={editorElement} className="min-h-[280px] text-sm" />
        </div>
        <p className="mt-2 text-xs text-gray-500">Formatting and merge fields are preserved when the template is generated as a PDF.</p>
    </div>;
}
