"use client"

import { useEffect } from "react"
import { useEditor, EditorContent } from "@tiptap/react"
import StarterKit from "@tiptap/starter-kit"
import Link from "@tiptap/extension-link"
import Placeholder from "@tiptap/extension-placeholder"
import { cn } from "@/lib/utils"
import sanitize from "sanitize-html"
import { Button } from "@/components/ui/button"
import { Separator } from "@/components/ui/separator"
import {
  Bold,
  Italic,
  Strikethrough,
  List,
  ListOrdered,
  Quote,
  Undo,
  Redo,
  Link as LinkIcon,
} from "lucide-react"

type RichTextEditorProps = {
  value?: string
  onChange?: (html: string) => void
  className?: string
  placeholder?: string
  disabled?: boolean
  minHeight?: number
}

export function RichTextEditor({
  value,
  onChange,
  className,
  placeholder = "Escreva aqui...",
  disabled,
  minHeight = 120,
}: RichTextEditorProps) {
  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        bulletList: { keepMarks: true },
        orderedList: { keepMarks: true },
      }),
      Link.configure({
        openOnClick: true,
        autolink: true,
        protocols: ["http", "https", "mailto"],
        HTMLAttributes: { rel: "noopener noreferrer", target: "_blank" },
      }),
      Placeholder.configure({ placeholder }),
    ],
    editorProps: {
      attributes: {
        class:
          "prose prose-sm max-w-none focus:outline-none text-foreground",
      },
    },
    content: value || "",
    onUpdate({ editor }) {
      onChange?.(editor.getHTML())
    },
    editable: !disabled,
    // Avoid SSR hydration mismatches per Tiptap recommendation
    immediatelyRender: false,
  })

  // Keep external value in sync when it changes
  useEffect(() => {
    if (!editor) return
    const current = editor.getHTML()
    if ((value ?? "") !== current) {
      editor.commands.setContent(value || "", { emitUpdate: false })
    }
  }, [value, editor])

  if (!editor) return null

  return (
    <div className={cn("rounded-md border bg-background", className)}>
      <div className="flex flex-wrap items-center gap-1 border-b px-2 py-1">
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleBold().run()}
          active={editor.isActive("bold")}
          ariaLabel="Negrito"
        >
          <Bold className="size-4" />
        </ToolbarButton>
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleItalic().run()}
          active={editor.isActive("italic")}
          ariaLabel="Itálico"
        >
          <Italic className="size-4" />
        </ToolbarButton>
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleStrike().run()}
          active={editor.isActive("strike")}
          ariaLabel="Tachado"
        >
          <Strikethrough className="size-4" />
        </ToolbarButton>
        <Separator orientation="vertical" className="mx-1 h-5" />
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleBulletList().run()}
          active={editor.isActive("bulletList")}
          ariaLabel="Lista"
        >
          <List className="size-4" />
        </ToolbarButton>
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleOrderedList().run()}
          active={editor.isActive("orderedList")}
          ariaLabel="Lista ordenada"
        >
          <ListOrdered className="size-4" />
        </ToolbarButton>
        <ToolbarButton
          onClick={() => editor.chain().focus().toggleBlockquote().run()}
          active={editor.isActive("blockquote")}
          ariaLabel="Citação"
        >
          <Quote className="size-4" />
        </ToolbarButton>
        <ToolbarButton
          onClick={() => {
            const prev = editor.getAttributes("link").href as string | undefined
            const url = window.prompt("URL do link:", prev || "https://")
            if (url === null) return
            if (url === "") {
              editor.chain().focus().extendMarkRange("link").unsetLink().run()
              return
            }
            editor.chain().focus().extendMarkRange("link").setLink({ href: url }).run()
          }}
          active={editor.isActive("link")}
          ariaLabel="Inserir link"
        >
          <LinkIcon className="size-4" />
        </ToolbarButton>
        <div className="ms-auto flex items-center gap-1">
          <ToolbarButton onClick={() => editor.chain().focus().undo().run()} ariaLabel="Desfazer">
            <Undo className="size-4" />
          </ToolbarButton>
          <ToolbarButton onClick={() => editor.chain().focus().redo().run()} ariaLabel="Refazer">
            <Redo className="size-4" />
          </ToolbarButton>
        </div>
      </div>
      <div style={{ minHeight }} className="rich-text p-3">
        <EditorContent editor={editor} />
      </div>
    </div>
  )
}

function ToolbarButton({
  onClick,
  active,
  ariaLabel,
  children,
}: {
  onClick: () => void
  active?: boolean
  ariaLabel?: string
  children: React.ReactNode
}) {
  return (
    <Button
      type="button"
      variant={active ? "default" : "ghost"}
      size="icon"
      className="h-7 w-7"
      onClick={onClick}
      aria-label={ariaLabel}
    >
      {children}
    </Button>
  )
}

// Utilitário simples para renderização segura do HTML do editor.
// Remove tags <script>/<style> e atributos on*.
export function sanitizeEditorHtml(html: string): string {
  try {
    return sanitize(html || "", {
      allowedTags: [
        "p","br","a","strong","em","u","s","blockquote","ul","ol","li","code","pre","span","h1","h2","h3"
      ],
      allowedAttributes: {
        a: ["href","name","target","rel"],
        span: ["style"],
        code: ["class"],
        pre: ["class"],
      },
      allowedSchemes: ["http","https","mailto"],
      // prevent target=_self phishing
      transformTags: {
        a: sanitize.simpleTransform("a", { rel: "noopener noreferrer", target: "_blank" }, true),
      },
      // disallow inline event handlers
      allowVulnerableTags: false,
    })
  } catch {
    return ""
  }
}

export function RichTextContent({ html, className }: { html: string; className?: string }) {
  return (
    <div
      className={cn("rich-text text-sm leading-relaxed", className)}
      dangerouslySetInnerHTML={{ __html: sanitizeEditorHtml(html) }}
    />
  )
}
