"use client";

import { Button } from "@mdxui/primitives/button";
import { Card } from "@mdxui/primitives/card";
import { cn } from "@mdxui/primitives/lib/utils";
import { Edit3, Eye, Split } from "lucide-react";
import { useCallback, useState } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";

export interface MarkdownEditorProps {
	/** Initial markdown content */
	initialValue?: string;
	/** Callback when content changes */
	onChange?: (value: string) => void;
	/** Placeholder text */
	placeholder?: string;
	/** Default view mode */
	defaultMode?: "edit" | "preview" | "split";
	/** Height of the editor */
	height?: string | number;
	/** Additional CSS class */
	className?: string;
	/** Whether the editor is read-only */
	readOnly?: boolean;
	/** Enable GitHub Flavored Markdown */
	enableGfm?: boolean;
	/** Custom toolbar actions */
	toolbar?: React.ReactNode;
}

export const MarkdownEditor: React.FC<MarkdownEditorProps> = ({
	initialValue = "",
	onChange,
	placeholder = "Start writing...",
	defaultMode = "split",
	height = 400,
	className,
	readOnly = false,
	enableGfm = true,
	toolbar,
}) => {
	const [content, setContent] = useState(initialValue);
	const [mode, setMode] = useState<"edit" | "preview" | "split">(defaultMode);

	const handleChange = useCallback(
		(value: string) => {
			setContent(value);
			onChange?.(value);
		},
		[onChange],
	);

	const insertMarkdown = useCallback(
		(before: string, after = "") => {
			const textarea = document.querySelector(
				".markdown-textarea",
			) as HTMLTextAreaElement;
			if (!textarea) return;

			const start = textarea.selectionStart;
			const end = textarea.selectionEnd;
			const selectedText = content.substring(start, end);
			const newText =
				content.substring(0, start) +
				before +
				selectedText +
				after +
				content.substring(end);

			handleChange(newText);

			setTimeout(() => {
				textarea.focus();
				textarea.setSelectionRange(start + before.length, end + before.length);
			}, 0);
		},
		[content, handleChange],
	);

	const defaultToolbar = (
		<div className="flex items-center gap-1 border-b border-border p-2">
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("**", "**")}
				disabled={readOnly}
				title="Bold"
			>
				<strong>B</strong>
			</Button>
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("*", "*")}
				disabled={readOnly}
				title="Italic"
			>
				<em>I</em>
			</Button>
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("`", "`")}
				disabled={readOnly}
				title="Code"
			>
				{"<>"}
			</Button>
			<div className="mx-2 h-6 w-px bg-border" />
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("\n### ", "")}
				disabled={readOnly}
				title="Heading"
			>
				H
			</Button>
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("\n- ", "")}
				disabled={readOnly}
				title="List"
			>
				• List
			</Button>
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("\n> ", "")}
				disabled={readOnly}
				title="Quote"
			>
				&gt; Quote
			</Button>
			<Button
				variant="ghost"
				size="sm"
				onClick={() => insertMarkdown("[", "](url)")}
				disabled={readOnly}
				title="Link"
			>
				Link
			</Button>
			<div className="ml-auto flex items-center gap-1">
				<Button
					variant={mode === "edit" ? "default" : "ghost"}
					size="sm"
					onClick={() => setMode("edit")}
				>
					<Edit3 className="h-4 w-4" />
				</Button>
				<Button
					variant={mode === "split" ? "default" : "ghost"}
					size="sm"
					onClick={() => setMode("split")}
				>
					<Split className="h-4 w-4" />
				</Button>
				<Button
					variant={mode === "preview" ? "default" : "ghost"}
					size="sm"
					onClick={() => setMode("preview")}
				>
					<Eye className="h-4 w-4" />
				</Button>
			</div>
		</div>
	);

	const editorArea = (
		<textarea
			className={cn(
				"markdown-textarea w-full resize-none p-4 font-mono text-sm outline-none",
				"bg-background text-foreground placeholder:text-muted-foreground",
				readOnly && "cursor-not-allowed opacity-50",
			)}
			value={content}
			onChange={(e) => handleChange(e.target.value)}
			placeholder={placeholder}
			readOnly={readOnly}
			style={{ height: typeof height === "number" ? `${height}px` : height }}
		/>
	);

	const previewArea = (
		<div
			className="prose prose-sm max-w-none overflow-auto p-4 dark:prose-invert"
			style={{ height: typeof height === "number" ? `${height}px` : height }}
		>
			<ReactMarkdown remarkPlugins={enableGfm ? [remarkGfm] : []}>
				{content || "*No content*"}
			</ReactMarkdown>
		</div>
	);

	return (
		<Card className={cn("overflow-hidden", className)}>
			{toolbar || defaultToolbar}
			{mode === "split" ? (
				<div className="grid grid-cols-2 divide-x divide-border">
					{editorArea}
					{previewArea}
				</div>
			) : mode === "edit" ? (
				editorArea
			) : (
				previewArea
			)}
		</Card>
	);
};
