import { useCallback, useEffect, useRef } from "react";
import wp from "wp";

import type { FC } from "react";

const CodeMirror: FC<{ settings: any; value?: string; onChange?: (value: string) => void }> = ({
    settings = {},
    value = "",
    onChange,
}) => {
    const ref = useRef<HTMLTextAreaElement>();
    const codeMirrorRef = useRef<any>();
    const { codeEditor } = wp;

    useEffect(() => {
        // Check if the current profile allows syntax highlighting
        if (codeEditor) {
            const { codemirror } = codeEditor.initialize(ref.current, settings);
            codeMirrorRef.current = codemirror;
            codemirror.on("change", (instance: any) => {
                onChange?.(instance.getValue());
            });
        }
    }, []);

    // Avoid React error: You provided a `value` prop to a form field without an `onChange` handler
    // The onChange handler is done by codemirror itself
    const noop = useCallback(() => {
        // Silence is golden.
    }, []);

    // Fix values coming from controlled element (e.g. antd `<Form.Item`)
    useEffect(() => {
        if (
            typeof value === "string" &&
            ref.current &&
            codeMirrorRef.current &&
            ref.current.value !== codeMirrorRef.current.getValue()
        ) {
            codeMirrorRef.current.setValue(ref.current.value);
        }
    }, [value]);

    return (
        <textarea
            ref={ref}
            value={value}
            onChange={codeEditor ? noop : ({ target: { value } }) => onChange(value)}
            style={{ width: "100%" }}
        />
    );
};

export { CodeMirror };
