/**
 * SlashMenu Plugin
 * 斜杠菜单插件 - 监听 / 输入并触发菜单
 */

import { Plugin, PluginKey } from 'prosemirror-state';
import type { Schema } from 'prosemirror-model';
import { PluginExtension } from '../../core/Extension';
import type { EditorView } from 'prosemirror-view';

export interface SlashMenuPluginOptions {
  onOpen?: (position: { top: number; left: number }, query: string) => void;
  onClose?: () => void;
  onQueryChange?: (query: string) => void;
}

export const slashMenuPluginKey = new PluginKey('slashMenu');

export class SlashMenuPlugin extends PluginExtension<SlashMenuPluginOptions> {
  get name() {
    return 'slashMenuPlugin';
  }

  plugins(_schema: Schema): Plugin[] {
    const options = this.options;

    return [
      new Plugin({
        key: slashMenuPluginKey,
        state: {
          init() {
            return {
              active: false,
              query: '',
              from: 0,
            };
          },
          apply(tr, value) {
            const meta = tr.getMeta(slashMenuPluginKey);
            if (meta !== undefined) {
              return meta;
            }
            // 如果文档变化，检查是否需要更新
            if (tr.docChanged && value.active) {
              return value;
            }
            return value;
          },
        },
        view() {
          return {
            update(view: EditorView) {
              const { state } = view;
              const { selection } = state;
              const { $from } = selection;

              // 只在光标位置处理
              if (!selection.empty) {
                options.onClose?.();
                return;
              }

              // 获取当前行文本
              const textBefore = $from.parent.textBetween(
                0,
                $from.parentOffset,
                undefined,
                '\ufffc'
              );

              // 查找最后一个 /
              const slashIndex = textBefore.lastIndexOf('/');

              if (slashIndex === -1) {
                options.onClose?.();
                return;
              }

              // 检查 / 前面是否是空格或行首
              const charBeforeSlash = slashIndex > 0 ? textBefore[slashIndex - 1] : '';
              if (slashIndex > 0 && charBeforeSlash !== ' ' && charBeforeSlash !== '\n') {
                options.onClose?.();
                return;
              }

              // 获取查询文本
              const query = textBefore.slice(slashIndex + 1);

              // 如果查询中包含空格，关闭菜单
              if (query.includes(' ')) {
                options.onClose?.();
                return;
              }

              // 计算菜单位置
              const coords = view.coordsAtPos($from.pos);
              const editorRect = view.dom.getBoundingClientRect();

              // 菜单显示在光标下方
              const position = {
                top: coords.bottom + 8,
                left: Math.max(coords.left, editorRect.left),
              };

              // 确保菜单不超出视口
              const viewportWidth = window.innerWidth;
              const viewportHeight = window.innerHeight;
              const menuWidth = 288; // 菜单宽度
              const menuHeight = 320; // 菜单大概高度

              if (position.left + menuWidth > viewportWidth) {
                position.left = viewportWidth - menuWidth - 16;
              }

              if (position.top + menuHeight > viewportHeight) {
                position.top = coords.top - menuHeight - 8;
              }

              options.onOpen?.(position, query);
              options.onQueryChange?.(query);
            },
          };
        },
        props: {
          handleKeyDown(view, event) {
            const pluginState = slashMenuPluginKey.getState(view.state);

            // 如果菜单打开，阻止某些按键的默认行为
            if (pluginState?.active) {
              if (['ArrowUp', 'ArrowDown', 'Enter', 'Escape'].includes(event.key)) {
                // 这些按键由 SlashMenu 组件处理
                return false;
              }
            }

            return false;
          },
        },
      }),
    ];
  }
}

export default SlashMenuPlugin;
