// app/admin/_components/editor/Editor.tsx
"use client";

import { useEditor, EditorContent } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import Placeholder from "@tiptap/extension-placeholder";
import { Button } from "../../../../../src/components/ui/button";
import {
  Bold,
  Italic,
  Strikethrough,
  List,
  ListOrdered,
  Heading1,
  Heading2,
  Heading3,
  Quote,
  Undo,
  Redo,
  Code,
  Pilcrow,
} from "lucide-react";
import { useEffect, useState } from "react";

interface EditorProps {
  value: string;
  onChange: (value: string) => void;
  rows?: number;
  className?: string;
  placeholder?: string;
  readOnly?: boolean;
  disabled?: boolean;
}

/**
 * Cleans Tiptap generated HTML before saving.
 * Fixes:
 * 1. <li><p>Text</p></li> => <li>Text</li>
 * 2. Removes empty <p></p>
 */
const cleanEditorHTML = (html: string) => {
  if (!html) return "";

  const parser = new DOMParser();
  const doc = parser.parseFromString(`<div>${html}</div>`, "text/html");
  const wrapper = doc.body.firstElementChild as HTMLElement | null;

  if (!wrapper) return "";

  // Remove <p> inside <li> only when <p> is the only element inside <li>
  wrapper.querySelectorAll("li").forEach((li) => {
    const elementChildren = Array.from(li.children);

    if (
      elementChildren.length === 1 &&
      elementChildren[0].tagName.toLowerCase() === "p"
    ) {
      const p = elementChildren[0];

      while (p.firstChild) {
        li.insertBefore(p.firstChild, p);
      }

      p.remove();
    }
  });

  // Remove empty <p></p>, <p><br></p>, <p>&nbsp;</p>
  wrapper.querySelectorAll("p").forEach((p) => {
    const content = p.innerHTML
      .replace(/<br\s*\/?>/gi, "")
      .replace(/&nbsp;/gi, "")
      .trim();

    if (!content) {
      p.remove();
    }
  });

  return wrapper.innerHTML.trim();
};

