import { useState, useEffect, useRef } from "react";
import { Button } from "@/components/ui/button";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { 
  Bold, 
  Italic, 
  Underline, 
  Heading1, 
  Heading2, 
  List, 
  ListOrdered, 
  Link as LinkIcon, 
  Quote, 
  Code, 
  Image as ImageIcon
} from "lucide-react";
import { Textarea } from "@/components/ui/textarea";
import { Input } from "@/components/ui/input";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Label } from "@/components/ui/label";

export interface RichTextEditorProps {
  /**
   * Initial content value
   */
  value?: string;
  /**
   * Event handler called when content changes
   */
  onChange?: (value: string) => void;
  /**
   * Placeholder text when editor is empty
   */
  placeholder?: string;
  /**
   * Height of the editor
   */
  height?: string;
  /**
   * Whether to show the preview tab
   */
  showPreview?: boolean;
  /**
   * CSS class to apply to the editor container
   */
  className?: string;
  /**
   * Whether the editor is disabled
   */
  disabled?: boolean;
}

/**
 * Rich text editor component for content creation
 * 
 * Features:
 * - Basic formatting (bold, italic, underline)
 * - Headings (h1, h2)
 * - Lists (ordered, unordered)
 * - Links
 * - Images
 * - Code blocks
 * - Quotes
 * - Preview mode
 * 
 * @example
 * ```tsx
 * <RichTextEditor
 *   value={content}
 *   onChange={setContent}
 *   placeholder="Write your content here..."
 *   height="min-h-[300px]"
 *   showPreview
 * />
 * ```
 */
