/**
 * Callout Node Extension
 * 提示框/警告框节点
 */

import type { NodeSpec, Schema, Command, SlashMenuItem, InputRule } from '../../core/types';
import { NodeExtension } from '../../core/Extension';
import { textblockTypeInputRule } from 'prosemirror-inputrules';
import { setBlockType } from 'prosemirror-commands';
import { AlertCircle, Info, AlertTriangle, CheckCircle, XCircle } from 'lucide-react';

export type CalloutType = 'info' | 'warning' | 'success' | 'error' | 'note';

export interface CalloutOptions {
  /** 默认类型 */
  defaultType?: CalloutType;
}

const CALLOUT_TYPES: Record<CalloutType, { label: string; icon: typeof Info; color: string }> = {
  info: { label: '信息', icon: Info, color: 'blue' },
  warning: { label: '警告', icon: AlertTriangle, color: 'yellow' },
  success: { label: '成功', icon: CheckCircle, color: 'green' },
  error: { label: '错误', icon: XCircle, color: 'red' },
  note: { label: '提示', icon: AlertCircle, color: 'gray' },
};

export class Callout extends NodeExtension<CalloutOptions> {
  get name(): string {
    return 'callout';
  }

  get schema(): NodeSpec {
    return {
      attrs: {
        type: { default: this.options.defaultType || 'info' },
      },
      content: 'block+',
      group: 'block',
      defining: true,
      parseDOM: [
        {
          tag: 'div.editor-callout',
          getAttrs(dom: HTMLElement) {
            const type = dom.getAttribute('data-callout-type') || 'info';
            return { type };
          },
        },
      ],
      toDOM(node) {
        const { type } = node.attrs;
        return [
          'div',
          {
            class: `editor-callout editor-callout--${type}`,
            'data-callout-type': type,
          },
          ['div', { class: 'editor-callout__icon' }],
          ['div', { class: 'editor-callout__content' }, 0],
        ];
      },
    };
  }

  inputRules(schema: Schema): InputRule[] {
    const calloutType = schema.nodes.callout;
    if (!calloutType) return [];

    return [
      // ::: 或 :::info -> callout
      textblockTypeInputRule(/^:::\s*$/, calloutType, { type: 'info' }),
      textblockTypeInputRule(/^:::info\s*$/, calloutType, { type: 'info' }),
      textblockTypeInputRule(/^:::warning\s*$/, calloutType, { type: 'warning' }),
      textblockTypeInputRule(/^:::success\s*$/, calloutType, { type: 'success' }),
      textblockTypeInputRule(/^:::error\s*$/, calloutType, { type: 'error' }),
      textblockTypeInputRule(/^:::note\s*$/, calloutType, { type: 'note' }),
    ];
  }

  commands(schema: Schema): Record<string, Command> {
    const calloutType = schema.nodes.callout;
    if (!calloutType) return {};

    // 默认创建 info 类型的 callout
    return {
      setCallout: (state, dispatch) => {
        const { from, to } = state.selection;
        const tr = state.tr.setBlockType(from, to, calloutType, { type: 'info' });
        if (dispatch) dispatch(tr);
        return true;
      },
    };
  }

  slashMenuItems(schema: Schema): SlashMenuItem[] {
    const calloutType = schema.nodes.callout;
    if (!calloutType) return [];

    return [
      {
        name: 'callout-info',
        title: '信息提示',
        description: '插入信息提示框',
        icon: Info,
        keywords: ['callout', 'info', 'alert', '提示', '信息'],
        group: 'blocks',
        priority: 20,
        command: (state, dispatch) => {
          return setBlockType(calloutType, { type: 'info' })(state, dispatch);
        },
      },
      {
        name: 'callout-warning',
        title: '警告提示',
        description: '插入警告提示框',
        icon: AlertTriangle,
        keywords: ['callout', 'warning', 'alert', '警告'],
        group: 'blocks',
        priority: 21,
        command: (state, dispatch) => {
          return setBlockType(calloutType, { type: 'warning' })(state, dispatch);
        },
      },
      {
        name: 'callout-success',
        title: '成功提示',
        description: '插入成功提示框',
        icon: CheckCircle,
        keywords: ['callout', 'success', 'alert', '成功'],
        group: 'blocks',
        priority: 22,
        command: (state, dispatch) => {
          return setBlockType(calloutType, { type: 'success' })(state, dispatch);
        },
      },
      {
        name: 'callout-error',
        title: '错误提示',
        description: '插入错误提示框',
        icon: XCircle,
        keywords: ['callout', 'error', 'alert', '错误'],
        group: 'blocks',
        priority: 23,
        command: (state, dispatch) => {
          return setBlockType(calloutType, { type: 'error' })(state, dispatch);
        },
      },
    ];
  }
}

export default Callout;
