import type { ActionContext, BlockActions, CommandItem } from '../../types';

export type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;

/**
 * heading1〜heading6 で共通する action/convert/isDisabled/isActive を生成する。
 * level だけ差し替えれば 6 種のすべての挙動が組み立てられる。
 */
export default function createHeadingActions(level: HeadingLevel) {
  return (cmd: CommandItem, ctx: ActionContext): BlockActions => ({
    action: (editor) => {
      ctx.recordUsage(cmd);
      editor.chain().focus().setHeading({ level }).run();
      const { $from } = editor.state.selection;
      const pos = $from.before($from.depth);
      editor.chain().focus().setBlockAttrs(pos, { class: cmd.class }).run();
    },
    convert: (editor, pos) => {
      const chain = editor.chain();
      chain.setNodeSelection(pos);
      chain.removeList(pos).removeBlockquote(pos).setHeading({ level }).run();
      const { $from } = editor.state.selection;
      const newPos = $from.before(1);
      editor.chain().focus().setBlockAttrs(newPos, { class: cmd.class }).run();
    },
    isDisabled: (editor) => {
      const isSame = cmd.class
        ? editor.isActive('heading', { level, class: cmd.class })
        : editor.isActive('heading', { level, class: null }) || editor.isActive('heading', { level, class: '' });
      // 同じ要素 + class なら disable
      if (isSame) {
        return true;
      }
      // 同じ要素だが class が違う場合 → enable
      if (editor.isActive('heading', { level })) {
        return false;
      }
      // それ以外は通常の can 判定
      return !editor.can().setHeading({ level });
    },
    isActive: (editor) => {
      if (cmd.class) {
        return editor.isActive('heading', { level, class: cmd.class });
      }
      return editor.isActive('heading', { level, class: null }) || editor.isActive('heading', { level, class: '' });
    },
  });
}
