import { Extension, CommandProps } from '@tiptap/core'
import { Node as ProseMirrorNode } from '@tiptap/pm/model'

const INDENT_CLASS_NAME = 'text-indent'


// Вспомогательная функция для добавления/удаления CSS-класса
const toggleCssClass = (currentClasses: string | null | undefined, className: string): string | null => {
  const classes = new Set((currentClasses || '').split(' ').filter(Boolean))

  if (classes.has(className)) {
    classes.delete(className)
  } else {
    classes.add(className)
  }

  return classes.size > 0 ? Array.from(classes).join(' ') : null
}

export const Indent = Extension.create({
  name: 'indent',

  addCommands() {
    return {
      toggleIndent:
          () =>
              ({ tr, state, dispatch }: CommandProps): boolean => {
                const { selection } = state
                const { from, to } = selection
                let changed = false

                tr.doc.nodesBetween(from, to, (node: ProseMirrorNode, pos: number) => {
                  if (node.type.name === 'paragraph') {
                    const currentClasses = node.attrs.class as string | null | undefined
                    const newClasses = toggleCssClass(currentClasses, INDENT_CLASS_NAME)

                    if (newClasses !== currentClasses) {
                      tr.setNodeMarkup(pos, undefined, {
                        ...node.attrs,
                        class: newClasses,
                      })
                      changed = true
                    }
                  }
                  return false // Не углубляться
                })

                if (changed && dispatch) {
                  dispatch(tr.scrollIntoView())
                  return true
                }

                return false
              },
    }
  },

  // Можно убрать, если не используешь
  addStorage() {
    return {
      isActive: (state: any): boolean => {
        const { $from } = state.selection
        const node = $from.node($from.depth)
        if (node?.type.name === 'paragraph') {
          return (node.attrs.class || '').split(' ').includes(INDENT_CLASS_NAME)
        }
        return false
      },
    }
  },
})
