'use client'

import { useState, useEffect, useRef } from 'react'
import { Node, mergeAttributes } from '@tiptap/core'
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react'
import { List, X } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n'
import type { Editor } from '@tiptap/core'

interface HeadingEntry {
  id: string
  level: number
  text: string
  pos: number
}

function collectHeadings(editor: Editor): HeadingEntry[] {
  const headings: HeadingEntry[] = []
  editor.state.doc.descendants((node, pos) => {
    if (node.type.name === 'heading') {
      const level = node.attrs.level as number
      if (level >= 1 && level <= 3) {
        const text = node.textContent.trim()
        if (text) {
          headings.push({
            id: node.attrs['data-id'] || `heading-${pos}`,
            level,
            text,
            pos,
          })
        }
      }
    }
  })
  return headings
}

const OutlineView = ({ editor, deleteNode }: any) => {
  const { t } = useLanguage()
  const [headings, setHeadings] = useState<HeadingEntry[]>(() => collectHeadings(editor as Editor))

  // Re-collect headings when the editor content changes
  useEffect(() => {
    const update = () => setHeadings(collectHeadings(editor as Editor))
    editor.on('update', update)
    return () => { editor.off('update', update) }
  }, [editor])

  const scrollToHeading = (pos: number) => {
    const docSize = editor.state.doc.content.size
    const safePos = Math.min(pos + 1, docSize)
    editor.chain().focus().setTextSelection(safePos).scrollIntoView().run()
  }

  return (
    <NodeViewWrapper className="outline-block my-3 rounded-lg border border-border bg-muted/20" contentEditable={false} dir="auto">
      <div className="flex items-center justify-between px-3 py-2 border-b border-border/30">
        <div className="flex items-center gap-1.5">
          <List className="h-4 w-4 text-muted-foreground" />
          <span className="text-xs font-medium text-muted-foreground">
            {t('richTextEditor.outlineTitle')}
          </span>
        </div>
        <button
          onClick={deleteNode}
          className="p-0.5 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
          title={t('richTextEditor.outlineDelete')}
        >
          <X className="h-3.5 w-3.5" />
        </button>
      </div>
      <div className="px-3 py-2.5 overflow-hidden">
        {headings.length === 0 ? (
          <p className="text-sm text-muted-foreground italic">
            {t('richTextEditor.outlineEmpty')}
          </p>
        ) : (
          <nav className="space-y-0.5">
            {headings.map((h, i) => {
              const indent = (h.level - 1) * 20
              return (
                <div
                  key={`${h.id}-${i}`}
                  style={{ paddingLeft: `${indent}px` }}
                  className={cn(
                    'group flex items-center gap-2 rounded-md px-2 py-1 transition-colors hover:bg-foreground/5 cursor-pointer min-w-0',
                  )}
                  onClick={() => scrollToHeading(h.pos)}
                >
                  <span
                    className={cn(
                      'flex-shrink-0 rounded-full',
                      h.level === 1 && 'w-1.5 h-1.5 bg-foreground/60',
                      h.level === 2 && 'w-1.5 h-1.5 border border-foreground/40',
                      h.level === 3 && 'w-1 h-1 bg-foreground/30',
                    )}
                  />
                  <span className={cn(
                    'text-sm leading-snug break-words min-w-0 flex-1 transition-colors',
                    h.level === 1 && 'font-semibold',
                    h.level === 2 && 'font-medium text-foreground/80',
                    h.level === 3 && 'text-foreground/60',
                  )}>
                    {h.text}
                  </span>
                </div>
              )
            })}
          </nav>
        )}
      </div>
    </NodeViewWrapper>
  )
}

export const OutlineExtension = Node.create({
  name: 'outlineBlock',

  group: 'block',

  atom: true,

  defining: true,

  parseHTML() {
    return [
      { tag: 'div[data-type="outline-block"]' },
    ]
  },

  renderHTML({ HTMLAttributes }) {
    return [
      'div',
      mergeAttributes(HTMLAttributes, {
        'data-type': 'outline-block',
        class: 'outline-block',
      }),
    ]
  },

  addNodeView() {
    return ReactNodeViewRenderer(OutlineView)
  },
})

export function insertOutlineBlock(editor: any) {
  editor.chain().focus().insertContent({
    type: 'outlineBlock',
  }).run()
}
