import { useCallback, useEffect, useRef, useState } from 'react';
import {
    CHECK_LIST,
    ELEMENT_TRANSFORMERS,
    MULTILINE_ELEMENT_TRANSFORMERS,
    TEXT_FORMAT_TRANSFORMERS,
    TEXT_MATCH_TRANSFORMERS,
} from '@lexical/markdown';
import { $convertFromMarkdownString, $convertToMarkdownString } from '@lexical/markdown';
import { InitialConfigType, LexicalComposer } from '@lexical/react/LexicalComposer';
import { ContentEditable } from '@lexical/react/LexicalContentEditable';
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary';
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin';
import { ListPlugin } from '@lexical/react/LexicalListPlugin';
import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin';
import { OnChangePlugin } from '@lexical/react/LexicalOnChangePlugin';
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin';
import { TabIndentationPlugin } from '@lexical/react/LexicalTabIndentationPlugin';
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
import { ListItemNode, ListNode } from '@lexical/list';
import { CodeNode } from '@lexical/code';
import { AutoLinkNode, LinkNode } from '@lexical/link';
import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode';
import { $getRoot, EditorState } from 'lexical';

import { editorTheme } from '@/components/editor/themes/editor-theme';
import { Separator } from '@/components/ui/separator';
import { HistoryToolbarPlugin } from '@/components/editor/plugins/toolbar/history-toolbar-plugin';
import { FontFormatToolbarPlugin } from '@/components/editor/plugins/toolbar/font-format-toolbar-plugin';
import { LinkToolbarPlugin } from '@/components/editor/plugins/toolbar/link-toolbar-plugin';
import { ClearFormattingToolbarPlugin } from '@/components/editor/plugins/toolbar/clear-formatting-toolbar-plugin';
import { BlockFormatDropDown } from '@/components/editor/plugins/toolbar/block-format-toolbar-plugin';
import { FormatParagraph } from '@/components/editor/plugins/toolbar/block-format/format-paragraph';
import { FormatHeading } from '@/components/editor/plugins/toolbar/block-format/format-heading';
import { FormatBulletedList } from '@/components/editor/plugins/toolbar/block-format/format-bulleted-list';
import { FormatNumberedList } from '@/components/editor/plugins/toolbar/block-format/format-numbered-list';
import { FormatQuote } from '@/components/editor/plugins/toolbar/block-format/format-quote';
import { ToolbarPlugin } from '@/components/editor/plugins/toolbar/toolbar-plugin';
import { ListToolbarPlugin } from '@/components/editor/plugins/toolbar/list-toolbar-plugin';
import { TooltipProvider } from '@/components/ui/tooltip';
import { LinkPlugin } from '@/components/editor/plugins/link-plugin';
import { AutoLinkPlugin } from '@/components/editor/plugins/auto-link-plugin';
import { FloatingLinkEditorPlugin } from '@/components/editor/plugins/floating-link-editor-plugin';
import { ClickableLinkPlugin } from '@lexical/react/LexicalClickableLinkPlugin';
import { HR } from '@/components/editor/transformers/markdown-hr-transformer';
import '@/components/editor/themes/editor-theme.css';

const TRANSFORMERS = [
    HR,
    CHECK_LIST,
    ...ELEMENT_TRANSFORMERS,
    ...MULTILINE_ELEMENT_TRANSFORMERS,
    ...TEXT_FORMAT_TRANSFORMERS,
    ...TEXT_MATCH_TRANSFORMERS,
];

interface RichTextEditorProps {
    name?: string;
    id?: string;
    defaultValue?: string;
    onChange?: (markdown: string) => void;
    placeholder?: string;
    disabled?: boolean;
}

// Plugin to handle markdown initialization
function MarkdownInitPlugin({ markdown }: { markdown: string }) {
    const [editor] = useLexicalComposerContext();
    const initialized = useRef(false);

    useEffect(() => {
        if (!initialized.current && markdown) {
            initialized.current = true;
            editor.update(() => {
                $convertFromMarkdownString(markdown, TRANSFORMERS, undefined, true);
            });
        }
    }, [editor, markdown]);

    return null;
}

