'use client'

import { Node, mergeAttributes } from '@tiptap/core'
import { ReactNodeViewRenderer, NodeViewWrapper, NodeViewContent } from '@tiptap/react'
import { Info, AlertTriangle, Lightbulb, CheckCircle, XCircle, Trash2, X } from 'lucide-react'
import { useState } from 'react'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n'

type CalloutType = 'info' | 'warning' | 'tip' | 'success' | 'danger'

const CALLOUT_STYLES: Record<CalloutType, { bg: string; border: string; icon: string; iconColor: string }> = {
  info:    { bg: 'bg-blue-50 dark:bg-blue-950/30',       border: 'border-blue-300 dark:border-blue-800',   icon: 'text-blue-500',       iconColor: 'text-blue-500' },
  warning: { bg: 'bg-amber-50 dark:bg-amber-950/30',     border: 'border-amber-300 dark:border-amber-800', icon: 'text-amber-500',      iconColor: 'text-amber-500' },
  tip:     { bg: 'bg-purple-50 dark:bg-purple-950/30',   border: 'border-purple-300 dark:border-purple-800', icon: 'text-purple-500',   iconColor: 'text-purple-500' },
  success: { bg: 'bg-green-50 dark:bg-green-950/30',     border: 'border-green-300 dark:border-green-800',  icon: 'text-green-500',      iconColor: 'text-green-500' },
  danger:  { bg: 'bg-red-50 dark:bg-red-950/30',         border: 'border-red-300 dark:border-red-800',      icon: 'text-red-500',        iconColor: 'text-red-500' },
}

const CALLOUT_ICONS: Record<CalloutType, typeof Info> = {
  info: Info,
  warning: AlertTriangle,
  tip: Lightbulb,
  success: CheckCircle,
  danger: XCircle,
}

const CALLOUT_TYPES: CalloutType[] = ['info', 'warning', 'tip', 'success', 'danger']

function CalloutTypePicker({ current, onChange }: { current: CalloutType; onChange: (t: CalloutType) => void }) {
  const [open, setOpen] = useState(false)
  const CurrentIcon = CALLOUT_ICONS[current]

  return (
    <div className="relative" contentEditable={false}>
      <button
        onClick={() => setOpen(v => !v)}
        className={cn('p-1 rounded hover:bg-black/5 dark:hover:bg-white/10', CALLOUT_STYLES[current].iconColor)}
      >
        <CurrentIcon className="h-4 w-4" />
      </button>
      {open && (
        <>
          <div className="fixed inset-0 z-10" onClick={() => setOpen(false)} />
          <div className="absolute top-full left-0 z-20 mt-1 rounded-lg border border-border bg-popover p-1 shadow-lg flex gap-1">
            {CALLOUT_TYPES.map(t => {
              const Icon = CALLOUT_ICONS[t]
              return (
                <button
                  key={t}
                  onClick={() => { onChange(t); setOpen(false) }}
                  className={cn('p-1.5 rounded hover:bg-muted', CALLOUT_STYLES[t].iconColor, t === current && 'ring-2 ring-primary')}
                >
                  <Icon className="h-4 w-4" />
                </button>
              )
            })}
          </div>
        </>
      )}
    </div>
  )
}

const CalloutView = ({ node, updateAttributes, deleteNode, getPos, editor }: any) => {
  const type = (node.attrs.type || 'info') as CalloutType
  const styles = CALLOUT_STYLES[type]
  const { t } = useLanguage()

  const unwrap = () => {
    const pos = getPos()
    if (typeof pos !== 'number') return
    const toggleNode = editor.state.doc.nodeAt(pos)
    if (!toggleNode) return
    const children: any[] = []
    toggleNode.forEach((child: any) => { children.push(child.toJSON()) })
    if (children.length === 0) children.push({ type: 'paragraph' })
    editor.chain().focus().deleteRange({ from: pos, to: pos + toggleNode.nodeSize }).run()
    editor.chain().focus().insertContentAt(pos, children).run()
  }

  return (
    <NodeViewWrapper className="callout-block group/callout my-2" dir="auto">
      <div className={cn('flex items-start gap-2 rounded-lg border px-3 py-2.5', styles.bg, styles.border)}>
        <div className="flex flex-col items-center gap-1 pt-0.5">
          <CalloutTypePicker
            current={type}
            onChange={(newType) => updateAttributes({ type: newType })}
          />
        </div>
        <div className="flex-1 min-w-0 text-sm leading-relaxed">
          <NodeViewContent className="callout-content" />
        </div>
        <div className="flex flex-shrink-0 items-center gap-0.5 pt-0.5 opacity-0 group-hover/callout:opacity-100 transition-opacity">
          <button
            onClick={unwrap}
            contentEditable={false}
            className="p-0.5 rounded hover:bg-black/5 dark:hover:bg-white/10 text-muted-foreground"
            title={t('richTextEditor.calloutUnwrap')}
          >
            <X className="h-3.5 w-3.5" />
          </button>
          <button
            onClick={deleteNode}
            contentEditable={false}
            className="p-0.5 rounded hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
            title={t('richTextEditor.calloutDelete')}
          >
            <Trash2 className="h-3.5 w-3.5" />
          </button>
        </div>
      </div>
    </NodeViewWrapper>
  )
}

export const CalloutExtension = Node.create({
  name: 'calloutBlock',

  group: 'block',

  content: 'block+',

  defining: true,

  isolating: true,

  addAttributes() {
    return {
      type: {
        default: 'info',
        parseHTML: (element) => {
          const t = element.getAttribute('data-callout-type')
          return (t && CALLOUT_TYPES.includes(t as CalloutType)) ? t : 'info'
        },
        renderHTML: (attributes) => ({
          'data-callout-type': attributes.type,
        }),
      },
    }
  },

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

  renderHTML({ HTMLAttributes }) {
    const type = (HTMLAttributes['data-callout-type'] as CalloutType) || 'info'
    return [
      'div',
      mergeAttributes(HTMLAttributes, {
        'data-type': 'callout-block',
        'data-callout-type': type,
        class: `callout-block callout-${type}`,
      }),
      0,
    ]
  },

  addNodeView() {
    return ReactNodeViewRenderer(CalloutView)
  },

  addKeyboardShortcuts() {
    return {
      'Mod-Alt-C': () => this.editor.commands.insertContent({
        type: this.name,
        attrs: { type: 'info' },
        content: [{ type: 'paragraph' }],
      }),
    }
  },
})

export function insertCalloutBlock(editor: any, type: CalloutType = 'info') {
  editor.chain().focus().insertContent({
    type: 'calloutBlock',
    attrs: { type },
    content: [{ type: 'paragraph' }],
  }).run()
}

export function turnIntoCalloutBlock(editor: any, blockPos: number, blockNode: any, type: CalloutType = 'info') {
  if (!blockNode || blockPos < 0) return

  const nodeJson = blockNode.toJSON()

  editor.chain().focus().deleteRange({
    from: blockPos,
    to: blockPos + blockNode.nodeSize,
  }).insertContentAt(blockPos, {
    type: 'calloutBlock',
    attrs: { type },
    content: [nodeJson],
  }).setTextSelection(blockPos + 2).run()
}

export { CALLOUT_TYPES, CALLOUT_ICONS, CALLOUT_STYLES }
export type { CalloutType }
