import { SparklesSmall } from "@wix/wix-ui-icons-common";
import React from "react";
import { Node_Type, quickActionsModalSections } from "./../ricos-types/index.js";
import { getIsEditorEmpty } from "./../_shared/get-is-editor-empty.js";
import { logInvariant } from "./../_shared/log-invariant.js";
import { getFakeReferenceElement } from "./../_shared/pos-to-dom-rect.js";
import { quickActionsPluginKey } from "./../_shared/quick-actions-plugin-key.js";
import { isAlwaysVisible } from "./../_shared/resolvers/is-always-visible.js";
import { TOP_LEVEL_NODES } from "./../_shared/top-level-nodes.js";
import { Plugin, PluginKey } from "./../tiptap/pm/state.js";
import { createRicosFunctionalExtension } from "./../tiptap-extensions/index.js";
import { aiRegion } from "./ai-region-extension.js";
import { AiSelectionTooltip } from "./ai-selection-tooltip.js";
import { CursorContext } from "./cursor-context.js";
import { InlineAiContextProvider } from "./inline-ai-context-provider.js";
import { AiModalNg, INLINE_AI_MODAL_ID, StreamingCursor } from "./modal.js";
import { openInlineAIModal } from "./open-inline-ai-modal.js";
import { ToolbarButtonSmall } from "./toolbar/toolbar-button-small.js";
import { ToolbarButton } from "./toolbar/toolbar-button.js";
import { INLINE_AI_PLUGIN_TYPE } from "./types.js";
const pluginInlineAi = (config) => {
  const inlinePromptEnabled = !config?.disableInlinePrompt;
  const GlobalComponents = () => {
    const cursorCtx = React.useContext(CursorContext);
    return /* @__PURE__ */ React.createElement(React.Fragment, null, inlinePromptEnabled && config?.enableSelectionTooltip && /* @__PURE__ */ React.createElement(AiSelectionTooltip, { interceptInlinePrompt: config?.interceptInlinePrompt }), cursorCtx?.cursorState.showCursor && /* @__PURE__ */ React.createElement(StreamingCursor, null));
  };
  return {
    config: { type: "inlineAi", ...config },
    type: INLINE_AI_PLUGIN_TYPE,
    Provider: InlineAiContextProvider,
    GlobalComponent: GlobalComponents,
    getQuickActions: () => inlinePromptEnabled ? [
      {
        id: "mainAI",
        title: "QuickActionsPlugin_ActionTitle_InlineAI",
        icon: SparklesSmall,
        section: quickActionsModalSections.AI,
        tags: [" ", "ai", "write", "automated"],
        command: ({ editor, modalService }) => {
          const { view } = editor;
          const rootLevelNodePosition = view.state.selection.$from.before(1);
          const nodeDOM = view.nodeDOM(rootLevelNodePosition);
          const referenceElement = nodeDOM instanceof Element ? nodeDOM : view.dom;
          editor.commands.setNodeSelection(rootLevelNodePosition);
          openInlineAIModal({
            editor,
            modalService,
            interceptInlinePrompt: config?.interceptInlinePrompt,
            generatingLabel: config?.generatingLabel,
            positioning: {
              referenceElement: {
                getBoundingClientRect: () => referenceElement.getBoundingClientRect(),
                focus: () => view.focus()
              },
              placement: "bottom"
            }
          });
          return true;
        }
      }
    ] : [],
    exports: {
      modals: inlinePromptEnabled ? {
        INLINE_AI: (editor, services) => openInlineAIModal({
          editor,
          modalService: services.modals,
          interceptInlinePrompt: config?.interceptInlinePrompt,
          generatingLabel: config?.generatingLabel
        })
      } : {}
    },
    textButtons: inlinePromptEnabled ? [
      {
        id: "wix-rich-content-plugin-ai",
        type: "modal",
        presentation: {
          dataHook: "text-button-ai",
          tooltip: "AIPlugin_ToolbarButton_Tooltip",
          component: (props) => /* @__PURE__ */ React.createElement(ToolbarButton, { ...props, showLabel: true }),
          icon: (props) => /* @__PURE__ */ React.createElement(ToolbarButtonSmall, { ...props, showLabel: true })
          // Rendering in external toolbar
        },
        attributes: {
          visible: isAlwaysVisible
        },
        command: ({ editor, modalService }) => () => {
          const { view } = editor;
          const rootLevelNodePosition = view.state.selection.$from.before(1);
          const nodeDOM = view.nodeDOM(rootLevelNodePosition);
          const referenceElement = nodeDOM instanceof Element ? nodeDOM : view.dom;
          openInlineAIModal({
            editor,
            modalService,
            interceptInlinePrompt: config?.interceptInlinePrompt,
            generatingLabel: config?.generatingLabel,
            positioning: {
              placement: "top",
              referenceElement: {
                getBoundingClientRect: () => referenceElement.getBoundingClientRect(),
                focus: () => view.focus()
              }
            }
          });
          return true;
        }
      }
    ] : [],
    tiptapExtensions: [
      aiRegion,
      createRicosFunctionalExtension({
        name: "inline-ai",
        type: "extension",
        groups: [],
        placeholder: {
          priority: 200,
          predicate: ({ doc, selection, node, pos, editor, isMobile }) => {
            if (!inlinePromptEnabled || isMobile) {
              return false;
            }
            const $pos = doc.resolve(pos);
            const isEditorEmpty = getIsEditorEmpty(doc);
            if (isEditorEmpty && !editor.isFocused) {
              return false;
            }
            const isEmptyTopLevelParagraph = TOP_LEVEL_NODES.includes($pos.parent.type.name) && !selection.$head.nodeBefore && !selection.$head.nodeAfter && node.type.name === Node_Type.PARAGRAPH;
            const isEmpty = !node.isLeaf && !node.childCount;
            const isSelected = selection.from - 1 === pos && selection.to + 1 === pos + node.nodeSize;
            return isEmptyTopLevelParagraph && isEmpty && isSelected;
          },
          content: "InlineAiPlugin_EditorPlaceholder"
        },
        reconfigure: (config2, _extensions, _ricosProps, _settings, services) => {
          return {
            ...config2,
            addOptions: () => {
              return { services };
            }
          };
        },
        createExtensionConfig() {
          return {
            name: "inline-ai",
            priority: 110,
            addProseMirrorPlugins() {
              return [
                new Plugin({
                  key: new PluginKey("inline-ai"),
                  props: {
                    handleKeyDown: (view, event) => {
                      if (!inlinePromptEnabled) {
                        return false;
                      }
                      const modalService = this.options.services.modals;
                      const spacePressed = event.key === " ";
                      if (!spacePressed || this.options.services.context.isMobile) {
                        return false;
                      }
                      if (event.shiftKey || event.altKey) {
                        return false;
                      }
                      if (!view.state.selection.empty) {
                        openInlineAIModal({
                          editor: this.editor,
                          modalService,
                          interceptInlinePrompt: config?.interceptInlinePrompt,
                          generatingLabel: config?.generatingLabel
                        });
                        return true;
                      }
                      const quickActionsState = quickActionsPluginKey.getState(view.state);
                      const $from = view.state.selection.$from;
                      let depth = 1;
                      while (depth < $from.depth && TOP_LEVEL_NODES.includes($from.node(depth).type.name)) {
                        depth += 1;
                      }
                      const rootLevelNodeUnderCursor = $from.node(depth);
                      const rootLevelNodePosition = $from.before(depth);
                      const quickActionsTrigger = quickActionsState && quickActionsState.active && quickActionsState.text === "/";
                      if (quickActionsTrigger) {
                        view.dispatch(
                          view.state.tr.delete(
                            quickActionsState.range.from,
                            quickActionsState.range.to
                          )
                        );
                      }
                      if (predicate({
                        doc: view.state.doc,
                        selection: view.state.selection,
                        node: rootLevelNodeUnderCursor,
                        pos: rootLevelNodePosition,
                        editor: this.editor
                      })) {
                        const nodeDOM = view.nodeDOM(rootLevelNodePosition);
                        const referenceElement = nodeDOM instanceof Element ? nodeDOM : view.dom;
                        this.editor.commands.setNodeSelection(rootLevelNodePosition);
                        modalService.openModal({
                          id: INLINE_AI_MODAL_ID,
                          Component: AiModalNg,
                          componentProps: {
                            interceptInlinePrompt: config?.interceptInlinePrompt,
                            onThemeChange: config?.onThemeChange,
                            getCurrentTheme: config?.getCurrentTheme,
                            generatingLabel: config?.generatingLabel
                          },
                          type: "exclusive",
                          layout: "manual",
                          positioning: {
                            referenceElement: {
                              getBoundingClientRect: () => referenceElement.getBoundingClientRect(),
                              focus: () => view.focus()
                            },
                            placement: "overlay"
                          },
                          returnFocusToEditor: false
                        });
                        return true;
                      }
                      if (quickActionsTrigger) {
                        modalService.openModal({
                          id: INLINE_AI_MODAL_ID,
                          Component: AiModalNg,
                          componentProps: {
                            interceptInlinePrompt: config?.interceptInlinePrompt,
                            onThemeChange: config?.onThemeChange,
                            getCurrentTheme: config?.getCurrentTheme,
                            generatingLabel: config?.generatingLabel
                          },
                          layout: "manual",
                          type: "exclusive",
                          positioning: {
                            referenceElement: getFakeReferenceElement(this.editor),
                            placement: "bottom"
                          },
                          returnFocusToEditor: false
                        });
                        return true;
                      }
                    }
                  }
                })
              ];
            },
            addCommands() {
              return {
                triggerInlineAi: ({
                  prompt,
                  selection,
                  modalConfig,
                  acceptByDefault = false,
                  invocationId,
                  headless,
                  onDone,
                  files,
                  traceParams,
                  systemPromptId
                }) => ({ tr, dispatch }) => {
                  const modalService = this.options.services.modals;
                  const inlineAiService = this.options.services.inlineAi;
                  const _invocationId = invocationId || crypto.randomUUID();
                  if (!inlineAiService.executePrompt) {
                    logInvariant(new Error("Inline AI service is not available"));
                    return true;
                  }
                  const document = this.options.services.schema.getContent();
                  inlineAiService.executePrompt({
                    prompt,
                    selection,
                    invocationId: _invocationId,
                    files,
                    onThemeChange: config?.onThemeChange,
                    getCurrentTheme: config?.getCurrentTheme,
                    document,
                    traceParams,
                    systemPromptId
                  });
                  modalService.openModal({
                    id: INLINE_AI_MODAL_ID,
                    Component: AiModalNg,
                    componentProps: {
                      acceptByDefault,
                      invocationId: _invocationId,
                      headless,
                      onThemeChange: config?.onThemeChange,
                      getCurrentTheme: config?.getCurrentTheme,
                      onDone,
                      interceptInlinePrompt: config?.interceptInlinePrompt,
                      generatingLabel: config?.generatingLabel
                    },
                    type: "exclusive",
                    layout: "manual",
                    positioning: {
                      referenceElement: getFakeReferenceElement(this.editor)
                    },
                    returnFocusToEditor: false,
                    ...modalConfig
                  });
                  if (dispatch) {
                    dispatch(tr);
                  }
                  return true;
                }
              };
            }
          };
        }
      })
    ]
  };
};
const predicate = ({
  doc,
  selection,
  node,
  pos,
  editor
}) => {
  const $pos = doc.resolve(pos);
  if (getIsEditorEmpty(doc) && !editor.isFocused) {
    return false;
  }
  const isEmptyTopLevelParagraph = TOP_LEVEL_NODES.includes($pos.parent.type.name) && !selection.$head.nodeBefore && !selection.$head.nodeAfter && (node.type.name === Node_Type.PARAGRAPH || node.type.name === Node_Type.HEADING);
  const isEmpty = !node.isLeaf && !node.childCount;
  const isSelected = selection.from - 1 === pos && selection.to + 1 === pos + node.nodeSize;
  return isEmptyTopLevelParagraph && isEmpty && isSelected;
};
export {
  pluginInlineAi
};
//# sourceMappingURL=editor.js.map