export function RichTextEditor({
  value = "",
  onChange,
  placeholder = "Write your content here...",
  height = "min-h-[300px]",
  showPreview = true,
  className = "",
  disabled = false,
}: RichTextEditorProps) {
  const [content, setContent] = useState(value);
  const [activeTab, setActiveTab] = useState<string>("write");
  const [linkDialogOpen, setLinkDialogOpen] = useState(false);
  const [imageDialogOpen, setImageDialogOpen] = useState(false);
  const [linkUrl, setLinkUrl] = useState("");
  const [linkText, setLinkText] = useState("");
  const [imageUrl, setImageUrl] = useState("");
  const [imageAlt, setImageAlt] = useState("");
  const editorRef = useRef<HTMLTextAreaElement>(null);

  useEffect(() => {
    if (value !== content) {
      setContent(value);
    }
  }, [value]);

  useEffect(() => {
    if (onChange && content !== value) {
      onChange(content);
    }
  }, [content, onChange, value]);

  // Insert text at cursor position or replace selection
  const insertTextAtCursor = (
    textBefore: string,
    textAfter: string = "",
    defaultText: string = ""
  ) => {
    if (!editorRef.current) return;

    const textarea = editorRef.current;
    const selectionStart = textarea.selectionStart;
    const selectionEnd = textarea.selectionEnd;
    const selectedText = textarea.value.substring(selectionStart, selectionEnd);
    const textToInsert = selectedText || defaultText;

    const newText =
      textarea.value.substring(0, selectionStart) +
      textBefore +
      textToInsert +
      textAfter +
      textarea.value.substring(selectionEnd);

    setContent(newText);

    // Focus back on textarea and position cursor after inserted text
    setTimeout(() => {
      textarea.focus();
      const newCursorPos = selectionStart + textBefore.length + textToInsert.length + textAfter.length;
      textarea.setSelectionRange(newCursorPos, newCursorPos);
    }, 0);
  };

  // Format handlers
  const handleBold = () => insertTextAtCursor("**", "**", "bold text");
  const handleItalic = () => insertTextAtCursor("*", "*", "italic text");
  const handleUnderline = () => insertTextAtCursor("<u>", "</u>", "underlined text");
  const handleH1 = () => insertTextAtCursor("# ", "", "Heading 1");
  const handleH2 = () => insertTextAtCursor("## ", "", "Heading 2");
  const handleUl = () => insertTextAtCursor("- ", "", "List item");
  const handleOl = () => insertTextAtCursor("1. ", "", "List item");
  const handleQuote = () => insertTextAtCursor("> ", "", "Blockquote");
  const handleCode = () => insertTextAtCursor("```\n", "\n```", "code");

  const handleInsertLink = () => {
    if (!linkUrl) return;
    const linkMarkdown = `[${linkText || linkUrl}](${linkUrl})`;
    insertTextAtCursor(linkMarkdown, "", "");
    setLinkDialogOpen(false);
    setLinkUrl("");
    setLinkText("");
  };

  const handleInsertImage = () => {
    if (!imageUrl) return;
    const imageMarkdown = `![${imageAlt || "Image"}](${imageUrl})`;
    insertTextAtCursor(imageMarkdown, "", "");
    setImageDialogOpen(false);
    setImageUrl("");
    setImageAlt("");
  };

  // Convert markdown to HTML for preview
  const renderPreview = () => {
    let html = content;
    // Convert headings
    html = html.replace(/^# (.*$)/gm, "<h1>$1</h1>");
    html = html.replace(/^## (.*$)/gm, "<h2>$1</h2>");
    // Convert bold
    html = html.replace(/\*\*(.*?)\*\*/g, "<strong>$1</strong>");
    // Convert italic
    html = html.replace(/\*(.*?)\*/g, "<em>$1</em>");
    // Convert links
    html = html.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" class="text-primary hover:underline">$1</a>');
    // Convert images
    html = html.replace(/!\[(.*?)\]\((.*?)\)/g, '<img src="$2" alt="$1" class="max-w-full h-auto" />');
    // Convert unordered lists
    html = html.replace(/^- (.*$)/gm, "<li>$1</li>");
    html = html.replace(/(<li>.*<\/li>)/g, "<ul>$1</ul>");
    // Convert ordered lists
    html = html.replace(/^\d+\. (.*$)/gm, "<li>$1</li>");
    html = html.replace(/(<li>.*<\/li>)/g, "<ol>$1</ol>");
    // Convert blockquotes
    html = html.replace(/^> (.*$)/gm, "<blockquote class='pl-4 border-l-4 border-gray-300 italic'>$1</blockquote>");
    // Convert code blocks
    html = html.replace(/```([\s\S]*?)```/g, '<pre class="bg-gray-100 dark:bg-gray-800 p-4 rounded overflow-x-auto"><code>$1</code></pre>');
    // Convert line breaks
    html = html.replace(/\n/g, "<br />");

    return html;
  };

  return (
    <div className={`border rounded-md ${className}`}>
      {showPreview ? (
        <Tabs defaultValue="write" value={activeTab} onValueChange={setActiveTab}>
          <div className="border-b px-3 py-1">
            <TabsList className="grid w-[200px] grid-cols-2">
              <TabsTrigger value="write">Write</TabsTrigger>
              <TabsTrigger value="preview">Preview</TabsTrigger>
            </TabsList>
          </div>
          
          <TabsContent value="write" className="mt-0">
            <EditorToolbar
              onBold={handleBold}
              onItalic={handleItalic}
              onUnderline={handleUnderline}
              onH1={handleH1}
              onH2={handleH2}
              onUl={handleUl}
              onOl={handleOl}
              onLink={() => setLinkDialogOpen(true)}
              onQuote={handleQuote}
              onCode={handleCode}
              onImage={() => setImageDialogOpen(true)}
              disabled={disabled}
            />
            <Textarea
              ref={editorRef}
              value={content}
              onChange={(e) => setContent(e.target.value)}
              placeholder={placeholder}
              className={`resize-y border-0 focus-visible:ring-0 focus-visible:ring-transparent ${height}`}
              disabled={disabled}
            />
          </TabsContent>
          
          <TabsContent value="preview" className="mt-0">
            {content ? (
              <div 
                className={`p-3 prose prose-sm md:prose dark:prose-invert max-w-none ${height} overflow-auto`}
                dangerouslySetInnerHTML={{ __html: renderPreview() }}
              />
            ) : (
              <div className={`p-3 text-gray-400 italic ${height}`}>
                Nothing to preview. Start writing in the "Write" tab.
              </div>
            )}
          </TabsContent>
        </Tabs>
      ) : (
        <>
          <EditorToolbar
            onBold={handleBold}
            onItalic={handleItalic}
            onUnderline={handleUnderline}
            onH1={handleH1}
            onH2={handleH2}
            onUl={handleUl}
            onOl={handleOl}
            onLink={() => setLinkDialogOpen(true)}
            onQuote={handleQuote}
            onCode={handleCode}
            onImage={() => setImageDialogOpen(true)}
            disabled={disabled}
          />
          <Textarea
            ref={editorRef}
            value={content}
            onChange={(e) => setContent(e.target.value)}
            placeholder={placeholder}
            className={`resize-y border-0 focus-visible:ring-0 focus-visible:ring-transparent ${height}`}
            disabled={disabled}
          />
        </>
      )}

      {/* Link Dialog */}
      <Dialog open={linkDialogOpen} onOpenChange={setLinkDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Insert Link</DialogTitle>
            <DialogDescription>
              Add the URL and text for your link
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-4 py-4">
            <div className="grid gap-2">
              <Label htmlFor="url">URL</Label>
              <Input
                id="url"
                value={linkUrl}
                onChange={(e) => setLinkUrl(e.target.value)}
                placeholder="https://example.com"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="text">Text</Label>
              <Input
                id="text"
                value={linkText}
                onChange={(e) => setLinkText(e.target.value)}
                placeholder="Link text (optional)"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setLinkDialogOpen(false)}>
              Cancel
            </Button>
            <Button onClick={handleInsertLink}>Insert Link</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      {/* Image Dialog */}
      <Dialog open={imageDialogOpen} onOpenChange={setImageDialogOpen}>
        <DialogContent>
          <DialogHeader>
            <DialogTitle>Insert Image</DialogTitle>
            <DialogDescription>
              Add the URL and alt text for your image
            </DialogDescription>
          </DialogHeader>
          <div className="grid gap-4 py-4">
            <div className="grid gap-2">
              <Label htmlFor="imageUrl">Image URL</Label>
              <Input
                id="imageUrl"
                value={imageUrl}
                onChange={(e) => setImageUrl(e.target.value)}
                placeholder="https://example.com/image.jpg"
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="imageAlt">Alt Text</Label>
              <Input
                id="imageAlt"
                value={imageAlt}
                onChange={(e) => setImageAlt(e.target.value)}
                placeholder="Image description (for accessibility)"
              />
            </div>
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setImageDialogOpen(false)}>
              Cancel
            </Button>
            <Button onClick={handleInsertImage}>Insert Image</Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </div>
  );
}

interface EditorToolbarProps {
  onBold: () => void;
  onItalic: () => void;
  onUnderline: () => void;
  onH1: () => void;
  onH2: () => void;
  onUl: () => void;
  onOl: () => void;
  onLink: () => void;
  onQuote: () => void;
  onCode: () => void;
  onImage: () => void;
  disabled?: boolean;
}

function EditorToolbar({
  onBold,
  onItalic,
  onUnderline,
  onH1,
  onH2,
  onUl,
  onOl,
  onLink,
  onQuote,
  onCode,
  onImage,
  disabled = false,
}: EditorToolbarProps) {
  return (
    <div className="flex flex-wrap gap-1 border-b p-2">
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onBold}
        disabled={disabled}
        title="Bold"
      >
        <Bold className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onItalic}
        disabled={disabled}
        title="Italic"
      >
        <Italic className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onUnderline}
        disabled={disabled}
        title="Underline"
      >
        <Underline className="h-4 w-4" />
      </Button>
      <span className="w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1 self-center" />
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onH1}
        disabled={disabled}
        title="Heading 1"
      >
        <Heading1 className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onH2}
        disabled={disabled}
        title="Heading 2"
      >
        <Heading2 className="h-4 w-4" />
      </Button>
      <span className="w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1 self-center" />
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onUl}
        disabled={disabled}
        title="Bullet List"
      >
        <List className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onOl}
        disabled={disabled}
        title="Numbered List"
      >
        <ListOrdered className="h-4 w-4" />
      </Button>
      <span className="w-px h-6 bg-gray-300 dark:bg-gray-600 mx-1 self-center" />
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onLink}
        disabled={disabled}
        title="Insert Link"
      >
        <LinkIcon className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onImage}
        disabled={disabled}
        title="Insert Image"
      >
        <ImageIcon className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onQuote}
        disabled={disabled}
        title="Blockquote"
      >
        <Quote className="h-4 w-4" />
      </Button>
      <Button
        type="button"
        variant="ghost"
        size="sm"
        className="px-2 h-8 w-8"
        onClick={onCode}
        disabled={disabled}
        title="Code Block"
      >
        <Code className="h-4 w-4" />
      </Button>
    </div>
  );
}