// Plugin to sync markdown to hidden input
function MarkdownSyncPlugin({
    onChange,
    inputRef
}: {
    onChange?: (markdown: string) => void;
    inputRef: React.RefObject<HTMLInputElement | null>;
}) {
    const [editor] = useLexicalComposerContext();

    const handleChange = useCallback(
        (editorState: EditorState) => {
            editorState.read(() => {
                const markdown = $convertToMarkdownString(TRANSFORMERS, undefined, true);
                if (inputRef.current) {
                    inputRef.current.value = markdown;
                }
                onChange?.(markdown);
            });
        },
        [onChange, inputRef]
    );

    return <OnChangePlugin onChange={handleChange} ignoreSelectionChange />;
}

const editorConfig: InitialConfigType = {
    namespace: 'RichTextEditor',
    theme: editorTheme,
    nodes: [
        HeadingNode,
        QuoteNode,
        ListNode,
        ListItemNode,
        CodeNode,
        LinkNode,
        AutoLinkNode,
        HorizontalRuleNode,
    ],
    onError: (error: Error) => {
        console.error('Editor error:', error);
    },
};

export function RichTextEditor({
    name,
    id,
    defaultValue = '',
    onChange,
    placeholder = 'Start writing...',
    disabled = false,
}: RichTextEditorProps) {
    const inputRef = useRef<HTMLInputElement>(null);
    const [isLinkEditMode, setIsLinkEditMode] = useState(false);
    const [floatingAnchorElem, setFloatingAnchorElem] = useState<HTMLDivElement | null>(null);

    const onRef = useCallback((elem: HTMLDivElement | null) => {
        if (elem !== null) {
            setFloatingAnchorElem(elem);
        }
    }, []);

    return (
        <div className="relative">
            {/* Hidden input for form submission */}
            <input
                ref={inputRef}
                type="hidden"
                name={name}
                id={id}
                defaultValue={defaultValue}
            />

            <LexicalComposer initialConfig={editorConfig}>
                <TooltipProvider>
                    <div className="overflow-hidden rounded-lg border bg-background shadow-sm">
                        {/* Toolbar */}
                        <ToolbarPlugin>
                            {() => (
                                <div className="flex flex-wrap items-center gap-1 border-b bg-muted/30 p-1">
                                    <HistoryToolbarPlugin />
                                    <Separator orientation="vertical" className="!h-6 mx-1" />
                                    <BlockFormatDropDown>
                                        <FormatParagraph />
                                        <FormatHeading levels={['h1', 'h2', 'h3']} />
                                        <FormatBulletedList />
                                        <FormatNumberedList />
                                        <FormatQuote />
                                    </BlockFormatDropDown>
                                    <Separator orientation="vertical" className="!h-6 mx-1" />
                                    <FontFormatToolbarPlugin />
                                    <Separator orientation="vertical" className="!h-6 mx-1" />
                                    <ListToolbarPlugin />
                                    <Separator orientation="vertical" className="!h-6 mx-1" />
                                    <LinkToolbarPlugin setIsLinkEditMode={setIsLinkEditMode} />
                                    <Separator orientation="vertical" className="!h-6 mx-1" />
                                    <ClearFormattingToolbarPlugin />
                                </div>
                            )}
                        </ToolbarPlugin>

                        {/* Editor Content */}
                        <div className="relative" ref={onRef}>
                            <RichTextPlugin
                                contentEditable={
                                    <ContentEditable
                                        className="min-h-[200px] px-4 py-3 text-sm outline-none"
                                        aria-placeholder={placeholder}
                                        placeholder={
                                            <div className="pointer-events-none absolute left-4 top-3 text-sm text-muted-foreground">
                                                {placeholder}
                                            </div>
                                        }
                                    />
                                }
                                ErrorBoundary={LexicalErrorBoundary}
                            />

                            <HistoryPlugin />
                            <ListPlugin />
                            <TabIndentationPlugin />
                            <MarkdownShortcutPlugin transformers={TRANSFORMERS} />
                            <MarkdownInitPlugin markdown={defaultValue} />
                            <MarkdownSyncPlugin onChange={onChange} inputRef={inputRef} />
                            <LinkPlugin />
                            <AutoLinkPlugin />
                            <ClickableLinkPlugin />
                            <FloatingLinkEditorPlugin
                                anchorElem={floatingAnchorElem}
                                isLinkEditMode={isLinkEditMode}
                                setIsLinkEditMode={setIsLinkEditMode}
                            />
                        </div>
                    </div>
                </TooltipProvider>
            </LexicalComposer>
        </div>
    );
}
