"use client"

import { forwardRef, useCallback, useEffect, useRef, useState } from "react"
import type { ReactNode } 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 { Input } from "@/components/ui/input"
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"
import {
  Bold,
  Italic,
  Strikethrough,
  List,
  ListOrdered,
  Quote,
  Undo,
  Redo,
  Link as LinkIcon,
  Check,
  Link2Off,
} 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,
  })

  const [linkPopoverOpen, setLinkPopoverOpen] = useState(false)
  const [linkUrl, setLinkUrl] = useState("")
  const linkInputRef = useRef<HTMLInputElement>(null)

  const closeLinkPopover = useCallback(() => {
    setLinkPopoverOpen(false)
    requestAnimationFrame(() => {
      editor?.commands.focus()
    })
  }, [editor])

  const openLinkPopover = useCallback(() => {
    if (!editor) return
    editor.chain().focus()
    const prev = (editor.getAttributes("link").href as string | undefined) ?? ""
    setLinkUrl(prev)
    setLinkPopoverOpen(true)
    requestAnimationFrame(() => {
      linkInputRef.current?.focus()
      if (prev) {
        linkInputRef.current?.select()
      }
    })
  }, [editor])

  const applyLink = useCallback(() => {
    if (!editor) return
    const trimmed = linkUrl.trim()
    if (!trimmed) {
      editor.chain().focus().extendMarkRange("link").unsetLink().run()
      closeLinkPopover()
      return
    }
    const normalized = /^(https?:\/\/|mailto:)/i.test(trimmed) ? trimmed : `https://${trimmed}`
    editor.chain().focus().extendMarkRange("link").setLink({ href: normalized }).run()
    closeLinkPopover()
  }, [closeLinkPopover, editor, linkUrl])

  const removeLink = useCallback(() => {
    if (!editor) return
    editor.chain().focus().extendMarkRange("link").unsetLink().run()
    closeLinkPopover()
  }, [closeLinkPopover, editor])

  useEffect(() => {
    if (!editor || !linkPopoverOpen) return
    const handler = () => {
      const prev = (editor.getAttributes("link").href as string | undefined) ?? ""
      setLinkUrl(prev)
    }
    editor.on("selectionUpdate", handler)
    return () => {
      editor.off("selectionUpdate", handler)
    }
  }, [editor, linkPopoverOpen])

  // 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>
        <Popover
          open={linkPopoverOpen}
          onOpenChange={(open) => {
            if (open) {
              openLinkPopover()
            } else {
              closeLinkPopover()
            }
          }}
        >
          <PopoverTrigger asChild>
            <ToolbarButton active={editor.isActive("link")} ariaLabel="Inserir link">
              <LinkIcon className="size-4" />
            </ToolbarButton>
          </PopoverTrigger>
          <PopoverContent className="w-72 space-y-3" align="start">
            <div className="space-y-1">
              <label htmlFor="rich-text-editor-link" className="text-xs font-semibold text-neutral-600">
                URL do link
              </label>
              <Input
                id="rich-text-editor-link"
                ref={linkInputRef}
                placeholder="https://"
                value={linkUrl}
                onChange={(event) => setLinkUrl(event.target.value)}
                onKeyDown={(event) => {
                  if (event.key === "Enter") {
                    event.preventDefault()
                    applyLink()
                  } else if (event.key === "Escape") {
                    event.preventDefault()
                    closeLinkPopover()
                  }
                }}
              />
            </div>
            <div className="flex items-center justify-between gap-2">
              <Button
                type="button"
                variant="outline"
                size="sm"
                className="inline-flex items-center gap-2"
                onClick={removeLink}
                disabled={!editor.isActive("link")}
              >
                <Link2Off className="size-4" />
                Remover
              </Button>
              <Button type="button" size="sm" className="inline-flex items-center gap-2" onClick={applyLink}>
                <Check className="size-4" />
                Aplicar
              </Button>
            </div>
          </PopoverContent>
        </Popover>
        <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>
  )
}

type ToolbarButtonProps = {
  onClick?: () => void
  active?: boolean
  ariaLabel?: string
  children: ReactNode
}

const ToolbarButton = forwardRef<HTMLButtonElement, ToolbarButtonProps>(
  ({ onClick, active, ariaLabel, children }, ref) => {
    return (
      <Button
        type="button"
        variant={active ? "default" : "ghost"}
        size="icon"
        className="h-7 w-7"
        onMouseDown={(event) => event.preventDefault()}
        onClick={onClick}
        aria-label={ariaLabel}
        ref={ref}
      >
        {children}
      </Button>
    )
  }
)

ToolbarButton.displayName = "ToolbarButton"

// 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) }}
    />
  )
}
