import * as A from "fp-ts-esm/Array";
import { pipe } from "fp-ts-esm/function";
import lodash from "lodash";
import { collectPmConverters } from "./../pm-converters/collect.js";
import { commonPluginConfig, commonPlugins } from "./../ricos-common-plugins/index.js";
import { editorQueryCreator } from "./../ricos-content-query/index.js";
import { isCommonPluginOptions } from "./../ricos-editor/utils/is-editor-plugin.js";
import { RicosEvents } from "./../ricos-events/index.js";
import { EditorPlugins, PluginsEvents } from "./../ricos-plugins/index.js";
import { EditorKeyboardShortcuts } from "./../ricos-shortcuts/index.js";
import { RicosStyles, ZIndexService } from "./../ricos-styles/index.js";
import { logInvariant } from "./../_shared/log-invariant.js";
import { createUpdateService } from "./../_shared/upload/update-service.js";
import { UploadService } from "./../_shared/upload/upload-service.js";
import { getLangDir, isSSR } from "./../wix-rich-content-common/index.js";
import {
  Content,
  FLOATING_FORMATTING_TOOLBAR,
  FLOATING_PLUGIN_TOOLBAR,
  STATIC_TOOLBAR_DATA_HOOK,
  TOOLBAR_VISIBLE
} from "./../toolbars-v3/index.js";
import { getHelpersConfig } from "./helpers-config.js";
import { mapBiCallbacksToSubscriptions } from "./map-bi-callbacks-to-events.js";
import { registerEventSources, registerEventSubscribers } from "./orchestrate-events.js";
import { RicosEditor } from "./ricos-editor.js";
import { RicosSchema } from "./ricos-schema.js";
class RicosOrchestrator {
  constructor({
    editorProps,
    t,
    platform,
    modalService,
    devService,
    wixInstance,
    makeRequestService,
    pluginsMap
  }) {
    /** Mutable ref updated by FullRicosEditor when BI helpers load asynchronously. */
    this.biHelpersRef = { current: {} };
    this.inlineAiService = {};
    this.inlineAiStateSelectorContextValue = void 0;
    this.toolbarStateSelectorContextValue = void 0;
    this.selectionSelectorContextValue = void 0;
    this.modalStateSelectorContextValue = void 0;
    this.pmContentSelectorContextValue = void 0;
    this.t = t;
    this.editorProps = editorProps;
    this.devService = devService;
    this.wixInstance = wixInstance;
    this.makeRequestService = makeRequestService;
    this.pluginsMap = pluginsMap;
    this.styles = new RicosStyles();
    const getEditorQuery = () => {
      return this.editorQuery;
    };
    this.converters = collectPmConverters(collectAllPlugins(this.editorProps, pluginsMap));
    this.content = Content.create([], {
      styles: this.styles,
      converters: this.converters,
      getEditorQuery,
      editor: null,
      modals: modalService
    });
    const isMobile = editorProps.isMobile || false;
    this.context = {
      t,
      debugMode: editorProps.debugMode || [],
      isMobile,
      languageDir: getLangDir(editorProps.locale),
      locale: editorProps.locale || "en",
      localeContent: editorProps.localeContent || editorProps.locale || "en",
      experiments: editorProps.experiments || {},
      platform: platform || "macOs",
      content: this.content,
      jsdomMode: editorProps.jsdomMode ?? false,
      environment: editorProps.environment || "liveSite",
      tabIndex: -1,
      portal: null,
      lastInteraction: null,
      tabFocusBehavior: editorProps.tabFocusBehavior || "edit"
    };
    this.updateService = createUpdateService();
    this.events = new RicosEvents(
      (editorProps.debugMode?.includes("events") || editorProps.debugMode?.includes("all")) ?? false
    );
    this.uploadService = new UploadService(this.updateService);
    this.modals = modalService;
    this.shortcuts = new EditorKeyboardShortcuts(this.modals, {
      isDebugMode: (editorProps.debugMode?.includes("shortcuts") || editorProps.debugMode?.includes("all")) ?? false
    });
    this.pluginsEvents = new PluginsEvents();
    this.schema = new RicosSchema(
      editorProps.content,
      this.converters,
      editorProps.shouldNormalizeRichContent ?? true
    );
    const focusShortcut = {
      name: "EnterToolbar",
      description: "ShortcutsSheet_ToolbarNavigation_EnterToolbar",
      group: "ShortcutsSheet_Section_ToolbarNavigation",
      keys: { macOs: "Ctrl+T", windows: "Alt+T" },
      command: ({ event }) => {
        event?.preventDefault();
        const focusFirstFocusableElement = (toolbarDataHook) => {
          const portalElement = this.context.portal || document;
          const toolbarElement = portalElement.querySelector(
            `[data-hook~=${toolbarDataHook}] [data-hook~=${TOOLBAR_VISIBLE}]`
          );
          const firstFocusableElement = toolbarElement?.querySelector(
            'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), details, [tabindex]:not([tabindex="-1"]):not([disabled])'
          );
          firstFocusableElement?.focus();
        };
        focusFirstFocusableElement(FLOATING_FORMATTING_TOOLBAR);
        focusFirstFocusableElement(STATIC_TOOLBAR_DATA_HOOK);
        focusFirstFocusableElement(FLOATING_PLUGIN_TOOLBAR);
        return "continue";
      },
      enabled: true,
      showInShortcutSheet: true
    };
    this.shortcuts.register(focusShortcut);
    this.plugins = new EditorPlugins({
      modals: this.modals,
      uploadService: this.uploadService,
      updateService: this.updateService,
      shortcuts: this.shortcuts,
      t: this.t,
      content: this.content,
      styles: this.styles,
      pluginsEvents: this.pluginsEvents,
      context: this.context,
      schema: this.schema,
      converters: this.converters,
      devService,
      editorProps: this.editorProps,
      wixInstance,
      makeRequestService
    });
    this.registerAllPlugins(commonPluginConfig);
    if (editorProps.keyboardShortcuts) {
      editorProps.keyboardShortcuts.map(
        (shortcut) => this.shortcuts.mergeKeyboadShortcutProp(shortcut)
      );
    }
    this.editor = new RicosEditor(
      this.editorProps,
      {
        styles: this.styles,
        plugins: this.plugins,
        updateService: this.updateService,
        uploadService: this.uploadService,
        t: this.t,
        content: this.content,
        shortcuts: this.shortcuts,
        modals: this.modals,
        pluginsEvents: this.pluginsEvents,
        context: this.context,
        schema: this.schema,
        getEditorQuery,
        converters: this.converters,
        devService,
        editorProps: this.editorProps,
        wixInstance,
        makeRequestService,
        inlineAi: this.inlineAiService
      },
      this.editorProps.debugMode?.includes("prosemirror") || editorProps.debugMode?.includes("all"),
      () => {
        if (!this.toolbarStateSelectorContextValue) {
          throw new Error("toolbarStateSelectorContextValue is not set");
        }
        return this.toolbarStateSelectorContextValue;
      },
      () => {
        if (!this.selectionSelectorContextValue) {
          throw new Error("selectionSelectorContextValue is not set");
        }
        return this.selectionSelectorContextValue;
      },
      () => {
        if (!this.modalStateSelectorContextValue) {
          throw new Error("modalStateSelectorContextValue is not set");
        }
        return this.modalStateSelectorContextValue;
      },
      () => {
        if (!this.pmContentSelectorContextValue) {
          throw new Error("pmContentSelectorContextValue is not set");
        }
        return this.pmContentSelectorContextValue;
      },
      () => {
        if (!this.inlineAiStateSelectorContextValue) {
          throw new Error("inlineAiStateSelectorContextValue is not set");
        }
        return this.inlineAiStateSelectorContextValue;
      }
    );
    this.plugins.setPublicCommands(this.editor.getPublicCommands());
    this.schema.setEditor(this.editor);
    this.content.update([], this.editor.adapter.tiptapEditor);
    this.updateService.setEditorCommands(this.editor.getPublicCommands());
    this.editorQuery = editorQueryCreator(
      this.editor.adapter.tiptapEditor,
      this.styles,
      this.converters
    );
    this.pluginExports = this.plugins.getExports();
    this.zIndexService = new ZIndexService(
      !!editorProps.isMobile,
      editorProps.theme?.settingsStyles
    );
    if (!isSSR()) {
      window.editorQuery = this.editorQuery;
      window.ricosOrchestrator = this;
    }
    this.orchestrateEvents();
  }
  // NOTE: it is crucual to keep the event registration/subsciption order to ensure their correct workflow
  orchestrateEvents() {
    registerEventSources(this.events, [
      this.shortcuts,
      this.modals,
      this.editor,
      this.uploadService,
      this.pluginsEvents,
      this.styles
    ]);
    registerEventSubscribers(this.events, [this.modals]);
    registerEventSubscribers(this.events, [
      this.modals,
      this.editor,
      this.styles,
      this.pluginsEvents
    ]);
    mapBiCallbacksToSubscriptions(this.biHelpersRef, this.events, this.schema);
  }
  setUpdateServiceDom(setErrorNotifier, setFileInput) {
    this.uploadService.setErrorNotifier(setErrorNotifier);
    this.uploadService.setHiddenInputElement(setFileInput);
  }
  getServices() {
    return {
      styles: this.styles,
      plugins: this.plugins,
      uploadService: this.uploadService,
      updateService: this.updateService,
      t: this.t,
      shortcuts: this.shortcuts,
      content: this.content,
      modals: this.modals,
      editor: this.editor,
      pluginsEvents: this.pluginsEvents,
      context: this.context,
      schema: this.schema,
      zIndexService: this.zIndexService,
      getEditorQuery: () => this.editorQuery,
      converters: this.converters,
      devService: this.devService,
      editorProps: this.editorProps,
      wixInstance: this.wixInstance,
      makeRequestService: this.makeRequestService,
      inlineAi: this.inlineAiService
    };
  }
  getPluginExports() {
    return this.pluginExports;
  }
  registerAllPlugins(commonPluginConfig2) {
    const helpersConfig = getHelpersConfig(this.editorProps);
    pipe(
      collectAllPlugins(this.editorProps, this.pluginsMap),
      EditorPlugins.mergeConfig(this.editorProps.pluginConfig),
      EditorPlugins.mergeConfig(commonPluginConfig2),
      EditorPlugins.mergeConfig(helpersConfig),
      A.map((plugin) => this.plugins.register(plugin))
    );
  }
  setPortalRef(portal) {
    this.context.portal = portal;
  }
}
const collectAllPlugins = (editorProps, pluginsMap) => {
  const { plugins } = editorProps;
  const collectPluginsWithDependencies = (plugins2) => plugins2.flatMap((plugin) => [
    plugin,
    ...plugin.dependencies ? collectPluginsWithDependencies(plugin.dependencies) : []
  ]);
  const allOptions = plugins || [];
  const commonOptions = allOptions.filter(isCommonPluginOptions);
  const pluginOptions = allOptions.filter((opt) => !isCommonPluginOptions(opt));
  const resolvedPlugins = pluginOptions.map((options) => {
    if ("tiptapExtensions" in options) {
      return options;
    }
    const creator = pluginsMap[options.type];
    if (!creator) {
      logInvariant(new Error(`Unknown plugin type: ${options.type}. No resolver registered.`));
      return void 0;
    }
    return creator(options);
  });
  const collectedPlugins = collectPluginsWithDependencies([
    ...commonPlugins(editorProps, commonOptions),
    ...resolvedPlugins.filter((p) => !!p)
  ]);
  return lodash.uniq(collectedPlugins);
};
export {
  RicosOrchestrator
};
//# sourceMappingURL=ricos-orchestrator.js.map
