'use client'

import { Node, mergeAttributes } from '@tiptap/core'
import { ReactNodeViewRenderer, NodeViewWrapper } from '@tiptap/react'
import { Link2, Trash2, X, ExternalLink, Loader2 } from 'lucide-react'
import { useState, useEffect, useRef } from 'react'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n'

interface PreviewData {
  title: string
  description: string
  image: string | null
  favicon: string | null
  siteName: string | null
}

const LinkPreviewView = ({ node, updateAttributes, deleteNode, selected }: any) => {
  const { t } = useLanguage()
  const url = node.attrs.url as string
  const cached = node.attrs.preview as PreviewData | null
  const [loading, setLoading] = useState(!cached && !!url)
  const [error, setError] = useState(false)
  const fetchedRef = useRef<string | null>(null)

  useEffect(() => {
    if (!url || cached || fetchedRef.current === url) return
    fetchedRef.current = url
    setLoading(true)
    setError(false)

    fetch(`/api/link-preview?url=${encodeURIComponent(url)}`)
      .then(r => r.ok ? r.json() : null)
      .then(data => {
        if (data) {
          updateAttributes({ preview: data })
        } else {
          setError(true)
        }
      })
      .catch(() => setError(true))
      .finally(() => setLoading(false))
  }, [url, cached, updateAttributes])

  const unwrap = () => {
    updateAttributes({ url: '', preview: null })
  }

  const domain = (() => {
    try { return new URL(url).hostname.replace('www.', '') } catch { return url }
  })()

  return (
    <NodeViewWrapper className="link-preview-block my-2" dir="auto" data-selected={selected}>
      <div className={cn(
        'group relative rounded-xl border overflow-hidden transition-all',
        'border-border bg-card hover:border-primary/40 hover:shadow-md',
        selected && 'ring-2 ring-primary/30'
      )}>
        <div className="flex flex-col sm:flex-row">
          {cached?.image && (
            <div className="sm:w-48 h-32 sm:h-auto flex-shrink-0 bg-muted overflow-hidden">
              <img
                src={`/api/image-proxy?url=${encodeURIComponent(cached.image)}`}
                alt=""
                className="w-full h-full object-cover"
                onError={(e) => { (e.target as HTMLImageElement).parentElement!.style.display = 'none' }}
              />
            </div>
          )}
          <div className="flex-1 min-w-0 p-3.5">
            {loading ? (
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <Loader2 className="h-4 w-4 animate-spin" />
                <span>{t('richTextEditor.linkPreviewLoading')}</span>
              </div>
            ) : error ? (
              <div className="flex items-center gap-2 text-sm text-muted-foreground">
                <Link2 className="h-4 w-4 flex-shrink-0" />
                <a href={url} target="_blank" rel="noopener noreferrer" className="truncate hover:underline text-primary">
                  {url}
                </a>
              </div>
            ) : cached ? (
              <>
                <div className="flex items-start justify-between gap-2 mb-1">
                  <a
                    href={url}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="font-semibold text-sm leading-tight hover:text-primary transition-colors line-clamp-2"
                  >
                    {cached.title || domain}
                  </a>
                  <ExternalLink className="h-3.5 w-3.5 text-muted-foreground flex-shrink-0 mt-0.5" />
                </div>
                {cached.description && (
                  <p className="text-xs text-muted-foreground line-clamp-2 mb-2 leading-relaxed">
                    {cached.description}
                  </p>
                )}
                <div className="flex items-center gap-1.5 text-[11px] text-muted-foreground">
                  {cached.favicon && (
                    <img src={`/api/image-proxy?url=${encodeURIComponent(cached.favicon)}`} alt="" className="w-3.5 h-3.5 rounded-sm" onError={(e) => { (e.target as HTMLImageElement).style.display = 'none' }} />
                  )}
                  <span className="truncate">{cached.siteName || domain}</span>
                </div>
              </>
            ) : null}
          </div>
        </div>

        <div className="absolute top-1.5 right-1.5 flex items-center gap-0.5 opacity-0 group-hover:opacity-100 transition-opacity">
          <button
            onClick={unwrap}
            contentEditable={false}
            className="p-1 rounded-md bg-background/80 backdrop-blur hover:bg-muted text-muted-foreground"
            title={t('richTextEditor.linkPreviewUnwrap')}
          >
            <X className="h-3.5 w-3.5" />
          </button>
          <button
            onClick={deleteNode}
            contentEditable={false}
            className="p-1 rounded-md bg-background/80 backdrop-blur hover:bg-destructive/10 text-muted-foreground hover:text-destructive"
            title={t('richTextEditor.linkPreviewDelete')}
          >
            <Trash2 className="h-3.5 w-3.5" />
          </button>
        </div>
      </div>
    </NodeViewWrapper>
  )
}

export const LinkPreviewExtension = Node.create({
  name: 'linkPreviewBlock',

  group: 'block',

  atom: true,

  defining: true,

  isolating: true,

  addAttributes() {
    return {
      url: {
        default: '',
        parseHTML: (el) => el.getAttribute('data-url') || '',
        renderHTML: (attrs) => ({ 'data-url': attrs.url }),
      },
      preview: {
        default: null,
        parseHTML: (el) => {
          const raw = el.getAttribute('data-preview')
          if (!raw) return null
          try { return JSON.parse(raw) } catch { return null }
        },
        renderHTML: (attrs) => {
          if (!attrs.preview) return {}
          return { 'data-preview': JSON.stringify(attrs.preview) }
        },
      },
    }
  },

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

  renderHTML({ node, HTMLAttributes }) {
    const url = node.attrs.url || ''
    const preview = node.attrs.preview as PreviewData | null
    const searchText = preview
      ? `${preview.title || ''} ${preview.description || ''} ${url}`.trim()
      : url

    return [
      'div',
      mergeAttributes(HTMLAttributes, {
        'data-type': 'link-preview-block',
        'data-url': url,
        class: 'link-preview-block',
      }),
      ['div', { class: 'link-preview-searchable', style: 'display:none' }, searchText],
    ]
  },

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

export function insertLinkPreview(editor: any, url: string) {
  if (!url?.trim()) return
  editor.chain().focus().insertContent({
    type: 'linkPreviewBlock',
    attrs: { url: url.trim(), preview: null },
  }).run()
}

export function isUrl(text: string): boolean {
  return /^https?:\/\/[^\s]+$/i.test(text.trim())
}
