import * as React from "react";
import { cn } from "./utils";
import { Button } from "./button";
import { Bold, Italic, Underline, List, ListOrdered, Heading1, Heading2, Heading3, AlignLeft, AlignCenter, AlignRight, Highlighter, X, Type } from "lucide-react";
import { Popover, PopoverContent, PopoverTrigger } from "./popover";
import { sanitizeHTML } from "@/utils/sanitizer";

interface RichTextEditorProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  className?: string;
  minHeight?: string;
}

// Predefined highlight colors - 12 major colors in 2 rows (6 columns x 2 rows)
// "No Color" is first for easy access (standard pattern)
const HIGHLIGHT_COLORS = [
  { name: 'No Color', value: 'transparent', class: 'bg-gray-200 border-2 border-gray-400', icon: '×' },
  { name: 'Yellow', value: '#FFEB3B', class: 'bg-yellow-400' },
  { name: 'Green', value: '#4CAF50', class: 'bg-green-400' },
  { name: 'Blue', value: '#2196F3', class: 'bg-blue-400' },
  { name: 'Red', value: '#F44336', class: 'bg-red-400' },
  { name: 'Orange', value: '#FF9800', class: 'bg-orange-400' },
  { name: 'Purple', value: '#9C27B0', class: 'bg-purple-400' },
  { name: 'Pink', value: '#E91E63', class: 'bg-pink-400' },
  { name: 'Cyan', value: '#00BCD4', class: 'bg-cyan-400' },
  { name: 'Teal', value: '#009688', class: 'bg-teal-400' },
  { name: 'Amber', value: '#FFC107', class: 'bg-amber-400' },
  { name: 'Indigo', value: '#3F51B5', class: 'bg-indigo-400' },
];

/**
 * RichTextEditor Component
 * 
 * Preserves formatting (lists, tables, etc.) when pasting content.
 * Uses contentEditable div to maintain HTML structure.
 */