export default function Editor({
  value,
  onChange,
  rows = 6,
  className = "",
  placeholder = "Write description here...",
  readOnly = false,
  disabled = false,
}: EditorProps) {
  const [isMounted, setIsMounted] = useState(false);
  const [htmlMode, setHtmlMode] = useState(false);
  const [htmlDraft, setHtmlDraft] = useState("");

  const isReadOnly = readOnly || disabled;

  const editor = useEditor({
    extensions: [
      StarterKit.configure({
        heading: {
          levels: [1, 2, 3],
        },
      }),
      Placeholder.configure({
        placeholder,
      }),
    ],
    content: value || "",
    editable: !isReadOnly,
    immediatelyRender: false,
    onUpdate: ({ editor }) => {
      const cleanHtml = cleanEditorHTML(editor.getHTML());
      onChange(cleanHtml);
    },
    editorProps: {
      attributes: {
        class: `prose prose-sm max-w-none focus:outline-none px-4 py-3 ${
          isReadOnly ? "cursor-default" : ""
        }`,
        style: `min-height: ${rows * 40}px; max-height: ${
          rows * 60
        }px; overflow-y: auto;`,
      },
    },
  });

  useEffect(() => {
    setIsMounted(true);
  }, []);

  /**
   * Sync external value with editor.
   * Compare cleaned HTML to avoid unnecessary update loops.
   */
  useEffect(() => {
    if (!editor || htmlMode) return;

    const editorHtml = cleanEditorHTML(editor.getHTML());
    const incomingHtml = cleanEditorHTML(value || "");

    if (incomingHtml !== editorHtml) {
      editor.commands.setContent(value || "");
    }
  }, [editor, value, htmlMode]);

  useEffect(() => {
    if (editor) {
      editor.setEditable(!isReadOnly);
    }
  }, [editor, isReadOnly]);

  if (!isMounted || !editor) {
    return (
      <div
        className={`w-full ${className} animate-pulse rounded-md bg-gray-100 dark:bg-gray-800`}
        style={{ minHeight: `${rows * 40}px` }}
      />
    );
  }

  // const openHtmlMode = () => {
  //   const cleanHtml = cleanEditorHTML(editor.getHTML());
  //   setHtmlDraft(cleanHtml);
  //   setHtmlMode(true);
  // };

  const openHtmlMode = () => {
  setHtmlDraft(value || "");
  setHtmlMode(true);
};

  // const applyHtml = () => {
  //   const cleanHtml = cleanEditorHTML(htmlDraft || "");

  //   editor.commands.setContent(cleanHtml);
  //   onChange(cleanHtml);

  //   setHtmlMode(false);
  // };

  const applyHtml = () => {
  const exactHtml = htmlDraft || "";
 
  onChange(exactHtml);
 
  // This only updates visual preview.
  // Tiptap may normalize tags here, but saved value remains exact.
  editor.commands.setContent(exactHtml);
 
  setHtmlMode(false);
};

  const cancelHtmlMode = () => {
    setHtmlDraft("");
    setHtmlMode(false);
  };

  const ToolbarButton = ({
    onClick,
    isActive = false,
    disabled: btnDisabled = false,
    icon: Icon,
    title,
  }: {
    onClick: () => void;
    isActive?: boolean;
    disabled?: boolean;
    icon: any;
    title: string;
  }) => (
    <Button
      type="button"
      variant="outline"
      size="sm"
      onClick={onClick}
      disabled={btnDisabled || isReadOnly || htmlMode}
      className={`h-8 w-8 p-0 ${
        isActive
          ? "border-purple-300 bg-purple-100 text-purple-700 dark:border-purple-800 dark:bg-purple-900/30 dark:text-purple-400"
          : ""
      }`}
      title={title}
    >
      <Icon className="h-4 w-4" />
    </Button>
  );

  return (
    <div className={`w-full ${className}`}>
      {!isReadOnly && (
        <div className="sticky top-0 z-10 flex flex-wrap gap-1 rounded-t-md border border-b-0 bg-gray-50 p-2 dark:bg-gray-800/50">
          <ToolbarButton
            onClick={() => editor.chain().focus().toggleBold().run()}
            isActive={editor.isActive("bold")}
            icon={Bold}
            title="Bold"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleItalic().run()}
            isActive={editor.isActive("italic")}
            icon={Italic}
            title="Italic"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleStrike().run()}
            isActive={editor.isActive("strike")}
            icon={Strikethrough}
            title="Strikethrough"
          />

          <div className="mx-1 h-6 w-px bg-gray-300 dark:bg-gray-600" />

          <ToolbarButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 1 }).run()
            }
            isActive={editor.isActive("heading", { level: 1 })}
            icon={Heading1}
            title="Heading 1"
          />

          <ToolbarButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 2 }).run()
            }
            isActive={editor.isActive("heading", { level: 2 })}
            icon={Heading2}
            title="Heading 2"
          />

          <ToolbarButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 3 }).run()
            }
            isActive={editor.isActive("heading", { level: 3 })}
            icon={Heading3}
            title="Heading 3"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().setParagraph().run()}
            isActive={editor.isActive("paragraph")}
            icon={Pilcrow}
            title="Paragraph"
          />

          <div className="mx-1 h-6 w-px bg-gray-300 dark:bg-gray-600" />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleBulletList().run()}
            isActive={editor.isActive("bulletList")}
            icon={List}
            title="Bullet List"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleOrderedList().run()}
            isActive={editor.isActive("orderedList")}
            icon={ListOrdered}
            title="Numbered List"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleBlockquote().run()}
            isActive={editor.isActive("blockquote")}
            icon={Quote}
            title="Quote"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().toggleCodeBlock().run()}
            isActive={editor.isActive("codeBlock")}
            icon={Code}
            title="Code Block"
          />

          <div className="mx-1 h-6 w-px bg-gray-300 dark:bg-gray-600" />

          <ToolbarButton
            onClick={() => editor.chain().focus().undo().run()}
            disabled={!editor.can().undo()}
            icon={Undo}
            title="Undo"
          />

          <ToolbarButton
            onClick={() => editor.chain().focus().redo().run()}
            disabled={!editor.can().redo()}
            icon={Redo}
            title="Redo"
          />

          <div className="mx-1 h-6 w-px bg-gray-300 dark:bg-gray-600" />

          <Button
            type="button"
            variant={htmlMode ? "default" : "outline"}
            size="sm"
            onClick={htmlMode ? applyHtml : openHtmlMode}
            className="h-8 px-3 text-xs"
          >
            {htmlMode ? "Apply HTML" : "HTML"}
          </Button>

          {htmlMode && (
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={cancelHtmlMode}
              className="h-8 px-3 text-xs"
            >
              Cancel
            </Button>
          )}
        </div>
      )}

      {htmlMode ? (
        <div className="overflow-hidden rounded-b-md border border-t-0 bg-white dark:bg-[#1f2a37]">
          <textarea
            value={htmlDraft}
            onChange={(e) => setHtmlDraft(e.target.value)}
            className="w-full bg-white p-3 font-mono text-sm outline-none dark:bg-[#1f2a37] dark:text-white"
            style={{
              minHeight: `${rows * 40}px`,
              maxHeight: `${rows * 70}px`,
              overflowY: "auto",
            }}
            placeholder="<p>Add your HTML here...</p>"
          />
        </div>
      ) : (
        <div
          className={`rounded-b-md border ${
            !isReadOnly ? "rounded-t-none border-t-0" : "rounded-md"
          } overflow-hidden bg-white dark:bg-[#1f2a37]`}
        >
          <EditorContent editor={editor} />
        </div>
      )}

      <style jsx global>{`
        .ProseMirror {
          outline: none;
          padding: 0.75rem 1rem;
          min-height: ${rows * 40}px;
          max-height: ${rows * 60}px;
          overflow-y: auto;
        }

        .ProseMirror p.is-editor-empty:first-child::before {
          content: attr(data-placeholder);
          float: left;
          color: #9ca3af;
          pointer-events: none;
          height: 0;
        }

        .ProseMirror > * + * {
          margin-top: 0.75em;
        }

        .ProseMirror ul,
        .ProseMirror ol {
          padding-left: 1.5rem;
          margin: 0.5rem 0;
        }

        .ProseMirror li {
          margin: 0.25rem 0;
        }

        .ProseMirror h1 {
          font-size: 2rem;
          font-weight: 600;
          margin: 1rem 0 0.5rem;
        }

        .ProseMirror h2 {
          font-size: 1.5rem;
          font-weight: 600;
          margin: 1rem 0 0.5rem;
        }

        .ProseMirror h3 {
          font-size: 1.25rem;
          font-weight: 600;
          margin: 0.75rem 0 0.5rem;
        }

        .ProseMirror blockquote {
          border-left: 3px solid #cbd5e1;
          padding-left: 1rem;
          margin: 0.5rem 0;
          color: #64748b;
          font-style: italic;
        }

        .dark .ProseMirror blockquote {
          border-left-color: #475569;
          color: #94a3b8;
        }

        .ProseMirror code {
          background-color: #f1f5f9;
          padding: 0.2rem 0.3rem;
          border-radius: 0.25rem;
          font-family: monospace;
          font-size: 0.875em;
        }

        .dark .ProseMirror code {
          background-color: #334155;
          color: #e2e8f0;
        }

        .ProseMirror pre {
          background-color: #1e293b;
          color: #e2e8f0;
          padding: 0.75rem;
          border-radius: 0.375rem;
          overflow-x: auto;
          margin: 0.5rem 0;
        }

        .ProseMirror pre code {
          background-color: transparent;
          padding: 0;
          color: inherit;
        }

        .ProseMirror a {
          color: #3b82f6;
          text-decoration: underline;
        }

        .ProseMirror img {
          max-width: 100%;
          height: auto;
          border-radius: 0.375rem;
          margin: 0.5rem 0;
        }

        .ProseMirror[contenteditable="false"] {
          background-color: #f9fafb;
          cursor: default;
        }

        .dark .ProseMirror[contenteditable="false"] {
          background-color: #1f2a37;
        }

        .ProseMirror::-webkit-scrollbar {
          width: 8px;
          height: 8px;
        }

        .ProseMirror::-webkit-scrollbar-track {
          background: #f1f1f1;
          border-radius: 4px;
        }

        .ProseMirror::-webkit-scrollbar-thumb {
          background: #cbd5e1;
          border-radius: 4px;
        }

        .ProseMirror::-webkit-scrollbar-thumb:hover {
          background: #94a3b8;
        }

        .dark .ProseMirror::-webkit-scrollbar-track {
          background: #1f2937;
        }

        .dark .ProseMirror::-webkit-scrollbar-thumb {
          background: #475569;
        }

        .dark .ProseMirror::-webkit-scrollbar-thumb:hover {
          background: #647b8;
        }
      `}</style>
    </div>
  );
}
