import { useState, useLayoutEffect, useEffect, useRef, memo } from "react";
import { useTranslation } from "react-i18next";
import { MagicdownEditor } from "@xiangfa/mdeditor";
import View from "./View";
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable";
import { useMobile } from "@/hooks/useMobile";
import { cn } from "@/utils/style";

import "./style.css";

type EditorProps = {
  className?: string;
  defaultValue: string;
  hideView?: boolean;
  onChange: (value: string) => void;
};

function Editor({
  className,
  defaultValue,
  onChange,
  hideView = false,
}: EditorProps) {
  const { t } = useTranslation();
  const isMobile = useMobile(750);
  const markdownEditorRef = useRef<HTMLDivElement>(null);
  const [markdownEditor, setMarkdownEditor] = useState<MagicdownEditor>();
  const [content, setContent] = useState<string>(defaultValue);

  // Update editor content when external data changes, such as data streams received from a server
  useEffect(() => {
    if (markdownEditor?.status === "created") {
      markdownEditor.update(defaultValue);
    }
  }, [markdownEditor, defaultValue]);

  // Initialize the Markdown editor
  useLayoutEffect(() => {
    const editor = new MagicdownEditor({
      root: markdownEditorRef.current,
      defaultValue: "",
      placeholder: t("editor.placeholder"),
      onChange: (value) => {
        setContent(value);
      },
      i18n: {
        tooltip: {
          bold: t("editor.tooltip.bold"),
          italic: t("editor.tooltip.italic"),
          strikethrough: t("editor.tooltip.strikethrough"),
          link: t("editor.tooltip.link"),
          code: t("editor.tooltip.code"),
          math: t("editor.tooltip.math"),
          quote: t("editor.tooltip.quote"),
        },
        slash: {
          heading: {
            name: t("editor.slash.heading.name"),
            description: t("editor.slash.heading.description"),
          },
          h1: {
            name: t("editor.slash.h1.name"),
            description: t("editor.slash.h1.description"),
          },
          h2: {
            name: t("editor.slash.h2.name"),
            description: t("editor.slash.h2.description"),
          },
          h3: {
            name: t("editor.slash.h3.name"),
            description: t("editor.slash.h3.description"),
          },
          h4: {
            name: t("editor.slash.h4.name"),
            description: t("editor.slash.h4.description"),
          },
          h5: {
            name: t("editor.slash.h5.name"),
            description: t("editor.slash.h5.description"),
          },
          h6: {
            name: t("editor.slash.h6.name"),
            description: t("editor.slash.h6.description"),
          },
          list: {
            name: t("editor.slash.list.name"),
            description: t("editor.slash.list.description"),
          },
          ul: {
            name: t("editor.slash.ul.name"),
            description: t("editor.slash.ul.description"),
          },
          ol: {
            name: t("editor.slash.ol.name"),
            description: t("editor.slash.ol.description"),
          },
          todo: {
            name: t("editor.slash.todo.name"),
            description: t("editor.slash.todo.description"),
          },
          advanced: {
            name: t("editor.slash.advanced.name"),
            description: t("editor.slash.advanced.description"),
          },
          link: {
            name: t("editor.slash.link.name"),
            description: t("editor.slash.link.description"),
          },
          image: {
            name: t("editor.slash.image.name"),
            description: t("editor.slash.image.description"),
          },
          code: {
            name: t("editor.slash.code.name"),
            description: t("editor.slash.code.description"),
          },
          math: {
            name: t("editor.slash.math.name"),
            description: t("editor.slash.math.description"),
          },
          table: {
            name: t("editor.slash.table.name"),
            description: t("editor.slash.table.description"),
          },
          quote: {
            name: t("editor.slash.quote.name"),
            description: t("editor.slash.quote.description"),
          },
          horizontal: {
            name: t("editor.slash.horizontal.name"),
            description: t("editor.slash.horizontal.description"),
          },
        },
        placeholder: t("editor.placeholder"),
      },
    });

    editor.create().then(() => {
      setMarkdownEditor(editor);
    });

    return () => {
      editor.destroy();
    };
  }, [t]);

  return (
    <ResizablePanelGroup
      className="flex rounded-md border"
      direction="horizontal"
    >
      <ResizablePanel>
        <div
          className={cn(
            "relative flex-1 text-base whitespace-break-spaces p-1.5",
            className
          )}
          ref={markdownEditorRef}
          onBlur={() => onChange(content)}
        ></div>
      </ResizablePanel>
      {isMobile || hideView ? null : (
        <>
          <ResizableHandle />
          <ResizablePanel>
            <div className="magicdown-view flex-1 prose prose-slate dark:prose-invert overflow-auto max-w-full p-2">
              <View>{content}</View>
            </div>
          </ResizablePanel>
        </>
      )}
    </ResizablePanelGroup>
  );
}

export default memo(Editor);
