"use client";

import { useEffect } from "react";
import { useEditor, EditorContent, type Editor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Link from "@tiptap/extension-link";
import Placeholder from "@tiptap/extension-placeholder";
import {
  Bold,
  Italic,
  Strikethrough,
  Heading1,
  Heading2,
  Heading3,
  List,
  ListOrdered,
  Quote,
  Code,
  Link2,
  Link2Off,
  Undo2,
  Redo2,
} from "lucide-react";
import { cn } from "@/lib/utils";

type Props = {
  value: string;
  onChange: (html: string) => void;
  dir?: "rtl" | "ltr";
  placeholder?: string;
};

/** Headless TipTap rich-text editor producing HTML. Used for long-form content
 * (blog posts) edited by trusted admins. */
export function RichTextEditor({ value, onChange, dir = "rtl", placeholder }: Props) {
  const editor = useEditor({
    immediatelyRender: false, // required under Next.js SSR to avoid hydration mismatch
    extensions: [
      StarterKit.configure({
        heading: { levels: [1, 2, 3] },
      }),
      Link.configure({ openOnClick: false, autolink: true, HTMLAttributes: { rel: "noopener", target: "_blank" } }),
      Placeholder.configure({ placeholder: placeholder ?? "" }),
    ],
    content: value || "",
    editorProps: {
      attributes: {
        dir,
        class: "meezi-rte-content min-h-44 px-3 py-2 focus:outline-none",
      },
    },
    onUpdate: ({ editor }) => onChange(editor.getHTML()),
  });

  // Keep the editor in sync when the external value changes (load existing post / reset).
  useEffect(() => {
    if (!editor) return;
    const current = editor.getHTML();
    if (value !== current) {
      editor.commands.setContent(value || "", false);
    }
  }, [value, editor]);

  return (
    <div className="overflow-hidden rounded-lg border border-border bg-background" dir={dir}>
      <Toolbar editor={editor} />
      <EditorContent editor={editor} />
      <style>{`
        .meezi-rte-content { font-size: 0.875rem; line-height: 1.7; }
        .meezi-rte-content:focus { outline: none; }
        .meezi-rte-content h1 { font-size: 1.5rem; font-weight: 700; margin: 0.6em 0 0.3em; }
        .meezi-rte-content h2 { font-size: 1.25rem; font-weight: 700; margin: 0.6em 0 0.3em; }
        .meezi-rte-content h3 { font-size: 1.1rem; font-weight: 600; margin: 0.5em 0 0.25em; }
        .meezi-rte-content p { margin: 0.4em 0; }
        .meezi-rte-content ul { list-style: disc; padding-inline-start: 1.5rem; margin: 0.4em 0; }
        .meezi-rte-content ol { list-style: decimal; padding-inline-start: 1.5rem; margin: 0.4em 0; }
        .meezi-rte-content blockquote { border-inline-start: 3px solid hsl(var(--primary)); padding-inline-start: 0.75rem; color: hsl(var(--muted-foreground)); margin: 0.5em 0; }
        .meezi-rte-content a { color: hsl(var(--primary)); text-decoration: underline; }
        .meezi-rte-content code { background: hsl(var(--muted)); padding: 0.1em 0.3em; border-radius: 4px; font-size: 0.85em; }
        .meezi-rte-content pre { background: hsl(var(--muted)); padding: 0.6rem 0.8rem; border-radius: 8px; overflow-x: auto; }
        .meezi-rte-content p.is-editor-empty:first-child::before { content: attr(data-placeholder); color: hsl(var(--muted-foreground)); float: inline-start; height: 0; pointer-events: none; }
      `}</style>
    </div>
  );
}

function Toolbar({ editor }: { editor: Editor | null }) {
  if (!editor) return <div className="h-9 border-b border-border bg-muted/40" />;

  const setLink = () => {
    const prev = editor.getAttributes("link").href as string | undefined;
    const url = window.prompt("URL", 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();
  };

  return (
    <div className="flex flex-wrap items-center gap-0.5 border-b border-border bg-muted/40 px-1.5 py-1">
      <Btn onClick={() => editor.chain().focus().toggleBold().run()} active={editor.isActive("bold")} title="Bold"><Bold className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleItalic().run()} active={editor.isActive("italic")} title="Italic"><Italic className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleStrike().run()} active={editor.isActive("strike")} title="Strikethrough"><Strikethrough className="size-4" /></Btn>
      <Sep />
      <Btn onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()} active={editor.isActive("heading", { level: 1 })} title="H1"><Heading1 className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()} active={editor.isActive("heading", { level: 2 })} title="H2"><Heading2 className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()} active={editor.isActive("heading", { level: 3 })} title="H3"><Heading3 className="size-4" /></Btn>
      <Sep />
      <Btn onClick={() => editor.chain().focus().toggleBulletList().run()} active={editor.isActive("bulletList")} title="Bullet list"><List className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleOrderedList().run()} active={editor.isActive("orderedList")} title="Numbered list"><ListOrdered className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleBlockquote().run()} active={editor.isActive("blockquote")} title="Quote"><Quote className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().toggleCodeBlock().run()} active={editor.isActive("codeBlock")} title="Code block"><Code className="size-4" /></Btn>
      <Sep />
      <Btn onClick={setLink} active={editor.isActive("link")} title="Link"><Link2 className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().unsetLink().run()} active={false} title="Remove link" disabled={!editor.isActive("link")}><Link2Off className="size-4" /></Btn>
      <Sep />
      <Btn onClick={() => editor.chain().focus().undo().run()} active={false} title="Undo" disabled={!editor.can().undo()}><Undo2 className="size-4" /></Btn>
      <Btn onClick={() => editor.chain().focus().redo().run()} active={false} title="Redo" disabled={!editor.can().redo()}><Redo2 className="size-4" /></Btn>
    </div>
  );
}

function Btn({
  onClick,
  active,
  title,
  disabled,
  children,
}: {
  onClick: () => void;
  active: boolean;
  title: string;
  disabled?: boolean;
  children: React.ReactNode;
}) {
  return (
    <button
      type="button"
      title={title}
      aria-label={title}
      onMouseDown={(e) => e.preventDefault()}
      onClick={onClick}
      disabled={disabled}
      className={cn(
        "inline-flex size-7 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-background hover:text-foreground disabled:opacity-40",
        active && "bg-primary/15 text-primary"
      )}
    >
      {children}
    </button>
  );
}

function Sep() {
  return <span className="mx-0.5 h-5 w-px bg-border" />;
}
