"use client";

import { Button } from "@mdxui/primitives/button";
import { Card } from "@mdxui/primitives/card";
import { cn } from "@mdxui/primitives/lib/utils";
import { Toggle } from "@mdxui/primitives/toggle";
import Link from "@tiptap/extension-link";
import Placeholder from "@tiptap/extension-placeholder";
import Table from "@tiptap/extension-table";
import TableCell from "@tiptap/extension-table-cell";
import TableHeader from "@tiptap/extension-table-header";
import TableRow from "@tiptap/extension-table-row";
import TaskItem from "@tiptap/extension-task-item";
import TaskList from "@tiptap/extension-task-list";
import Underline from "@tiptap/extension-underline";
import { type Editor, EditorContent, useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
import {
	Bold,
	CheckSquare,
	Code,
	Heading1,
	Heading2,
	Heading3,
	Italic,
	Link as LinkIcon,
	List,
	ListOrdered,
	Minus,
	Quote,
	Redo,
	Strikethrough,
	Table as TableIcon,
	Underline as UnderlineIcon,
	Undo,
} from "lucide-react";
import type React from "react";
import { useCallback } from "react";

export interface WYSIWYGEditorProps {
	/** Initial HTML content */
	initialValue?: string;
	/** Callback when content changes */
	onChange?: (html: string, json: any) => void;
	/** Placeholder text */
	placeholder?: string;
	/** Height of the editor */
	height?: string | number;
	/** Additional CSS class */
	className?: string;
	/** Whether the editor is read-only */
	readOnly?: boolean;
	/** Enable tables */
	enableTables?: boolean;
	/** Enable task lists */
	enableTaskLists?: boolean;
	/** Custom toolbar */
	toolbar?: (editor: Editor) => React.ReactNode;
}

const MenuBar: React.FC<{ editor: Editor }> = ({ editor }) => {
	const setLink = useCallback(() => {
		const url = window.prompt("Enter URL");
		if (url) {
			editor.chain().focus().setLink({ href: url }).run();
		}
	}, [editor]);

	return (
		<div className="flex flex-wrap items-center gap-1 border-b border-border p-2">
			<Toggle
				size="sm"
				pressed={editor.isActive("bold")}
				onPressedChange={() => editor.chain().focus().toggleBold().run()}
				aria-label="Bold"
			>
				<Bold className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("italic")}
				onPressedChange={() => editor.chain().focus().toggleItalic().run()}
				aria-label="Italic"
			>
				<Italic className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("underline")}
				onPressedChange={() => editor.chain().focus().toggleUnderline().run()}
				aria-label="Underline"
			>
				<UnderlineIcon className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("strike")}
				onPressedChange={() => editor.chain().focus().toggleStrike().run()}
				aria-label="Strikethrough"
			>
				<Strikethrough className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("code")}
				onPressedChange={() => editor.chain().focus().toggleCode().run()}
				aria-label="Code"
			>
				<Code className="h-4 w-4" />
			</Toggle>

			<div className="mx-1 h-6 w-px bg-border" />

			<Toggle
				size="sm"
				pressed={editor.isActive("heading", { level: 1 })}
				onPressedChange={() =>
					editor.chain().focus().toggleHeading({ level: 1 }).run()
				}
				aria-label="Heading 1"
			>
				<Heading1 className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("heading", { level: 2 })}
				onPressedChange={() =>
					editor.chain().focus().toggleHeading({ level: 2 }).run()
				}
				aria-label="Heading 2"
			>
				<Heading2 className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("heading", { level: 3 })}
				onPressedChange={() =>
					editor.chain().focus().toggleHeading({ level: 3 }).run()
				}
				aria-label="Heading 3"
			>
				<Heading3 className="h-4 w-4" />
			</Toggle>

			<div className="mx-1 h-6 w-px bg-border" />

			<Toggle
				size="sm"
				pressed={editor.isActive("bulletList")}
				onPressedChange={() => editor.chain().focus().toggleBulletList().run()}
				aria-label="Bullet List"
			>
				<List className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("orderedList")}
				onPressedChange={() => editor.chain().focus().toggleOrderedList().run()}
				aria-label="Ordered List"
			>
				<ListOrdered className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("taskList")}
				onPressedChange={() => editor.chain().focus().toggleTaskList().run()}
				aria-label="Task List"
			>
				<CheckSquare className="h-4 w-4" />
			</Toggle>
			<Toggle
				size="sm"
				pressed={editor.isActive("blockquote")}
				onPressedChange={() => editor.chain().focus().toggleBlockquote().run()}
				aria-label="Quote"
			>
				<Quote className="h-4 w-4" />
			</Toggle>

			<div className="mx-1 h-6 w-px bg-border" />

			<Button size="sm" variant="ghost" onClick={setLink} aria-label="Add Link">
				<LinkIcon className="h-4 w-4" />
			</Button>
			<Button
				size="sm"
				variant="ghost"
				onClick={() =>
					editor.chain().focus().insertTable({ rows: 3, cols: 3 }).run()
				}
				aria-label="Insert Table"
			>
				<TableIcon className="h-4 w-4" />
			</Button>
			<Button
				size="sm"
				variant="ghost"
				onClick={() => editor.chain().focus().setHorizontalRule().run()}
				aria-label="Horizontal Rule"
			>
				<Minus className="h-4 w-4" />
			</Button>

			<div className="mx-1 h-6 w-px bg-border" />

			<Button
				size="sm"
				variant="ghost"
				onClick={() => editor.chain().focus().undo().run()}
				disabled={!editor.can().undo()}
				aria-label="Undo"
			>
				<Undo className="h-4 w-4" />
			</Button>
			<Button
				size="sm"
				variant="ghost"
				onClick={() => editor.chain().focus().redo().run()}
				disabled={!editor.can().redo()}
				aria-label="Redo"
			>
				<Redo className="h-4 w-4" />
			</Button>
		</div>
	);
};

export const WYSIWYGEditor: React.FC<WYSIWYGEditorProps> = ({
	initialValue = "",
	onChange,
	placeholder = "Start writing...",
	height = 400,
	className,
	readOnly = false,
	enableTables = true,
	enableTaskLists = true,
	toolbar,
}) => {
	const editor = useEditor({
		extensions: [
			StarterKit,
			Placeholder.configure({
				placeholder,
			}),
			Link.configure({
				openOnClick: false,
			}),
			Underline,
			...(enableTables ? [Table, TableRow, TableCell, TableHeader] : []),
			...(enableTaskLists
				? [
						TaskList,
						TaskItem.configure({
							nested: true,
						}),
					]
				: []),
		],
		content: initialValue,
		editable: !readOnly,
		onUpdate: ({ editor }) => {
			const html = editor.getHTML();
			const json = editor.getJSON();
			onChange?.(html, json);
		},
	});

	if (!editor) {
		return null;
	}

	return (
		<Card className={cn("overflow-hidden", className)}>
			{toolbar ? toolbar(editor) : <MenuBar editor={editor} />}
			<EditorContent
				editor={editor}
				className={cn(
					"prose prose-sm max-w-none dark:prose-invert",
					"[&_.ProseMirror]:outline-none",
				)}
				style={{
					height: typeof height === "number" ? `${height}px` : height,
					overflowY: "auto",
				}}
			/>
		</Card>
	);
};