export function RichTextEditor({
  value,
  onChange,
  placeholder = "Enter text...",
  className,
  minHeight = "120px",
  ...props
}: RichTextEditorProps) {
  const editorRef = React.useRef<HTMLDivElement>(null);
  const [isFocused, setIsFocused] = React.useState(false);
  const [activeFormats, setActiveFormats] = React.useState<Set<string>>(new Set());
  const [highlightColorOpen, setHighlightColorOpen] = React.useState(false);
  const [currentHighlightColor, setCurrentHighlightColor] = React.useState<string | null>(null);
  const [customColor, setCustomColor] = React.useState<string>('#FFEB3B');
  const [textColorOpen, setTextColorOpen] = React.useState(false);
  const [currentTextColor, setCurrentTextColor] = React.useState<string | null>(null);
  const [customTextColor, setCustomTextColor] = React.useState<string>('#000000');

  // Sync external value to editor
  React.useEffect(() => {
    if (editorRef.current && editorRef.current.innerHTML !== value) {
      // Only update if the value actually changed externally
      const currentValue = editorRef.current.innerHTML;
      if (currentValue !== value) {
        // Sanitize incoming content
        editorRef.current.innerHTML = sanitizeHTML(value || '');
      }
    }
  }, [value]);

  // Clean HTML from Word/Office documents - remove style tags, comments, and metadata
  const cleanWordHTML = React.useCallback((html: string): string => {
    // Remove HTML comments (like Word style definitions)
    html = html.replace(/<!--[\s\S]*?-->/g, '');

    // Remove style tags (Word CSS)
    html = html.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');

    // Remove script tags
    html = html.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');

    // Remove meta tags
    html = html.replace(/<meta[^>]*>/gi, '');

    // Remove Word-specific classes and attributes
    html = html.replace(/\s*class="Mso[^"]*"/gi, '');
    html = html.replace(/\s*class="mso[^"]*"/gi, '');
    html = html.replace(/\s*style="[^"]*mso-[^"]*"/gi, '');
    html = html.replace(/\s*style="[^"]*font-family:[^"]*"/gi, '');

    // Remove xmlns attributes
    html = html.replace(/\s*xmlns[^=]*="[^"]*"/gi, '');

    // Remove o:p tags (Word paragraph markers)
    html = html.replace(/<\/?o:p[^>]*>/gi, '');

    // Remove v:shapes and other Word-specific elements
    html = html.replace(/<v:[^>]*>[\s\S]*?<\/v:[^>]*>/gi, '');
    html = html.replace(/<v:[^>]*\/>/gi, '');

    // Clean up empty paragraphs
    html = html.replace(/<p[^>]*>\s*<\/p>/gi, '');
    html = html.replace(/<div[^>]*>\s*<\/div>/gi, '');

    // Remove excessive whitespace
    html = html.replace(/\s+/g, ' ');
    html = html.trim();

    return html;
  }, []);

  // Handle paste event to preserve formatting
  const handlePaste = React.useCallback((e: React.ClipboardEvent<HTMLDivElement>) => {
    e.preventDefault();

    const clipboardData = e.clipboardData;
    let pastedData = clipboardData.getData('text/html') || clipboardData.getData('text/plain');

    // Clean Word/Office metadata if HTML
    if (pastedData.includes('<!--') || pastedData.includes('<style') || pastedData.includes('MsoNormal')) {
      pastedData = cleanWordHTML(pastedData);
    }

    if (!editorRef.current) return;

    const selection = window.getSelection();
    if (!selection || selection.rangeCount === 0) return;

    const range = selection.getRangeAt(0);
    range.deleteContents();

    // Create a temporary container to parse HTML
    const tempDiv = document.createElement('div');
    tempDiv.innerHTML = pastedData;

    // Clean and preserve formatting
    const fragment = document.createDocumentFragment();

    // Process each node to preserve lists, tables, and basic formatting
    Array.from(tempDiv.childNodes).forEach((node) => {
      if (node.nodeType === Node.ELEMENT_NODE) {
        const element = node as HTMLElement;

        // Preserve lists (ul, ol)
        if (element.tagName === 'UL' || element.tagName === 'OL') {
          const list = element.cloneNode(true) as HTMLElement;
          // Remove all inline styles and classes
          list.removeAttribute('style');
          list.removeAttribute('class');
          // Clean up list items but keep structure
          list.querySelectorAll('li').forEach((li) => {
            li.removeAttribute('style');
            li.removeAttribute('class');
            // Keep text content and basic formatting
            const text = li.textContent || '';
            if (text.trim()) {
              li.textContent = text.trim();
            }
          });
          fragment.appendChild(list);
        }
        // Preserve tables - wrap in scrollable container
        else if (element.tagName === 'TABLE') {
          const table = element.cloneNode(true) as HTMLElement;
          // Remove all inline styles and classes
          table.removeAttribute('style');
          table.removeAttribute('class');
          // Clean table cells
          table.querySelectorAll('td, th').forEach((cell) => {
            cell.removeAttribute('style');
            cell.removeAttribute('class');
          });
          // Wrap table in scrollable container for mobile
          const wrapper = document.createElement('div');
          wrapper.className = 'table-wrapper';
          wrapper.appendChild(table);
          fragment.appendChild(wrapper);
        }
        // Preserve paragraphs and divs
        else if (element.tagName === 'P' || element.tagName === 'DIV') {
          const p = document.createElement('p');
          // Extract text content and preserve line breaks
          const innerHTML = element.innerHTML;
          // Remove style tags and comments from inner HTML
          const cleaned = innerHTML.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '')
            .replace(/<!--[\s\S]*?-->/g, '');
          p.innerHTML = cleaned;
          p.removeAttribute('style');
          p.removeAttribute('class');
          fragment.appendChild(p);
        }
        // Preserve line breaks
        else if (element.tagName === 'BR') {
          fragment.appendChild(element.cloneNode(true));
        }
        // For other elements, extract text content
        else {
          const text = element.textContent || '';
          if (text.trim()) {
            const p = document.createElement('p');
            p.textContent = text.trim();
            fragment.appendChild(p);
          }
        }
      } else if (node.nodeType === Node.TEXT_NODE) {
        const text = node.textContent || '';
        if (text.trim()) {
          const p = document.createElement('p');
          p.textContent = text.trim();
          fragment.appendChild(p);
        }
      }
    });

    // If no structured content, insert as plain text with line breaks
    if (fragment.childNodes.length === 0) {
      const plainText = clipboardData.getData('text/plain');
      const lines = plainText.split('\n');
      lines.forEach((line) => {
        if (line.trim()) {
          const p = document.createElement('p');
          p.textContent = line.trim();
          fragment.appendChild(p);
        } else {
          fragment.appendChild(document.createElement('br'));
        }
      });
    }

    range.insertNode(fragment);

    // Move cursor to end of inserted content
    range.collapse(false);
    selection.removeAllRanges();
    selection.addRange(range);

    // Trigger onChange with sanitized content
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }
  }, [onChange, cleanWordHTML]);

  // Check active formats (bold, italic, etc.)
  const checkActiveFormats = React.useCallback(() => {
    if (!editorRef.current || !isFocused) return;

    const formats = new Set<string>();
    const selection = window.getSelection();

    if (selection && selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      const commonAncestor = range.commonAncestorContainer;
      let element: HTMLElement | null = null;

      if (commonAncestor.nodeType === Node.TEXT_NODE) {
        element = commonAncestor.parentElement;
      } else {
        element = commonAncestor as HTMLElement;
      }

      while (element && element !== editorRef.current) {
        const tagName = element.tagName.toLowerCase();
        if (tagName === 'strong' || tagName === 'b') formats.add('bold');
        if (tagName === 'em' || tagName === 'i') formats.add('italic');
        if (tagName === 'u') formats.add('underline');
        if (tagName === 'h1') formats.add('h1');
        if (tagName === 'h2') formats.add('h2');
        if (tagName === 'h3') formats.add('h3');
        if (tagName === 'ul') formats.add('ul');
        if (tagName === 'ol') formats.add('ol');

        const style = window.getComputedStyle(element);
        if (style.textAlign === 'center') formats.add('center');
        if (style.textAlign === 'right') formats.add('right');
        if (style.textAlign === 'left') formats.add('left');

        // Convert RGB/RGBA to hex for comparison
        const colorToHex = (color: string): string | null => {
          // If already hex format
          if (color.startsWith('#')) {
            return color.toUpperCase();
          }
          // If RGB/RGBA format
          const result = color.match(/\d+/g);
          if (!result || result.length < 3) return null;
          const r = result[0];
          const g = result[1];
          const b = result[2];
          if (!r || !g || !b) return null;
          const rHex = parseInt(r).toString(16).padStart(2, '0');
          const gHex = parseInt(g).toString(16).padStart(2, '0');
          const bHex = parseInt(b).toString(16).padStart(2, '0');
          return `#${rHex}${gHex}${bHex}`.toUpperCase();
        };

        // Check for background color (highlight)
        const bgColor = style.backgroundColor;
        // Check if background color is set and not transparent/default
        if (bgColor &&
          bgColor !== 'rgba(0, 0, 0, 0)' &&
          bgColor !== 'transparent' &&
          bgColor !== 'rgb(255, 255, 255)' &&
          bgColor !== '#ffffff' &&
          bgColor !== '#FFFFFF') {
          formats.add('highlight');
          const hexColor = colorToHex(bgColor);
          if (hexColor) {
            // Find matching color from our palette (allowing for slight variations)
            const matchedColor = HIGHLIGHT_COLORS.find(c => {
              if (c.value === 'transparent') return false;
              // Compare hex values (case-insensitive)
              return c.value.toUpperCase() === hexColor;
            });
            if (matchedColor) {
              setCurrentHighlightColor(matchedColor.value);
            } else {
              // Store the actual color even if not in our palette
              setCurrentHighlightColor(hexColor);
            }
          }
        } else if (!formats.has('highlight')) {
          // Only reset if we haven't found a highlight yet
          setCurrentHighlightColor(null);
        }

        // Check for text color
        const textColor = style.color;
        // Convert to hex for comparison
        const hexTextColor = colorToHex(textColor);
        // Check if text color is set and not default black
        if (textColor && hexTextColor &&
          textColor !== 'rgba(0, 0, 0, 0)' &&
          hexTextColor !== '#000000') {
          formats.add('textColor');
          // Find matching color from our palette
          const matchedColor = HIGHLIGHT_COLORS.find(c => {
            if (c.value === 'transparent') return false;
            return c.value.toUpperCase() === hexTextColor;
          });
          if (matchedColor) {
            setCurrentTextColor(matchedColor.value);
          } else {
            // Store the actual color even if not in our palette
            setCurrentTextColor(hexTextColor);
          }
        } else if (!formats.has('textColor')) {
          // Only reset if we haven't found a text color yet (default to black)
          if (hexTextColor === '#000000' || !hexTextColor) {
            setCurrentTextColor('#000000');
          } else {
            setCurrentTextColor(null);
          }
        }

        element = element.parentElement;
      }
    }

    setActiveFormats(formats);
  }, [isFocused]);

  // Apply formatting command
  const applyFormat = React.useCallback((command: string, value?: string) => {
    if (!editorRef.current) return;

    // Restore focus if needed
    if (!isFocused) {
      editorRef.current.focus();
    }

    // Save current selection
    const selection = window.getSelection();
    if (!selection || selection.rangeCount === 0) {
      // If no selection, focus the editor
      editorRef.current.focus();
      return;
    }

    // Execute formatting command
    document.execCommand(command, false, value);

    // Update content
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }

    // Check active formats after a short delay
    setTimeout(checkActiveFormats, 10);
  }, [isFocused, onChange, checkActiveFormats]);

  // Apply highlight color
  const applyHighlight = React.useCallback((color: string) => {
    if (!editorRef.current) return;

    // Restore focus if needed
    if (!isFocused) {
      editorRef.current.focus();
    }

    // Save current selection
    const selection = window.getSelection();
    if (!selection || selection.rangeCount === 0) {
      // If no selection, focus the editor
      editorRef.current.focus();
      return;
    }

    // Check if this color is already applied by checking the selection's style
    let isAlreadyApplied = false;
    if (selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      const commonAncestor = range.commonAncestorContainer;
      let element: HTMLElement | null = null;

      if (commonAncestor.nodeType === Node.TEXT_NODE) {
        element = commonAncestor.parentElement;
      } else {
        element = commonAncestor as HTMLElement;
      }

      // Check if the selected element has the same background color
      while (element && element !== editorRef.current) {
        const style = window.getComputedStyle(element);
        const bgColor = style.backgroundColor;
        if (bgColor && bgColor !== 'rgba(0, 0, 0, 0)' && bgColor !== 'transparent' &&
          bgColor !== 'rgb(255, 255, 255)' && bgColor !== '#ffffff' && bgColor !== '#FFFFFF') {
          // Convert to hex and compare
          const colorToHex = (c: string): string | null => {
            if (c.startsWith('#')) return c.toUpperCase();
            const result = c.match(/\d+/g);
            if (!result || result.length < 3) return null;
            const r = result[0];
            const g = result[1];
            const b = result[2];
            if (!r || !g || !b) return null;
            const rHex = parseInt(r).toString(16).padStart(2, '0');
            const gHex = parseInt(g).toString(16).padStart(2, '0');
            const bHex = parseInt(b).toString(16).padStart(2, '0');
            return `#${rHex}${gHex}${bHex}`.toUpperCase();
          };
          const hexBgColor = colorToHex(bgColor);
          if (hexBgColor && hexBgColor === color.toUpperCase()) {
            isAlreadyApplied = true;
            break;
          }
        }
        element = element.parentElement;
      }
    }

    // Use backColor command for highlight (background color)
    if (color === 'transparent' || isAlreadyApplied) {
      // Remove highlight - use a more aggressive approach to fully remove
      const range = selection.getRangeAt(0);
      if (!range.collapsed) {
        // Store the range before manipulation
        const contents = range.extractContents();

        // Create a new text node or span without background color
        const fragment = document.createDocumentFragment();

        // Process extracted contents to remove background colors
        const processNode = (node: Node) => {
          if (node.nodeType === Node.TEXT_NODE) {
            return node.cloneNode(true);
          } else if (node.nodeType === Node.ELEMENT_NODE) {
            const el = node as HTMLElement;
            const newEl = document.createElement(el.tagName.toLowerCase());

            // Copy all attributes except style-related ones
            Array.from(el.attributes).forEach(attr => {
              if (attr.name !== 'style' && attr.name !== 'class') {
                newEl.setAttribute(attr.name, attr.value);
              }
            });

            // Process children and copy without background color
            Array.from(el.childNodes).forEach(child => {
              const processed = processNode(child);
              if (processed) {
                newEl.appendChild(processed);
              }
            });

            // Remove background color if present
            if (el.style.backgroundColor) {
              newEl.style.backgroundColor = '';
            }

            return newEl;
          }
          return null;
        };

        Array.from(contents.childNodes).forEach(child => {
          const processed = processNode(child);
          if (processed) {
            fragment.appendChild(processed);
          }
        });

        // Insert the cleaned fragment
        range.insertNode(fragment);

        // Also use execCommand to ensure removal
        document.execCommand('removeFormat', false);
      } else {
        // No selection - remove format from current position
        document.execCommand('removeFormat', false);
      }
      setCurrentHighlightColor(null);
      setCustomColor('#FFEB3B'); // Reset to default
    } else {
      // Apply new highlight color - only if there's a selection
      if (selection.rangeCount > 0 && !selection.getRangeAt(0).collapsed) {
        document.execCommand('backColor', false, color);
        setCurrentHighlightColor(color);
        // Update custom color input if it's a valid hex color (not transparent)
        if (color !== 'transparent' && /^#[0-9A-Fa-f]{6}$/i.test(color)) {
          setCustomColor(color);
        }
      } else {
        // No selection - don't apply (prevents sticky mode where it applies to next typed text)
        return;
      }
    }

    // Clear selection immediately after applying to prevent "sticky" highlight mode
    const sel = window.getSelection();
    if (sel) {
      sel.removeAllRanges();
    }

    // Update content
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }

    // Close popover
    setHighlightColorOpen(false);

    // Refocus editor after a short delay and check formats
    setTimeout(() => {
      if (editorRef.current) {
        editorRef.current.focus();
      }
      checkActiveFormats();
    }, 50);
  }, [isFocused, onChange, checkActiveFormats]);

  // Apply text color
  const applyTextColor = React.useCallback((color: string) => {
    if (!editorRef.current) return;

    // Restore focus if needed
    if (!isFocused) {
      editorRef.current.focus();
    }

    // Save current selection
    const selection = window.getSelection();
    if (!selection || selection.rangeCount === 0) {
      // If no selection, focus the editor
      editorRef.current.focus();
      return;
    }

    // Check if this color is already applied by checking the selection's style
    let isAlreadyApplied = false;
    if (selection.rangeCount > 0) {
      const range = selection.getRangeAt(0);
      const commonAncestor = range.commonAncestorContainer;
      let element: HTMLElement | null = null;

      if (commonAncestor.nodeType === Node.TEXT_NODE) {
        element = commonAncestor.parentElement;
      } else {
        element = commonAncestor as HTMLElement;
      }

      // Check if the selected element has the same text color
      while (element && element !== editorRef.current) {
        const style = window.getComputedStyle(element);
        const textColor = style.color;
        if (textColor) {
          // Convert to hex and compare
          const colorToHex = (c: string): string | null => {
            if (c.startsWith('#')) return c.toUpperCase();
            const result = c.match(/\d+/g);
            if (!result || result.length < 3) return null;
            const r = result[0];
            const g = result[1];
            const b = result[2];
            if (!r || !g || !b) return null;
            const rHex = parseInt(r).toString(16).padStart(2, '0');
            const gHex = parseInt(g).toString(16).padStart(2, '0');
            const bHex = parseInt(b).toString(16).padStart(2, '0');
            return `#${rHex}${gHex}${bHex}`.toUpperCase();
          };
          const hexTextColor = colorToHex(textColor);
          // For black, also check if it's the default (no custom color)
          if (color === '#000000') {
            // If it's black and matches, or if no custom color is set (default black)
            if (hexTextColor === '#000000' || !hexTextColor) {
              isAlreadyApplied = true;
              break;
            }
          } else if (hexTextColor && hexTextColor === color.toUpperCase()) {
            isAlreadyApplied = true;
            break;
          }
        }
        element = element.parentElement;
      }
    }

    // Use foreColor command for text color
    if (color === 'transparent' || color === 'default' || isAlreadyApplied) {
      // Remove text color by removing format or setting to default
      // If clicking black when it's already default, do nothing or reset
      if (color === '#000000' && isAlreadyApplied) {
        // Already default, no need to change
        setTextColorOpen(false);
        return;
      }
      document.execCommand('removeFormat', false);
      setCurrentTextColor(null);
      setCustomTextColor('#000000'); // Reset to default black
    } else {
      document.execCommand('foreColor', false, color);
      setCurrentTextColor(color);
      // Update custom text color input if it's a valid hex color
      if (color !== 'transparent' && /^#[0-9A-Fa-f]{6}$/i.test(color)) {
        setCustomTextColor(color);
      }
    }

    // Update content
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }

    // Close popover
    setTextColorOpen(false);

    // Check active formats after a short delay
    setTimeout(checkActiveFormats, 10);
  }, [isFocused, onChange, checkActiveFormats]);

  // Handle input changes
  const handleInput = React.useCallback(() => {
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }
    checkActiveFormats();
  }, [onChange, checkActiveFormats]);

  // Handle keyboard shortcuts
  const handleKeyDown = React.useCallback((e: React.KeyboardEvent<HTMLDivElement>) => {
    // Ctrl+B for Bold
    if (e.ctrlKey && e.key === 'b') {
      e.preventDefault();
      applyFormat('bold');
      return;
    }
    // Ctrl+I for Italic
    if (e.ctrlKey && e.key === 'i') {
      e.preventDefault();
      applyFormat('italic');
      return;
    }
    // Ctrl+U for Underline
    if (e.ctrlKey && e.key === 'u') {
      e.preventDefault();
      applyFormat('underline');
      return;
    }
  }, [applyFormat]);

  // Handle focus
  const handleFocus = React.useCallback(() => {
    setIsFocused(true);
  }, []);

  // Handle blur
  const handleBlur = React.useCallback(() => {
    setIsFocused(false);
    if (editorRef.current) {
      onChange(sanitizeHTML(editorRef.current.innerHTML));
    }
  }, [onChange]);

  // Handle selection change to update active formats
  React.useEffect(() => {
    if (!isFocused) return;

    const handleSelectionChange = () => {
      checkActiveFormats();
    };

    document.addEventListener('selectionchange', handleSelectionChange);
    return () => {
      document.removeEventListener('selectionchange', handleSelectionChange);
    };
  }, [isFocused, checkActiveFormats]);

  return (
    <div className="relative border border-gray-300 rounded-md bg-white">
      {/* Formatting Toolbar */}
      <div className="flex items-center gap-1 p-2 border-b border-gray-200 bg-gray-50 rounded-t-md flex-wrap">
        {/* Text Formatting */}
        <div className="flex items-center gap-1 border-r border-gray-300 pr-2">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('bold') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('bold')}
            title="Bold (Ctrl+B)"
          >
            <Bold className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('italic') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('italic')}
            title="Italic (Ctrl+I)"
          >
            <Italic className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('underline') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('underline')}
            title="Underline (Ctrl+U)"
          >
            <Underline className="h-4 w-4" />
          </Button>

          {/* Highlight Color Picker */}
          <Popover open={highlightColorOpen} onOpenChange={setHighlightColorOpen}>
            <PopoverTrigger asChild>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                className={cn(
                  "h-7 w-7 p-0",
                  activeFormats.has('highlight') && "bg-blue-100 text-blue-700"
                )}
                title="Text Highlight"
              >
                <Highlighter className="h-4 w-4" />
              </Button>
            </PopoverTrigger>
            <PopoverContent
              className="w-auto p-2"
              align="start"
              onPointerDownOutside={(e) => {
                // Prevent closing when clicking inside popover
                const target = e.target as HTMLElement;
                if (target.closest('[data-popover-content]')) {
                  e.preventDefault();
                }
              }}
            >
              <div className="space-y-2 relative" onClick={(e) => e.stopPropagation()}>
                {/* Cancel Button */}
                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  className="absolute top-0 right-0 h-6 w-6 p-0 hover:bg-gray-100"
                  onClick={(e) => {
                    e.stopPropagation();
                    setHighlightColorOpen(false);
                  }}
                  title="Close"
                >
                  <X className="h-4 w-4 text-gray-500" />
                </Button>

                <div className="text-xs font-semibold text-gray-700 mb-2 pr-6">Highlight Color</div>
                <div className="grid grid-cols-6 gap-1.5 pr-1 mb-2">
                  {HIGHLIGHT_COLORS.map((color) => {
                    const isActive = currentHighlightColor === color.value;
                    const isNoColor = color.value === 'transparent';
                    return (
                      <button
                        key={color.value}
                        type="button"
                        onClick={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          // Standard toggle: if clicking the same color, remove it
                          if (isActive && !isNoColor) {
                            applyHighlight('transparent');
                          } else {
                            applyHighlight(color.value);
                          }
                        }}
                        className={cn(
                          "w-6 h-6 rounded border-2 transition-all hover:scale-110 hover:shadow-md relative",
                          color.class,
                          isActive && "ring-2 ring-blue-600 ring-offset-1 border-blue-600",
                          isNoColor && "border-gray-400 bg-white",
                          !isNoColor && !isActive && "border-gray-300"
                        )}
                        title={isActive && !isNoColor ? `${color.name} (Click to remove)` : color.name}
                        style={!isNoColor ? { backgroundColor: color.value } : {}}
                      >
                        {isNoColor && (
                          <span className="text-[10px] text-gray-600 font-bold">×</span>
                        )}
                        {isActive && !isNoColor && (
                          <span className="absolute inset-0 flex items-center justify-center">
                            <span className="w-2 h-2 bg-white rounded-full shadow-sm"></span>
                          </span>
                        )}
                      </button>
                    );
                  })}
                </div>

                {/* Remove Highlight Button - Standard pattern */}
                {currentHighlightColor && currentHighlightColor !== 'transparent' && (
                  <div className="mb-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="w-full h-7 text-xs"
                      onClick={(e) => {
                        e.stopPropagation();
                        applyHighlight('transparent');
                      }}
                      title="Remove highlight color"
                    >
                      Remove Highlight
                    </Button>
                  </div>
                )}

                {/* Custom Color Picker */}
                <div className="border-t border-gray-200 pt-2 mt-2">
                  <div className="text-xs font-semibold text-gray-700 mb-1.5">Custom Color</div>
                  <div className="flex items-center gap-2">
                    <input
                      type="color"
                      value={currentHighlightColor && currentHighlightColor !== 'transparent' ? currentHighlightColor : customColor}
                      onChange={(e) => {
                        const color = e.target.value;
                        setCustomColor(color);
                        // Only apply if there's selected text
                        const selection = window.getSelection();
                        if (selection && selection.rangeCount > 0 && !selection.getRangeAt(0).collapsed) {
                          applyHighlight(color);
                        }
                      }}
                      className="w-8 h-8 rounded border border-gray-300 cursor-pointer"
                      title="Pick a custom color"
                    />
                    <input
                      type="text"
                      value={currentHighlightColor && currentHighlightColor !== 'transparent' ? currentHighlightColor : customColor}
                      onChange={(e) => {
                        e.stopPropagation();
                        const color = e.target.value;
                        // Allow typing freely - don't restrict input
                        setCustomColor(color);
                      }}
                      onKeyDown={(e) => {
                        // Prevent popover from closing
                        e.stopPropagation();
                        // Allow all keys including backspace, delete, etc.
                        if (e.key === 'Enter') {
                          e.preventDefault();
                          const color = e.currentTarget.value.trim();
                          // Apply if valid hex color
                          if (/^#[0-9A-Fa-f]{6}$/i.test(color)) {
                            applyHighlight(color);
                          }
                        }
                      }}
                      onPaste={(e) => {
                        e.stopPropagation();
                        // Get pasted text from clipboard
                        const pastedText = e.clipboardData.getData('text').trim();
                        e.preventDefault();

                        // Process after paste event completes
                        setTimeout(() => {
                          // Check if it's a valid hex color with #
                          if (/^#[0-9A-Fa-f]{6}$/i.test(pastedText)) {
                            setCustomColor(pastedText);
                            // Auto-apply if text is selected in editor
                            const selection = window.getSelection();
                            if (selection && selection.rangeCount > 0 && !selection.getRangeAt(0).collapsed) {
                              applyHighlight(pastedText);
                            }
                          } else {
                            // Check if it's a hex color without # prefix (6 hex digits)
                            const hexMatch = pastedText.match(/^([0-9A-Fa-f]{6})$/);
                            if (hexMatch) {
                              const colorWithHash = `#${hexMatch[1]}`;
                              setCustomColor(colorWithHash);
                              const selection = window.getSelection();
                              if (selection && selection.rangeCount > 0 && !selection.getRangeAt(0).collapsed) {
                                applyHighlight(colorWithHash);
                              }
                            } else {
                              // If no match, allow default paste behavior (setTimeout allows default paste)
                              // Value will be updated by onChange
                            }
                          }
                        }, 0);
                      }}
                      onClick={(e) => {
                        e.stopPropagation();
                      }}
                      onFocus={(e) => {
                        e.stopPropagation();
                        // Select all text on focus for easy replacement
                        e.target.select();
                      }}
                      onBlur={(e) => {
                        // On blur, if valid color, apply it
                        const color = e.target.value.trim();
                        if (/^#[0-9A-Fa-f]{6}$/i.test(color)) {
                          const selection = window.getSelection();
                          if (selection && selection.rangeCount > 0 && !selection.getRangeAt(0).collapsed) {
                            applyHighlight(color);
                          }
                        } else if (color === '') {
                          // Reset to current if cleared
                          setCustomColor(currentHighlightColor || '#FFEB3B');
                        } else {
                          // Keep the typed value even if invalid (user might be typing)
                          setCustomColor(color);
                        }
                      }}
                      placeholder="#FFEB3B"
                      className="flex-1 h-7 px-2 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
                      title="Enter hex color code (Press Enter or click Apply). Supports copy-paste."
                      autoComplete="off"
                      spellCheck="false"
                    />
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      className="h-7 px-2 text-xs"
                      onClick={() => {
                        const color = customColor.trim();
                        if (/^#[0-9A-Fa-f]{6}$/i.test(color)) {
                          applyHighlight(color);
                        } else {
                          // If invalid, show current value or reset
                          setCustomColor(currentHighlightColor || '#FFEB3B');
                        }
                      }}
                      title="Apply custom color"
                    >
                      Apply
                    </Button>
                  </div>
                </div>
              </div>
            </PopoverContent>
          </Popover>

          {/* Text Color Picker */}
          <Popover open={textColorOpen} onOpenChange={setTextColorOpen}>
            <PopoverTrigger asChild>
              <Button
                type="button"
                variant="ghost"
                size="sm"
                className={cn(
                  "h-7 w-7 p-0",
                  activeFormats.has('textColor') && "bg-blue-100 text-blue-700"
                )}
                title="Text Color"
              >
                <Type className="h-4 w-4" />
              </Button>
            </PopoverTrigger>
            <PopoverContent
              className="w-auto p-2"
              align="start"
              onPointerDownOutside={(e) => {
                const target = e.target as HTMLElement;
                if (target.closest('[data-popover-content]')) {
                  e.preventDefault();
                }
              }}
            >
              <div className="space-y-2 relative" onClick={(e) => e.stopPropagation()}>
                {/* Cancel Button */}
                <Button
                  type="button"
                  variant="ghost"
                  size="sm"
                  className="absolute top-0 right-0 h-6 w-6 p-0 hover:bg-gray-100"
                  onClick={(e) => {
                    e.stopPropagation();
                    setTextColorOpen(false);
                  }}
                  title="Close"
                >
                  <X className="h-4 w-4 text-gray-500" />
                </Button>

                <div className="text-xs font-semibold text-gray-700 mb-2 pr-6">Text Color</div>
                <div className="grid grid-cols-6 gap-1.5 pr-1 mb-2">
                  {/* Default/Black Color Option - First position (standard) */}
                  <button
                    type="button"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      const isDefault = currentTextColor === '#000000' || (!currentTextColor && !activeFormats.has('textColor'));
                      // Toggle: if already default, do nothing (or could reset to default explicitly)
                      if (!isDefault) {
                        applyTextColor('#000000');
                      }
                    }}
                    className={cn(
                      "w-6 h-6 rounded border-2 transition-all hover:scale-110 hover:shadow-md flex items-center justify-center bg-black",
                      (currentTextColor === '#000000' || (!currentTextColor && !activeFormats.has('textColor'))) && "ring-2 ring-blue-600 ring-offset-1 border-blue-600",
                      (currentTextColor !== '#000000' && (currentTextColor || activeFormats.has('textColor'))) && "border-gray-300"
                    )}
                    title="Default (Black)"
                  >
                    <span className="text-[10px] text-white font-bold">A</span>
                    {(currentTextColor === '#000000' || (!currentTextColor && !activeFormats.has('textColor'))) && (
                      <span className="absolute inset-0 flex items-center justify-center">
                        <span className="w-2 h-2 bg-white rounded-full shadow-sm"></span>
                      </span>
                    )}
                  </button>
                  {HIGHLIGHT_COLORS.filter(c => c.value !== 'transparent').map((color) => {
                    const isActive = currentTextColor === color.value;
                    return (
                      <button
                        key={`text-${color.value}`}
                        type="button"
                        onClick={(e) => {
                          e.preventDefault();
                          e.stopPropagation();
                          // Standard toggle: if clicking the same color, reset to default
                          if (isActive) {
                            applyTextColor('#000000');
                          } else {
                            applyTextColor(color.value);
                          }
                        }}
                        className={cn(
                          "w-6 h-6 rounded border-2 transition-all hover:scale-110 hover:shadow-md flex items-center justify-center relative",
                          isActive && "ring-2 ring-blue-600 ring-offset-1 border-blue-600",
                          !isActive && "border-gray-300"
                        )}
                        title={isActive ? `${color.name} (Click to reset to default)` : color.name}
                        style={{ color: color.value, borderColor: isActive ? '#2563eb' : color.value }}
                      >
                        <span className="text-xs font-bold">A</span>
                        {isActive && (
                          <span className="absolute inset-0 flex items-center justify-center">
                            <span className="w-2 h-2 bg-white rounded-full shadow-sm"></span>
                          </span>
                        )}
                      </button>
                    );
                  })}
                </div>

                {/* Remove Text Color Button - Standard pattern */}
                {currentTextColor && currentTextColor !== '#000000' && (
                  <div className="mb-2">
                    <Button
                      type="button"
                      variant="outline"
                      size="sm"
                      className="w-full h-7 text-xs"
                      onClick={(e) => {
                        e.stopPropagation();
                        applyTextColor('#000000');
                      }}
                      title="Reset to default black"
                    >
                      Reset to Default
                    </Button>
                  </div>
                )}

                {/* Custom Text Color Picker */}
                <div className="border-t border-gray-200 pt-2 mt-2">
                  <div className="text-xs font-semibold text-gray-700 mb-1.5">Custom Color</div>
                  <div className="flex items-center gap-2">
                    <input
                      type="color"
                      value={currentTextColor || customTextColor}
                      onChange={(e) => {
                        const color = e.target.value;
                        setCustomTextColor(color);
                        applyTextColor(color);
                      }}
                      className="w-8 h-8 rounded border border-gray-300 cursor-pointer"
                      title="Pick a custom text color"
                    />
                    <input
                      type="text"
                      value={currentTextColor || customTextColor}
                      onChange={(e) => {
                        const color = e.target.value;
                        setCustomTextColor(color);
                        // Don't auto-apply, let user press Apply or Enter
                      }}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                          e.preventDefault();
                          const color = e.currentTarget.value;
                          if (/^#[0-9A-Fa-f]{6}$/.test(color)) {
                            applyTextColor(color);
                          }
                        }
                      }}
                      onBlur={(e) => {
                        // On blur, if valid color, apply it
                        const color = e.target.value;
                        if (/^#[0-9A-Fa-f]{6}$/.test(color)) {
                          applyTextColor(color);
                        } else if (color === '') {
                          // Reset to current if cleared
                          setCustomTextColor(currentTextColor || '#000000');
                        }
                      }}
                      placeholder="#000000"
                      className="flex-1 h-7 px-2 text-xs border border-gray-300 rounded focus:outline-none focus:ring-1 focus:ring-blue-500"
                      title="Enter hex color code (Press Enter or click Apply)"
                    />
                    <Button
                      type="button"
                      variant="ghost"
                      size="sm"
                      className="h-7 px-2 text-xs"
                      onClick={() => applyTextColor(customTextColor)}
                      title="Apply custom text color"
                    >
                      Apply
                    </Button>
                  </div>
                </div>
              </div>
            </PopoverContent>
          </Popover>
        </div>

        {/* Headings */}
        <div className="flex items-center gap-1 border-r border-gray-300 pr-2">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('h1') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('formatBlock', '<h1>')}
            title="Heading 1"
          >
            <Heading1 className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('h2') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('formatBlock', '<h2>')}
            title="Heading 2"
          >
            <Heading2 className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('h3') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('formatBlock', '<h3>')}
            title="Heading 3"
          >
            <Heading3 className="h-4 w-4" />
          </Button>
        </div>

        {/* Lists */}
        <div className="flex items-center gap-1 border-r border-gray-300 pr-2">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('ul') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('insertUnorderedList')}
            title="Bullet List"
          >
            <List className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('ol') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('insertOrderedList')}
            title="Numbered List"
          >
            <ListOrdered className="h-4 w-4" />
          </Button>
        </div>

        {/* Alignment */}
        <div className="flex items-center gap-1">
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('left') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('justifyLeft')}
            title="Align Left"
          >
            <AlignLeft className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('center') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('justifyCenter')}
            title="Align Center"
          >
            <AlignCenter className="h-4 w-4" />
          </Button>
          <Button
            type="button"
            variant="ghost"
            size="sm"
            className={cn(
              "h-7 w-7 p-0",
              activeFormats.has('right') && "bg-blue-100 text-blue-700"
            )}
            onClick={() => applyFormat('justifyRight')}
            title="Align Right"
          >
            <AlignRight className="h-4 w-4" />
          </Button>
        </div>
      </div>

      <div
        ref={editorRef}
        contentEditable
        onPaste={handlePaste}
        onInput={handleInput}
        onFocus={handleFocus}
        onBlur={handleBlur}
        onKeyDown={handleKeyDown}
        onMouseUp={checkActiveFormats}
        onKeyUp={checkActiveFormats}
        data-placeholder={placeholder}
        className={cn(
          "w-full rounded-b-md border-0 px-3 py-2 text-base transition-all outline-none",
          "bg-white text-gray-900",
          "min-h-[120px]",
          "overflow-y-auto",
          // Horizontal scrolling for smaller screens
          "overflow-x-auto",
          "md:overflow-x-visible",
          "md:text-sm",
          // Placeholder styling - match Input and Textarea
          "empty:before:content-[attr(data-placeholder)] empty:before:text-muted-foreground empty:before:pointer-events-none",
          // Focus styling
          "focus-visible:outline-none",
          // Preserve formatting styles
          "[&_ul]:list-disc [&_ul]:ml-6 [&_ul]:my-2 [&_ul]:list-outside",
          "[&_ol]:list-decimal [&_ol]:ml-6 [&_ol]:my-2 [&_ol]:list-outside",
          "[&_li]:my-1 [&_li]:pl-2",
          // Table wrapper for scrolling
          "[&_.table-wrapper]:overflow-x-auto [&_.table-wrapper]:max-w-full [&_.table-wrapper]:my-2",
          "[&_.table-wrapper_table]:border-collapse [&_.table-wrapper_table]:border [&_.table-wrapper_table]:border-gray-300 [&_.table-wrapper_table]:min-w-full",
          "[&_.table-wrapper_table_td]:border [&_.table-wrapper_table_td]:border-gray-300 [&_.table-wrapper_table_td]:px-3 [&_.table-wrapper_table_td]:py-2 [&_.table-wrapper_table_td]:text-sm [&_.table-wrapper_table_td]:whitespace-nowrap",
          "[&_.table-wrapper_table_th]:border [&_.table-wrapper_table_th]:border-gray-300 [&_.table-wrapper_table_th]:px-3 [&_.table-wrapper_table_th]:py-2 [&_.table-wrapper_table_th]:bg-gray-50 [&_.table-wrapper_table_th]:font-semibold [&_.table-wrapper_table_th]:text-sm [&_.table-wrapper_table_th]:text-left [&_.table-wrapper_table_th]:whitespace-nowrap",
          "[&_.table-wrapper_table_tr:nth-child(even)]:bg-gray-50",
          // Direct table styles (for tables not wrapped)
          "[&_table]:border-collapse [&_table]:my-2 [&_table]:border [&_table]:border-gray-300 [&_table]:w-full",
          "[&_table_td]:border [&_table_td]:border-gray-300 [&_table_td]:px-3 [&_table_td]:py-2 [&_table_td]:text-sm",
          "[&_table_th]:border [&_table_th]:border-gray-300 [&_table_th]:px-3 [&_table_th]:py-2 [&_table_th]:bg-gray-50 [&_table_th]:font-semibold [&_table_th]:text-sm [&_table_th]:text-left",
          "[&_table_tr:nth-child(even)]:bg-gray-50",
          "[&_p]:my-1 [&_p]:leading-relaxed",
          "[&_strong]:font-bold",
          "[&_em]:italic",
          "[&_u]:underline",
          // Highlight color styles - preserve background colors on spans
          "[&_span[style*='background']]:px-0.5 [&_span[style*='background']]:rounded",
          "[&_h1]:text-xl [&_h1]:font-bold [&_h1]:my-2",
          "[&_h2]:text-lg [&_h2]:font-semibold [&_h2]:my-2",
          "[&_h3]:text-base [&_h3]:font-semibold [&_h3]:my-1",
          className
        )}
        style={{ minHeight }}
        {...props}
      />
    </div>
  );
}

