import React, { useRef, useCallback, useState, useEffect, useMemo } from 'react';
import { 
  Box, 
  Button, 
  HStack, 
  Modal, 
  ModalOverlay, 
  ModalContent, 
  ModalHeader, 
  ModalCloseButton, 
  ModalBody, 
  ModalFooter,
  FormControl,
  FormLabel,
  FormHelperText,
  Input,
  Text,
  SimpleGrid,
  useToast,
  VStack,
  ButtonGroup,
  IconButton,
  Tooltip,
} from '@chakra-ui/react';
import ReactQuill from 'react-quill';
import ReactCrop, { Crop } from 'react-image-crop';
import DOMPurify from 'dompurify';
import 'react-quill/dist/quill.snow.css';
import 'react-image-crop/dist/ReactCrop.css';
import '../../styles/custom-editor.css';
import { 
  Image as ImageIcon, Code, Type, Trash2, AlignLeft, AlignCenter, AlignRight,
  RotateCw, RotateCcw, FlipHorizontal, FlipVertical, Sun, Droplets, Eye,
  Sparkles, Contrast, ZoomIn, ZoomOut, Move, Maximize2, Settings,
  Circle, Square, X, Check, Filter
} from 'lucide-react';
import { Image as ChakraImage } from '@chakra-ui/react';
import { cropAndUpload, quickEditImage } from '../../services/imageProcessing';
import { assetUrl } from '../../utils/url';

interface ImageFilters {
  brightness: number;
  contrast: number;
  saturation: number;
  blur: number;
  grayscale: number;
  sepia: number;
  hueRotate: number;
  rotation: number;
  flipH: boolean;
  flipV: boolean;
}

interface CustomRichEditorProps {
  value: string;
  onChange: (value: string) => void;
  placeholder?: string;
  height?: string;
  readOnly?: boolean;
  onImageUpload?: (file: File) => Promise<{ url: string }>;
  showImageResize?: boolean;
  toolbar?: 'full' | 'basic' | 'minimal';
}

const CustomRichEditor: React.FC<CustomRichEditorProps> = ({
  value,
  onChange,
  placeholder = 'Začněte psát...',
  height = '400px',
  readOnly = false,
  onImageUpload,
  showImageResize = true,
  toolbar = 'full',
}) => {
  const toast = useToast();
  const quillRef = useRef<ReactQuill | null>(null);
  const toolbarRef = useRef<HTMLDivElement | null>(null);
  const onChangeRef = useRef(onChange);
  const selectedImageIdRef = useRef<string | null>(null);
  const selectImageByIdRef = useRef<(id: string) => void>(() => {});
  const toolbarDragRef = useRef<{ active: boolean; startX: number; startY: number; startLeft: number; startTop: number }>({ active: false, startX: 0, startY: 0, startLeft: 0, startTop: 0 });
  const [isMounted, setIsMounted] = useState(false);
  
  // Ensure component is mounted before rendering Quill
  useEffect(() => {
    setIsMounted(true);
    return () => setIsMounted(false);
  }, []);
  
  // Keep onChange ref up to date
  useEffect(() => {
    onChangeRef.current = onChange;
  }, [onChange]);
  
  // Crop modal state
  const [cropOpen, setCropOpen] = useState(false);
  const [cropSrc, setCropSrc] = useState<string | null>(null);
  const [cropFile, setCropFile] = useState<File | null>(null);
  const [crop, setCrop] = useState<Crop>({ unit: '%', width: 80, height: 80, x: 10, y: 10 });
  const [cropQuality, setCropQuality] = useState<number>(85);
  const [cropMaxWidth, setCropMaxWidth] = useState<number>(1500);
  const [cropProcessing, setCropProcessing] = useState(false);
  const imgRef = useRef<HTMLImageElement | null>(null);

  // Force white mode for better readability in admin
  const borderColor = 'gray.200';
  const bgColor = 'white';
  const hoverBg = 'gray.50';
  const toolbarBg = 'white';
  const toolbarBorder = 'gray.200';
  
  // Image editing state
  const [selectedImageElement, setSelectedImageElement] = useState<HTMLImageElement | null>(null);
  const [imageFilters, setImageFilters] = useState<ImageFilters>({
    brightness: 100,
    contrast: 100,
    saturation: 100,
    blur: 0,
    grayscale: 0,
    sepia: 0,
    hueRotate: 0,
    rotation: 0,
    flipH: false,
    flipV: false,
  });
  const [showImageToolbar, setShowImageToolbar] = useState(false);
  const [toolbarPosition, setToolbarPosition] = useState({ top: 0, left: 0 });
  const [previewImage, setPreviewImage] = useState<string | null>(null);
  const [isPreviewOpen, setIsPreviewOpen] = useState(false);
  const [imageWidth, setImageWidth] = useState<number>(0);
  const [manualWidth, setManualWidth] = useState<string>('');
  const [widthPercent, setWidthPercent] = useState<number>(0);

  // Define toolbar configurations
  const toolbarConfigs = {
    full: [
      [{ header: [1, 2, 3, false] }],
      ['bold', 'italic', 'underline', 'strike'],
      [{ color: [] }, { background: [] }],
      [{ list: 'ordered' }, { list: 'bullet' }],
      [{ align: [] }],
      ['link', 'image'],
      ['blockquote'],
      ['clean'],
    ],
    basic: [
      [{ header: [1, 2, 3, false] }],
      ['bold', 'italic', 'underline'],
      [{ list: 'ordered' }, { list: 'bullet' }],
      [{ align: [] }],
      ['link', 'image'],
      ['clean'],
    ],
    minimal: [
      ['bold', 'italic', 'underline'],
      [{ list: 'bullet' }],
      ['link'],
      ['clean'],
    ],
  };

  const toolbarConfig = useMemo(() => {
    return toolbarConfigs[toolbar] || toolbarConfigs.full;
  }, [toolbar]);

  // Image upload handler
  const handleImageUpload = useCallback(() => {
    const input = document.createElement('input');
    input.setAttribute('type', 'file');
    input.setAttribute('accept', 'image/*');
    input.onchange = async () => {
      const file = (input.files || [])[0];
      if (!file) return;
      setCropFile(file);
      const reader = new FileReader();
      reader.onload = () => {
        setCropSrc(reader.result as string);
        setCropOpen(true);
      };
      reader.readAsDataURL(file);
    };
    input.click();
  }, []);

  // Memoize modules to prevent Quill reinitialization
  const quillModules = useMemo(() => ({
    toolbar: {
      container: toolbarConfig,
      handlers: {
        image: onImageUpload ? handleImageUpload : undefined,
      },
    },
    clipboard: {
      matchVisual: false,
    },
  }), [toolbarConfig, onImageUpload, handleImageUpload]);

  // Localize Quill toolbar tooltips/labels to Czech
  useEffect(() => {
    if (!isMounted) return;
    const editor = quillRef.current?.getEditor();
    if (!editor) return;
    const container = editor.root?.parentElement; // .ql-container
    const toolbarEl = container?.previousElementSibling as HTMLElement | null; // .ql-toolbar
    if (!toolbarEl) return;

    const setTitle = (selector: string, title: string) => {
      toolbarEl.querySelectorAll(selector).forEach((el) => {
        (el as HTMLElement).setAttribute('title', title);
        (el as HTMLElement).setAttribute('aria-label', title);
      });
    };

    // Basic formatting
    setTitle('button.ql-bold', 'Tučné');
    setTitle('button.ql-italic', 'Kurzíva');
    setTitle('button.ql-underline', 'Podtržení');
    setTitle('button.ql-strike', 'Přeškrtnutí');
    setTitle('button.ql-link', 'Vložit odkaz');
    setTitle('button.ql-image', 'Vložit obrázek');
    setTitle('button.ql-blockquote', 'Citace');
    setTitle('button.ql-clean', 'Vyčistit formátování');

    // Lists
    setTitle('button.ql-list[value="ordered"]', 'Číslovaný seznam');
    setTitle('button.ql-list[value="bullet"]', 'Odrážkový seznam');

    // Alignment
    setTitle('button.ql-align', 'Zarovnání');
    setTitle('button.ql-align[value=""]', 'Zarovnat vlevo');
    setTitle('button.ql-align[value="center"]', 'Zarovnat na střed');
    setTitle('button.ql-align[value="right"]', 'Zarovnat vpravo');
    setTitle('button.ql-align[value="justify"]', 'Do bloku');

    // Colors and background
    setTitle('.ql-color .ql-picker-label', 'Barva textu');
    setTitle('.ql-background .ql-picker-label', 'Barva pozadí');

    // Headers
    setTitle('.ql-header .ql-picker-label', 'Nadpis');
    setTitle('.ql-header .ql-picker-item[data-value="1"]', 'Nadpis 1');
    setTitle('.ql-header .ql-picker-item[data-value="2"]', 'Nadpis 2');
    setTitle('.ql-header .ql-picker-item[data-value="3"]', 'Nadpis 3');
  }, [isMounted, toolbar]);

  // Get cropped blob
  const getCroppedBlob = (image: HTMLImageElement, cropPixels: { x: number; y: number; width: number; height: number }): Promise<Blob> => {
    const canvas = document.createElement('canvas');
    const scaleX = image.naturalWidth / image.width;
    const scaleY = image.naturalHeight / image.height;
    
    let outputWidth = Math.max(1, Math.round(cropPixels.width * scaleX));
    let outputHeight = Math.max(1, Math.round(cropPixels.height * scaleY));
    
    if (outputWidth > cropMaxWidth) {
      const scale = cropMaxWidth / outputWidth;
      outputWidth = cropMaxWidth;
      outputHeight = Math.round(outputHeight * scale);
    }
    
    canvas.width = outputWidth;
    canvas.height = outputHeight;
    const ctx = canvas.getContext('2d', { alpha: false });
    if (!ctx) throw new Error('Canvas not supported');
    
    ctx.imageSmoothingEnabled = true;
    ctx.imageSmoothingQuality = 'high';
    
    ctx.drawImage(
      image,
      Math.round(cropPixels.x * scaleX),
      Math.round(cropPixels.y * scaleY),
      Math.round(cropPixels.width * scaleX),
      Math.round(cropPixels.height * scaleY),
      0,
      0,
      outputWidth,
      outputHeight
    );
    
    return new Promise((resolve) => {
      canvas.toBlob((blob) => resolve(blob as Blob), 'image/jpeg', cropQuality / 100);
    });
  };

  // Confirm crop and insert
  const confirmCropAndInsert = async () => {
    try {
      setCropProcessing(true);
      
      if (!cropFile) {
        toast({ title: 'Chyba', description: 'Soubor není načten', status: 'error' });
        return;
      }
      
      if (!imgRef.current) {
        toast({ title: 'Chyba', description: 'Obrázek není načten', status: 'error' });
        return;
      }
      
      // Calculate crop data in natural image pixels (backend expects absolute pixels)
      const img = imgRef.current;
      const displayW = img.width;
      const displayH = img.height;
      const naturalW = img.naturalWidth || displayW;
      const naturalH = img.naturalHeight || displayH;
      const scaleX = naturalW / Math.max(1, displayW);
      const scaleY = naturalH / Math.max(1, displayH);
      const toDisplayPx = (val: number, size: number) => (crop.unit === '%' ? (val / 100) * size : val);

      let cropData = undefined;
      if (crop.width && crop.height && crop.width > 0 && crop.height > 0) {
        // Convert selection from displayed coordinates to natural pixel coordinates
        const dispX = Math.max(0, toDisplayPx(crop.x || 0, displayW));
        const dispY = Math.max(0, toDisplayPx(crop.y || 0, displayH));
        const dispW = Math.min(displayW, toDisplayPx(crop.width || displayW, displayW));
        const dispH = Math.min(displayH, toDisplayPx(crop.height || displayH, displayH));

        let natX = Math.round(dispX * scaleX);
        let natY = Math.round(dispY * scaleY);
        let natW = Math.round(dispW * scaleX);
        let natH = Math.round(dispH * scaleY);

        // Clamp within natural bounds
        if (natX + natW > naturalW) natW = naturalW - natX;
        if (natY + natH > naturalH) natH = naturalH - natY;
        natW = Math.max(1, natW);
        natH = Math.max(1, natH);

        cropData = { x: natX, y: natY, width: natW, height: natH };
      }
      
      toast({ title: 'Zpracování obrázku...', status: 'info', duration: 2000 });
      
      // Use backend to crop and upload
      const res = await cropAndUpload(cropFile, cropData, cropQuality, cropMaxWidth);
      
      if (!res.url) {
        throw new Error('Upload failed - no URL returned');
      }
      
      // Insert into editor
      const quill = quillRef.current?.getEditor();
      if (quill) {
        // Ensure editor is focused and ready
        quill.focus();
        
        // Use setTimeout to ensure Quill's internal state is ready
        setTimeout(() => {
          try {
            const range = quill.getSelection();
            const index = range ? range.index : quill.getLength();
            
            const absoluteUrl = assetUrl(res.url) || res.url;
            const img = new Image();
            img.onload = () => {
              try {
                quill.insertEmbed(index, 'image', absoluteUrl, 'api');
                // Move cursor after the image
                quill.setSelection(index + 1, 0, 'api');
                // Force content change to trigger re-render
                onChangeRef.current(quill.root.innerHTML);
                toast({ title: 'Obrázek vložen', status: 'success', duration: 2000 });
              } catch (e) {
                console.error('Insert after preload error:', e);
                toast({ title: 'Chyba při vkládání obrázku', description: String(e), status: 'error' });
              }
            };
            img.onerror = () => {
              toast({ title: 'Obrázek nelze načíst', description: absoluteUrl, status: 'error' });
            };
            img.src = absoluteUrl;
          } catch (embedError) {
            console.error('Error inserting image:', embedError);
            toast({ title: 'Chyba při vkládání obrázku', description: String(embedError), status: 'error' });
          }
        }, 50);
      }
    } catch (e: any) {
      console.error('Crop and insert error:', e);
      toast({ title: 'Zpracování obrázku selhalo', description: e?.response?.data?.error || e?.message || 'Chyba', status: 'error' });
    } finally {
      setCropProcessing(false);
      setCropOpen(false);
      setCropSrc(null);
      setCropFile(null);
      setCrop({ unit: '%', width: 80, height: 80, x: 10, y: 10 });
      setCropQuality(85);
      setCropMaxWidth(1500);
    }
  };

  // Make images draggable and resizable
  useEffect(() => {
    const editor = quillRef.current?.getEditor();
    if (!editor || readOnly) return;

    let selectedImage: HTMLImageElement | null = null;
    let resizeHandle: HTMLDivElement | null = null;
    let isResizing = false;
    let isDragging = false;
    let startX = 0;
    let startY = 0;
    let startWidth = 0;
    let rafId = 0;

    const createResizeHandle = (img: HTMLImageElement) => {
      removeResizeHandle();
      
      // Create container for all resize handles
      const container = document.createElement('div');
      container.className = 'custom-image-resize-container';
      container.style.cssText = `
        position: absolute;
        pointer-events: none;
        z-index: 1000;
      `;
      
      const rect = img.getBoundingClientRect();
      const editorRect = editor.root.getBoundingClientRect();
      const scrollTop = editor.root.scrollTop;
      const scrollLeft = editor.root.scrollLeft;
      const sizeLabel = document.createElement('div');
      sizeLabel.style.cssText = `
        position: absolute;
        top: -26px;
        right: 0;
        background: rgba(26,32,44,0.9);
        color: #fff;
        font-size: 11px;
        line-height: 1;
        padding: 4px 6px;
        border-radius: 4px;
        pointer-events: none;
        box-shadow: 0 2px 6px rgba(0,0,0,0.3);
      `;
      const updateSizeLabel = (w: number) => {
        try {
          const edW = editor.root.clientWidth || w || 1;
          const pct = Math.max(1, Math.min(100, Math.round((w / edW) * 100)));
          sizeLabel.textContent = `${Math.round(w)} px (${pct}%)`;
        } catch {
          sizeLabel.textContent = `${Math.round(w)} px`;
        }
      };
      
      // Create edge handles (right, bottom, left, top)
      const handles = [
        { position: 'right', cursor: 'ew-resize', width: '12px', height: '60%' },
        { position: 'bottom', cursor: 'ns-resize', width: '60%', height: '12px' },
        { position: 'left', cursor: 'ew-resize', width: '12px', height: '60%' },
        { position: 'top', cursor: 'ns-resize', width: '60%', height: '12px' },
        { position: 'bottom-right', cursor: 'nwse-resize', width: '20px', height: '20px', isCorner: true },
        { position: 'bottom-left', cursor: 'nesw-resize', width: '20px', height: '20px', isCorner: true },
        { position: 'top-right', cursor: 'nesw-resize', width: '20px', height: '20px', isCorner: true },
        { position: 'top-left', cursor: 'nwse-resize', width: '20px', height: '20px', isCorner: true },
      ];
      
      const updateHandlePositions = () => {
        const rect = img.getBoundingClientRect();
        const editorRect = editor.root.getBoundingClientRect();
        const scrollTop = editor.root.scrollTop;
        const scrollLeft = editor.root.scrollLeft;
        
        container.style.left = `${rect.left - editorRect.left + scrollLeft}px`;
        container.style.top = `${rect.top - editorRect.top + scrollTop}px`;
        container.style.width = `${rect.width}px`;
        container.style.height = `${rect.height}px`;
      };
      
      handles.forEach(({ position, cursor, width, height, isCorner }) => {
        const handle = document.createElement('div');
        handle.className = `custom-image-resize-handle custom-resize-${position}`;
        
        let positionStyle = 'position: absolute; pointer-events: auto; transition: all 0.2s;';
        
        if (isCorner) {
          // Corner handle - circular blue dot
          positionStyle += `
            width: ${width};
            height: ${height};
            background: linear-gradient(135deg, #3182ce 0%, #2c5aa0 100%);
            border: 3px solid white;
            border-radius: 50%;
            box-shadow: 0 2px 8px rgba(0,0,0,0.4), 0 0 0 1px rgba(49, 130, 206, 0.3);
          `;
          
          if (position === 'bottom-right') {
            positionStyle += 'right: -8px; bottom: -8px;';
          } else if (position === 'bottom-left') {
            positionStyle += 'left: -8px; bottom: -8px;';
          } else if (position === 'top-right') {
            positionStyle += 'right: -8px; top: -8px;';
          } else if (position === 'top-left') {
            positionStyle += 'left: -8px; top: -8px;';
          }
        } else {
          // Edge handle - thin blue bar
          positionStyle += `
            background: rgba(49, 130, 206, 0.6);
            border: 1px solid rgba(49, 130, 206, 0.8);
          `;
          
          if (position === 'right') {
            positionStyle += `width: ${width}; height: ${height}; right: -4px; top: 50%; transform: translateY(-50%);`;
          } else if (position === 'bottom') {
            positionStyle += `width: ${width}; height: ${height}; bottom: -4px; left: 50%; transform: translateX(-50%);`;
          } else if (position === 'left') {
            positionStyle += `width: ${width}; height: ${height}; left: -4px; top: 50%; transform: translateY(-50%);`;
          } else if (position === 'top') {
            positionStyle += `width: ${width}; height: ${height}; top: -4px; left: 50%; transform: translateX(-50%);`;
          }
        }
        
        positionStyle += `cursor: ${cursor};`;
        handle.style.cssText = positionStyle;
        
        // Hover effect for corners
        if (isCorner) {
          handle.addEventListener('mouseenter', () => {
            handle.style.transform = 'scale(1.3)';
            handle.style.boxShadow = '0 3px 12px rgba(0,0,0,0.5), 0 0 0 2px rgba(49, 130, 206, 0.5)';
          });
          
          handle.addEventListener('mouseleave', () => {
            if (!isResizing) {
              handle.style.transform = 'scale(1)';
              handle.style.boxShadow = '0 2px 8px rgba(0,0,0,0.4), 0 0 0 1px rgba(49, 130, 206, 0.3)';
            }
          });
        } else {
          // Hover effect for edges
          handle.addEventListener('mouseenter', () => {
            handle.style.background = 'rgba(49, 130, 206, 0.9)';
          });
          
          handle.addEventListener('mouseleave', () => {
            if (!isResizing) {
              handle.style.background = 'rgba(49, 130, 206, 0.6)';
            }
          });
        }
        
        handle.addEventListener('pointerdown', (e: PointerEvent) => {
          e.preventDefault();
          e.stopPropagation();
          e.stopImmediatePropagation();
          isResizing = true;
          startX = e.clientX;
          startY = e.clientY;
          startWidth = img.offsetWidth;
          const startHeight = img.offsetHeight;
          const aspectRatio = startWidth / startHeight;
          const onPointerMove = (ev: PointerEvent) => {
            if (!isResizing) return;
            const deltaX = ev.clientX - startX;
            const deltaY = ev.clientY - startY;
            let newWidth = startWidth;
            if (position.includes('right')) {
              newWidth = startWidth + deltaX;
            } else if (position.includes('left')) {
              newWidth = startWidth - deltaX;
            } else if (position.includes('bottom') || position.includes('top')) {
              newWidth = startWidth + (deltaY * aspectRatio);
            }
            newWidth = Math.max(50, Math.min(newWidth, editor.root.clientWidth - 40));
            img.style.width = `${newWidth}px`;
            img.style.maxWidth = '100%';
            img.style.height = 'auto';
            try { img.setAttribute('width', String(Math.round(newWidth))); } catch {}
            setImageWidth(newWidth);
            setManualWidth(newWidth.toString());
            try {
              const editorWidth = editor.root.clientWidth || newWidth || 1;
              setWidthPercent(Math.max(1, Math.min(100, Math.round((newWidth / editorWidth) * 100))));
            } catch {}
            updateHandlePositions();
            updateSizeLabel(newWidth);
          };
          const onPointerUp = () => {
            isResizing = false;
            document.removeEventListener('pointermove', onPointerMove);
            document.removeEventListener('pointerup', onPointerUp);
            onChangeRef.current(editor.root.innerHTML);
            const id = selectedImageIdRef.current;
            setTimeout(() => { if (id) { try { selectImageByIdRef.current?.(id); } catch {} } }, 30);
          };
          document.addEventListener('pointermove', onPointerMove);
          document.addEventListener('pointerup', onPointerUp);
        });
        
        container.appendChild(handle);
      });
      
      updateHandlePositions();
      updateSizeLabel(img.offsetWidth || img.width || 0);
      editor.root.style.position = 'relative';
      editor.root.appendChild(container);
      container.appendChild(sizeLabel);
      resizeHandle = container;
      
      return container;
    };

    const removeResizeHandle = () => {
      if (resizeHandle && resizeHandle.parentNode) {
        resizeHandle.parentNode.removeChild(resizeHandle);
        resizeHandle = null;
      }
    };

    const selectImage = (img: HTMLImageElement) => {
      if (selectedImage) {
        selectedImage.style.outline = '';
        selectedImage.style.cursor = '';
        selectedImage.style.boxShadow = '';
      }
      
      selectedImage = img;
      // Ensure image has a persistent ID for reselection after content updates
      let id = img.getAttribute('data-img-id') || '';
      if (!id) {
        id = 'img-' + Date.now() + '-' + Math.random().toString(36).slice(2);
        try { img.setAttribute('data-img-id', id); } catch {}
      }
      selectedImageIdRef.current = id;
      img.style.outline = '3px solid #3182ce';
      img.style.cursor = 'move';
      img.style.boxShadow = '0 4px 12px rgba(49, 130, 206, 0.3)';
      
      // Prevent default drag behavior to avoid duplication
      img.setAttribute('draggable', 'false');
      
      createResizeHandle(img);
      
      // Set selected image state and load filters
      setSelectedImageElement(img);
      
      // Get current width
      const currentWidth = img.offsetWidth || img.width;
      setImageWidth(currentWidth);
      setManualWidth(currentWidth.toString());
      try {
        const editorWidth = editor.root.clientWidth || currentWidth || 1;
        setWidthPercent(Math.max(1, Math.min(100, Math.round((currentWidth / editorWidth) * 100))));
      } catch {}
      
      // Load saved filters
      const filtersData = img.getAttribute('data-filters');
      if (filtersData) {
        try {
          const savedFilters = JSON.parse(filtersData);
          setImageFilters(savedFilters);
        } catch {
          // If parsing fails, reset to defaults
          setImageFilters({
            brightness: 100,
            contrast: 100,
            saturation: 100,
            blur: 0,
            grayscale: 0,
            sepia: 0,
            hueRotate: 0,
            rotation: 0,
            flipH: false,
            flipV: false,
          });
        }
      }
      
      // Show toolbar and position it next to the image
      const rect = img.getBoundingClientRect();
      const editorRect = editor.root.getBoundingClientRect();
      const scrollTop = editor.root.scrollTop;
      const scrollLeft = editor.root.scrollLeft;
      
      // Place toolbar close to the image (top-right corner inside the image area when possible)
      const toolbarWidth = 380;
      const margin = 8;
      let leftPos = rect.left - editorRect.left + scrollLeft + (rect.width > toolbarWidth + margin ? (rect.width - toolbarWidth - margin) : margin);
      leftPos = Math.max(margin, Math.min(leftPos, editorRect.width - toolbarWidth - margin));
      let topPos = rect.top - editorRect.top + scrollTop + margin;
      topPos = Math.max(margin, topPos);
      
      setToolbarPosition({
        top: topPos,
        left: leftPos,
      });
      setShowImageToolbar(true);
    };

    // Expose reselection helper bound to current effect scope
    selectImageByIdRef.current = (id: string) => {
      const ed = quillRef.current?.getEditor();
      if (!ed) return;
      const node = ed.root.querySelector(`img[data-img-id="${id}"]`) as HTMLImageElement | null;
      if (node) {
        selectImage(node);
      }
    };

    const deselectImage = () => {
      if (selectedImage) {
        selectedImage.style.outline = '';
        selectedImage.style.cursor = '';
        selectedImage.style.boxShadow = '';
        selectedImage = null;
      }
      removeResizeHandle();
      setSelectedImageElement(null);
      setShowImageToolbar(false);
      setImageWidth(0);
      setManualWidth('');
    };

    const handleImageClick = (e: Event) => {
      const target = e.target as HTMLElement;
      if (target.tagName === 'IMG') {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        
        // In read-only mode, show preview instead of selecting
        if (readOnly) {
          const imgSrc = (target as HTMLImageElement).src;
          setPreviewImage(imgSrc);
          setIsPreviewOpen(true);
          return;
        }
        
        selectImage(target as HTMLImageElement);
        return; // Important: return early to prevent further processing
      }
      
      // Don't deselect if clicking on resize handle or toolbar
      if (target.classList.contains('custom-image-resize-handle') || 
          target.classList.contains('custom-image-resize-container')) {
        e.preventDefault();
        e.stopPropagation();
        return;
      }
      if (toolbarRef.current && (toolbarRef.current === target || toolbarRef.current.contains(target))) {
        e.preventDefault();
        e.stopPropagation();
        return; // Don't deselect if clicking inside toolbar
      }
      
      // Only deselect if clicking outside image, toolbar, and handle
      deselectImage();
    };

    const handleMouseDown = (e: MouseEvent) => {
      const target = e.target as HTMLElement;
      if (target.tagName === 'IMG' && selectedImage === target) {
        // Allow edge-drag fallback resize if overlay handle doesn't catch it
        const rect = target.getBoundingClientRect();
        const nearLeft = e.clientX < rect.left + 16;
        const nearRight = e.clientX > rect.right - 16;
        const nearTop = e.clientY < rect.top + 16;
        const nearBottom = e.clientY > rect.bottom - 16;
        if (nearLeft || nearRight || nearTop || nearBottom) {
          e.preventDefault();
          e.stopPropagation();
          isResizing = true;
          startX = e.clientX;
          startY = e.clientY;
          startWidth = (target as HTMLImageElement).offsetWidth;
          const startHeight = (target as HTMLImageElement).offsetHeight;
          const aspectRatio = startWidth / Math.max(1, startHeight);
          const edge = nearRight ? 'right' : nearLeft ? 'left' : nearBottom ? 'bottom' : 'top';

          const onMouseMove: (ev: MouseEvent) => void = (ev: MouseEvent) => {
            if (!isResizing) return;
            const deltaX = ev.clientX - startX;
            const deltaY = ev.clientY - startY;
            let newWidth = startWidth;
            if (edge === 'right') newWidth = startWidth + deltaX;
            else if (edge === 'left') newWidth = startWidth - deltaX;
            else if (edge === 'bottom') newWidth = startWidth + (deltaY * aspectRatio);
            else if (edge === 'top') newWidth = startWidth - (deltaY * aspectRatio);
            const maxW = editor.root.clientWidth - 40;
            newWidth = Math.max(50, Math.min(newWidth, maxW));
            const imgEl = target as HTMLImageElement;
            imgEl.style.width = `${newWidth}px`;
            imgEl.style.maxWidth = '100%';
            imgEl.style.height = 'auto';
            try { imgEl.setAttribute('width', String(Math.round(newWidth))); } catch {}
            setImageWidth(newWidth);
            setManualWidth(String(Math.round(newWidth)));
            try {
              const editorWidth = editor.root.clientWidth || newWidth || 1;
              setWidthPercent(Math.max(1, Math.min(100, Math.round((newWidth / editorWidth) * 100))));
            } catch {}
            handleScroll();
          };

          const onMouseUp = () => {
            isResizing = false;
            document.removeEventListener('mousemove', onMouseMove);
            document.removeEventListener('mouseup', onMouseUp);
            onChangeRef.current(editor.root.innerHTML);
          };

          document.addEventListener('mousemove', onMouseMove);
          document.addEventListener('mouseup', onMouseUp);
          return;
        }
        
        e.preventDefault();
        e.stopPropagation();
        isDragging = true;
        startX = e.clientX;
        startY = e.clientY;
        
        // Store initial alignment to prevent copying behavior
        const initialMarginLeft = selectedImage.style.marginLeft || '';
        const initialMarginRight = selectedImage.style.marginRight || '';
        let currentAlignment: 'left' | 'center' | 'right' = 'center';
        
        if (initialMarginLeft === '0' || initialMarginLeft === '0px') {
          currentAlignment = 'left';
        } else if (initialMarginRight === '0' || initialMarginRight === '0px') {
          currentAlignment = 'right';
        }
        
        // Already set in selectImage, but ensure it's off
        target.setAttribute('draggable', 'false');
        
        const onMouseMove: (e: MouseEvent) => void = (e: MouseEvent) => {
          if (!isDragging || !selectedImage) return;
          
          const deltaX = e.clientX - startX;
          
          // Require significant movement to trigger alignment change
          if (Math.abs(deltaX) > 50) {
            const newAlignment = deltaX > 0 ? 'right' : 'left';
            
            // Only update if alignment actually changed
            if (newAlignment !== currentAlignment) {
              currentAlignment = newAlignment;
              startX = e.clientX; // Reset start position
              
              selectedImage.style.display = 'block';
              selectedImage.style.float = 'none';
              
              if (newAlignment === 'right') {
                selectedImage.style.marginLeft = 'auto';
                selectedImage.style.marginRight = '0';
              } else {
                selectedImage.style.marginLeft = '0';
                selectedImage.style.marginRight = 'auto';
              }
            }
          }
        };
        
        const onMouseUp: (e: MouseEvent) => void = () => {
          isDragging = false;
          document.removeEventListener('mousemove', onMouseMove);
          document.removeEventListener('mouseup', onMouseUp);
          if (selectedImage) {
            onChangeRef.current(editor.root.innerHTML);
          }
        };
        
        document.addEventListener('mousemove', onMouseMove);
        document.addEventListener('mouseup', onMouseUp);
      }
    };

    // Delete selected image on Delete key
    const handleKeyDown = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement | null;
      const tag = target?.tagName;
      // Do not act on Delete/Backspace if user is typing in an input, textarea, or contentEditable
      if (tag === 'INPUT' || tag === 'TEXTAREA' || (target && (target as any).isContentEditable)) {
        return;
      }
      if (selectedImage && (e.key === 'Delete' || e.key === 'Backspace')) {
        e.preventDefault();
        selectedImage.remove();
        deselectImage();
        onChangeRef.current(editor.root.innerHTML);
        toast({ title: 'Obrázek odstraněn', status: 'info', duration: 1500 });
      }
    };

    // Handle scroll to update resize handle position
    const handleScroll = () => {
      if (!selectedImage || !resizeHandle) return;
      if (rafId) cancelAnimationFrame(rafId);
      rafId = requestAnimationFrame(() => {
        const rect = selectedImage!.getBoundingClientRect();
        const editorRect = editor.root.getBoundingClientRect();
        const scrollTop = editor.root.scrollTop;
        const scrollLeft = editor.root.scrollLeft;
        resizeHandle!.style.left = `${rect.left - editorRect.left + scrollLeft}px`;
        resizeHandle!.style.top = `${rect.top - editorRect.top + scrollTop}px`;
        resizeHandle!.style.width = `${rect.width}px`;
        resizeHandle!.style.height = `${rect.height}px`;
      });
    };

    // Prevent default drag behavior on images
    const handleDragStart = (e: DragEvent) => {
      const target = e.target as HTMLElement;
      if (target.tagName === 'IMG') {
        e.preventDefault();
        e.stopPropagation();
        return false;
      }
    };

    editor.root.addEventListener('click', handleImageClick);
    editor.root.addEventListener('mousedown', handleMouseDown);
    editor.root.addEventListener('scroll', handleScroll);
    editor.root.addEventListener('dragstart', handleDragStart);
    document.addEventListener('keydown', handleKeyDown);
    // Also reposition on window resize and any document scroll (capture phase)
    window.addEventListener('resize', handleScroll);
    document.addEventListener('scroll', handleScroll, true);

    return () => {
      editor.root.removeEventListener('click', handleImageClick);
      editor.root.removeEventListener('mousedown', handleMouseDown);
      editor.root.removeEventListener('scroll', handleScroll);
      editor.root.removeEventListener('dragstart', handleDragStart);
      document.removeEventListener('keydown', handleKeyDown);
      window.removeEventListener('resize', handleScroll);
      document.removeEventListener('scroll', handleScroll, true);
      if (rafId) cancelAnimationFrame(rafId);
      removeResizeHandle();
      deselectImage();
    };
  }, [readOnly, toast, isMounted]);

  // Apply filters to selected image
  const applyFiltersToImage = useCallback((img: HTMLImageElement, filters: ImageFilters) => {
    const filterString = `
      brightness(${filters.brightness}%)
      contrast(${filters.contrast}%)
      saturate(${filters.saturation}%)
      blur(${filters.blur}px)
      grayscale(${filters.grayscale}%)
      sepia(${filters.sepia}%)
      hue-rotate(${filters.hueRotate}deg)
    `.trim();
    
    const transform = `
      rotate(${filters.rotation}deg)
      scaleX(${filters.flipH ? -1 : 1})
      scaleY(${filters.flipV ? -1 : 1})
    `.trim();
    
    img.style.filter = filterString;
    img.style.transform = transform;
    img.setAttribute('data-filters', JSON.stringify(filters));
  }, []);

  // Reset filters
  const resetFilters = useCallback(() => {
    const defaultFilters: ImageFilters = {
      brightness: 100,
      contrast: 100,
      saturation: 100,
      blur: 0,
      grayscale: 0,
      sepia: 0,
      hueRotate: 0,
      rotation: 0,
      flipH: false,
      flipV: false,
    };
    setImageFilters(defaultFilters);
    if (selectedImageElement) {
      applyFiltersToImage(selectedImageElement, defaultFilters);
    }
  }, [selectedImageElement, applyFiltersToImage]);

  // Update filter and apply to image (preview only - client-side)
  const updateFilter = useCallback((key: keyof ImageFilters, value: any) => {
    setImageFilters(prev => {
      const newFilters = { ...prev, [key]: value };
      if (selectedImageElement) {
        applyFiltersToImage(selectedImageElement, newFilters);
      }
      return newFilters;
    });
  }, [selectedImageElement, applyFiltersToImage]);

  // Apply filters via backend and replace image
  const [isApplyingFilters, setIsApplyingFilters] = useState(false);
  const applyFiltersToBackend = useCallback(async () => {
    if (!selectedImageElement) return;
    
    try {
      setIsApplyingFilters(true);
      toast({ title: 'Zpracování filtry...', status: 'info', duration: 2000 });
      
      const currentSrc = selectedImageElement.src;
      
      // Prepare filter values for backend (convert from % to -100 to 100 scale)
      const brightness = imageFilters.brightness - 100;
      const contrast = imageFilters.contrast - 100;
      const saturation = imageFilters.saturation - 100;
      
      const res = await quickEditImage({
        image_url: currentSrc,
        width: selectedImageElement.offsetWidth || undefined,
        rotation: imageFilters.rotation,
        flip_h: imageFilters.flipH,
        flip_v: imageFilters.flipV,
        brightness,
        contrast,
        saturation,
        grayscale: imageFilters.grayscale > 0,
        quality: 85,
      });
      
      // Replace image src
      const absoluteUrl = assetUrl(res.url) || res.url;
      selectedImageElement.src = absoluteUrl;
      
      // Reset filters to default since they're now baked into the image
      setImageFilters({
        brightness: 100,
        contrast: 100,
        saturation: 100,
        blur: 0,
        grayscale: 0,
        sepia: 0,
        hueRotate: 0,
        rotation: 0,
        flipH: false,
        flipV: false,
      });
      selectedImageElement.style.filter = '';
      selectedImageElement.style.transform = '';
      selectedImageElement.removeAttribute('data-filters');
      
      // Update editor content
      const editor = quillRef.current?.getEditor();
      if (editor) {
        onChangeRef.current(editor.root.innerHTML);
      }
      reselectAfterContentUpdate();
      
      toast({ title: 'Filtry aplikovány', status: 'success', duration: 2000 });
    } catch (e: any) {
      console.error('Apply filters error:', e);
      toast({ title: 'Aplikace filtrů selhala', description: e?.response?.data?.error || e?.message, status: 'error' });
    } finally {
      setIsApplyingFilters(false);
    }
  }, [selectedImageElement, imageFilters, toast]);

  // Align image
  const alignImage = useCallback((alignment: 'left' | 'center' | 'right') => {
    if (selectedImageElement) {
      selectedImageElement.style.display = 'block';
      selectedImageElement.style.float = 'none';
      
      if (alignment === 'left') {
        selectedImageElement.style.marginLeft = '0';
        selectedImageElement.style.marginRight = 'auto';
      } else if (alignment === 'center') {
        selectedImageElement.style.marginLeft = 'auto';
        selectedImageElement.style.marginRight = 'auto';
      } else if (alignment === 'right') {
        selectedImageElement.style.marginLeft = 'auto';
        selectedImageElement.style.marginRight = '0';
      }
      
      const editor = quillRef.current?.getEditor();
      if (editor) {
        onChangeRef.current(editor.root.innerHTML);
        // Force overlay reposition
        try { editor.root.dispatchEvent(new Event('scroll')); } catch {}
      }
      reselectAfterContentUpdate();
      toast({ title: `Obrázek zarovnán ${alignment === 'left' ? 'vlevo' : alignment === 'center' ? 'na střed' : 'vpravo'}`, status: 'success', duration: 1500 });
    }
  }, [selectedImageElement, toast]);

  // Reselect helper after content updates (e.g., when value change triggers rerender)
  const reselectAfterContentUpdate = useCallback(() => {
    const id = selectedImageIdRef.current;
    if (!id) return;
    setTimeout(() => {
      try { selectImageByIdRef.current?.(id); } catch {}
    }, 30);
  }, []);

  const applyWidthPx = useCallback((px: number, opts?: { silent?: boolean }) => {
    if (!selectedImageElement) return;
    const editor = quillRef.current?.getEditor();
    const maxWidth = editor ? editor.root.clientWidth - 40 : 1200;
    const finalWidth = Math.min(Math.max(50, Math.round(px)), maxWidth);
    selectedImageElement.style.width = `${finalWidth}px`;
    selectedImageElement.style.height = 'auto';
    selectedImageElement.style.maxWidth = '100%';
    selectedImageElement.setAttribute('width', String(finalWidth));
    setImageWidth(finalWidth);
    setManualWidth(finalWidth.toString());
    if (editor) {
      onChangeRef.current(editor.root.innerHTML);
    }
    // Keep selection active for subsequent operations (e.g., 50% → 75%)
    reselectAfterContentUpdate();
    if (!opts?.silent) {
      toast({ title: 'Šířka nastavena', description: `${finalWidth}px`, status: 'success', duration: 1500 });
    }
  }, [selectedImageElement, toast]);

  const resetWidth = useCallback(() => {
    if (!selectedImageElement) return;
    const editor = quillRef.current?.getEditor();
    selectedImageElement.style.width = '';
    selectedImageElement.style.height = '';
    selectedImageElement.style.maxWidth = '100%';
    selectedImageElement.removeAttribute('width');
    const currentWidth = selectedImageElement.offsetWidth || selectedImageElement.width || 0;
    setImageWidth(currentWidth);
    setManualWidth('');
    if (editor) {
      onChangeRef.current(editor.root.innerHTML);
    }
    reselectAfterContentUpdate();
    toast({ title: 'Šířka resetována', status: 'info', duration: 1200 });
  }, [selectedImageElement, toast]);

  const applyPercent = useCallback((percent: number, opts?: { silent?: boolean }) => {
    const clamped = Math.max(5, Math.min(100, Math.round(percent)));
    setWidthPercent(clamped);
    const editor = quillRef.current?.getEditor();
    if (editor && selectedImageElement) {
      const px = (editor.root.clientWidth * clamped) / 100;
      applyWidthPx(px, opts);
    }
  }, [applyWidthPx, selectedImageElement]);

  // Set manual width
  const applyManualWidth = useCallback(() => {
    if (selectedImageElement && manualWidth) {
      const raw = manualWidth.trim();
      if (raw.endsWith('%')) {
        const percent = parseFloat(raw.slice(0, -1));
        const editor = quillRef.current?.getEditor();
        if (editor && !isNaN(percent) && percent > 0) {
          const px = (editor.root.clientWidth * percent) / 100;
          applyWidthPx(px);
          return;
        }
      }
      const width = parseInt(raw, 10);
      if (!isNaN(width) && width > 0) {
        applyWidthPx(width);
      } else {
        toast({ title: 'Neplatná šířka', description: 'Zadejte kladné číslo nebo procenta (např. 50%)', status: 'warning', duration: 1500 });
      }
    }
  }, [selectedImageElement, manualWidth, toast, applyWidthPx]);

  // Delete selected image
  const deleteSelectedImage = useCallback(() => {
    if (selectedImageElement) {
      selectedImageElement.remove();
      setSelectedImageElement(null);
      setShowImageToolbar(false);
      const editor = quillRef.current?.getEditor();
      if (editor) {
        onChangeRef.current(editor.root.innerHTML);
      }
      toast({ title: 'Obrázek odstraněn', status: 'info', duration: 1500 });
    }
  }, [selectedImageElement, toast]);

  // Sanitize HTML on change and fix white text colors
  const handleChange = (content: string) => {
    // First sanitize
    let cleaned = DOMPurify.sanitize(content, {
      USE_PROFILES: { html: true },
      ADD_TAGS: ['iframe'],
      ADD_ATTR: ['target', 'rel', 'allow', 'allowfullscreen', 'style', 'data-filters', 'data-img-id'],
    });
    
    // Replace white and very light colors with dark colors for visibility
    const whiteColorPatterns = [
      /color:\s*rgb\(255,\s*255,\s*255\)/gi,
      /color:\s*rgb\(255\s*,\s*255\s*,\s*255\)/gi,
      /color:\s*white/gi,
      /color:\s*#fff(?:fff)?(?=[;\s"'])/gi,
      /color:\s*rgba?\(255,\s*255,\s*255/gi,
      // Very light grays that are barely visible on white
      /color:\s*rgb\(25[0-4],\s*25[0-4],\s*25[0-4]\)/gi,
      /color:\s*rgb\(24[5-9],\s*24[5-9],\s*24[5-9]\)/gi,
    ];
    
    whiteColorPatterns.forEach(pattern => {
      cleaned = cleaned.replace(pattern, 'color: #1a202c');
    });
    
    onChangeRef.current(cleaned);
  };

  return (
    <Box>
      {/* Editor Controls */}
      {!readOnly && onImageUpload && (
        <HStack mb={2} spacing={2} justify="flex-start" flexWrap="wrap">
          <Button
            size="sm"
            leftIcon={<ImageIcon size={16} />}
            colorScheme="purple"
            onClick={handleImageUpload}
          >
            Vložit obrázek
          </Button>
          <Text fontSize="xs" color="gray.500">
            nebo použijte tlačítko obrázku v nástrojové liště
          </Text>
        </HStack>
      )}

      <Box 
        position="relative"
        borderWidth="1px" 
        borderColor={borderColor}
        borderRadius="md" 
        overflow="visible"
        bg={bgColor}
        sx={{
            '.ql-toolbar': {
              borderBottom: '1px solid',
              borderColor: borderColor,
              bg: hoverBg,
              display: 'flex',
              flexWrap: 'wrap',
              gap: '4px',
              padding: '12px',
              '& button': {
                color: 'gray.700 !important',
                width: '32px !important',
                height: '32px !important',
                borderRadius: '6px',
                transition: 'all 0.2s',
                '&:hover': {
                  background: 'rgba(49, 130, 206, 0.1) !important',
                  transform: 'scale(1.05)',
                },
                '&.ql-active': {
                  background: 'rgba(49, 130, 206, 0.2) !important',
                  color: '#3182ce !important',
                },
              },
              '& .ql-stroke': {
                stroke: 'gray.700 !important',
              },
              '& .ql-fill': {
                fill: 'gray.700 !important',
              },
              '& .ql-active .ql-stroke': {
                stroke: '#3182ce !important',
              },
              '& .ql-active .ql-fill': {
                fill: '#3182ce !important',
              },
              '& .ql-picker': {
                color: 'gray.700 !important',
              },
              '& .ql-picker-label': {
                borderRadius: '6px',
                padding: '4px 8px',
                transition: 'all 0.2s',
                '&:hover': {
                  background: 'rgba(49, 130, 206, 0.1) !important',
                },
              },
              '& .ql-picker-options': {
                background: 'white',
                borderRadius: '8px',
                boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
                padding: '8px',
              },
            },
            '.ql-container': {
              fontSize: '16px',
              fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif',
              bg: 'white',
            },
            '.ql-editor': {
              minHeight: height,
              maxHeight: '70vh',
              overflowY: 'auto',
              bg: 'white !important',
              color: '#1a202c !important',
              padding: '16px',
              lineHeight: '1.6',
              '&::-webkit-scrollbar': {
                width: '8px',
              },
              '&::-webkit-scrollbar-track': {
                bg: 'gray.100',
              },
              '&::-webkit-scrollbar-thumb': {
                bg: 'gray.400',
                borderRadius: '4px',
              },
              'h1, h2, h3, h4, h5, h6': {
                color: '#1a202c !important',
              },
              'h1': {
                fontSize: '2em !important',
                fontWeight: 'bold !important',
                marginTop: '0.67em !important',
                marginBottom: '0.67em !important',
                lineHeight: '1.2 !important',
              },
              'h2': {
                fontSize: '1.5em !important',
                fontWeight: 'bold !important',
                marginTop: '0.83em !important',
                marginBottom: '0.83em !important',
                lineHeight: '1.3 !important',
              },
              'h3': {
                fontSize: '1.17em !important',
                fontWeight: 'bold !important',
                marginTop: '1em !important',
                marginBottom: '1em !important',
                lineHeight: '1.4 !important',
              },
              'p, li, span, div': {
                color: '#2d3748 !important',
              },
              'strong, b': {
                color: '#1a202c !important',
                fontWeight: 'bold !important',
              },
              'a': {
                color: '#3182ce !important',
                textDecoration: 'underline',
              },
              'blockquote': {
                borderLeft: '4px solid #3182ce',
                paddingLeft: '16px',
                margin: '1em 0',
                color: '#4a5568 !important',
                fontStyle: 'italic',
                backgroundColor: '#f7fafc',
                padding: '12px 16px',
                borderRadius: '4px',
              },
              'code': {
                backgroundColor: '#f7fafc',
                padding: '2px 6px',
                borderRadius: '3px',
                color: '#e53e3e !important',
                fontFamily: 'monospace',
              },
              'pre': {
                backgroundColor: '#2d3748',
                color: '#f7fafc !important',
                padding: '16px',
                borderRadius: '6px',
                overflow: 'auto',
              },
              'ul, ol': {
                paddingLeft: '1.5em',
                margin: '0.5em 0',
              },
              img: {
                cursor: 'pointer',
                maxWidth: '100%',
                height: 'auto',
                display: 'block',
                margin: '12px 0',
                transition: 'all 0.2s ease',
                borderRadius: '4px',
                userSelect: 'none',
                pointerEvents: 'auto',
                WebkitUserDrag: 'none',
                userDrag: 'none',
                '&:hover': {
                  opacity: 0.95,
                  transform: 'scale(1.01)',
                },
              },
            },
            '.ql-editor.ql-blank::before': {
              color: '#a0aec0 !important',
              fontStyle: 'italic',
            },
            // Prevent white and very light text colors
            '.ql-editor [style*="color: rgb(255, 255, 255)"]': {
              color: '#1a202c !important',
            },
            '.ql-editor [style*="color: white"]': {
              color: '#1a202c !important',
            },
            '.ql-editor [style*="color: #fff"]': {
              color: '#1a202c !important',
            },
            '.ql-editor [style*="color: #ffffff"]': {
              color: '#1a202c !important',
            },
            '.ql-editor [style*="color: rgb(255,255,255)"]': {
              color: '#1a202c !important',
            },
          }}
        >
          {isMounted && (
            <ReactQuill
              theme="snow"
              value={value}
              onChange={handleChange}
              readOnly={readOnly}
              placeholder={placeholder}
              ref={quillRef}
              modules={quillModules}
            />
          )}
        </Box>

      {!readOnly && (
        <Text fontSize="xs" color="gray.500" mt={2}>
          💡 <strong>Tip:</strong> Klikněte na obrázek pro výběr. Poté můžete: • Přetáhnout pro zarovnání • Změnit velikost tažením modrého bodu • Upravit filtry a transformace • Stisknout Delete pro smazání
        </Text>
      )}

      {/* Floating Image Editing Toolbar */}
      {showImageToolbar && selectedImageElement && !readOnly && (
        <Box
          ref={toolbarRef}
          position="absolute"
          top={`${toolbarPosition.top}px`}
          left={`${toolbarPosition.left}px`}
          bg={toolbarBg}
          borderWidth="2px"
          borderColor="blue.400"
          borderRadius="lg"
          boxShadow="2xl"
          p={3}
          zIndex={9999}
          minW="320px"
          maxW="380px"
          maxH="80vh"
          overflowY="auto"
          pointerEvents="auto"
          onClick={(e) => { e.stopPropagation(); }}
          onMouseDown={(e) => { e.stopPropagation(); }}
          onMouseUp={(e) => { e.stopPropagation(); }}
          css={{
            '&::-webkit-scrollbar': {
              width: '6px',
            },
            '&::-webkit-scrollbar-track': {
              background: '#f1f1f1',
            },
            '&::-webkit-scrollbar-thumb': {
              background: '#888',
              borderRadius: '3px',
            },
            '&::-webkit-scrollbar-thumb:hover': {
              background: '#555',
            },
          }}
        >
          <VStack align="stretch" spacing={3}>
            {/* Toolbar Header */}
            <HStack
              justify="space-between"
              onMouseDown={(e) => {
                if (e.button !== 0) return;
                e.preventDefault();
                e.stopPropagation();
                toolbarDragRef.current.active = true;
                toolbarDragRef.current.startX = e.clientX;
                toolbarDragRef.current.startY = e.clientY;
                toolbarDragRef.current.startLeft = toolbarPosition.left;
                toolbarDragRef.current.startTop = toolbarPosition.top;
                const onMove = (ev: MouseEvent) => {
                  if (!toolbarDragRef.current.active) return;
                  const dx = ev.clientX - toolbarDragRef.current.startX;
                  const dy = ev.clientY - toolbarDragRef.current.startY;
                  setToolbarPosition((pos) => ({ top: Math.max(0, toolbarDragRef.current.startTop + dy), left: Math.max(0, toolbarDragRef.current.startLeft + dx) }));
                };
                const onUp = () => {
                  toolbarDragRef.current.active = false;
                  document.removeEventListener('mousemove', onMove);
                  document.removeEventListener('mouseup', onUp);
                };
                document.addEventListener('mousemove', onMove);
                document.addEventListener('mouseup', onUp);
              }}
              cursor="move"
            >
              <HStack spacing={2}>
                <Settings size={16} />
                <Text fontWeight="bold" fontSize="sm">Úprava obrázku</Text>
              </HStack>
              <IconButton
                aria-label="Close"
                icon={<X size={16} />}
                size="xs"
                onClick={() => setShowImageToolbar(false)}
                variant="ghost"
              />
            </HStack>

            {/* Alignment Buttons */}
            <VStack align="stretch" spacing={2}>
              <Text fontSize="xs" fontWeight="semibold" color="gray.600">Zarovnání</Text>
              <HStack spacing={2} justify="stretch">
                <Tooltip label="Zarovnat vlevo">
                  <IconButton
                    aria-label="Align left"
                    icon={<AlignLeft size={16} />}
                    size="sm"
                    onClick={() => alignImage('left')}
                    colorScheme="teal"
                    variant="outline"
                    flex={1}
                  />
                </Tooltip>
                <Tooltip label="Zarovnat na střed">
                  <IconButton
                    aria-label="Align center"
                    icon={<AlignCenter size={16} />}
                    size="sm"
                    onClick={() => alignImage('center')}
                    colorScheme="teal"
                    variant="outline"
                    flex={1}
                  />
                </Tooltip>
                <Tooltip label="Zarovnat vpravo">
                  <IconButton
                    aria-label="Align right"
                    icon={<AlignRight size={16} />}
                    size="sm"
                    onClick={() => alignImage('right')}
                    colorScheme="teal"
                    variant="outline"
                    flex={1}
                  />
                </Tooltip>
              </HStack>
            </VStack>

            {/* Width Control */
            }
            <VStack align="stretch" spacing={2}>
              <Text fontSize="xs" fontWeight="semibold" color="gray.600">Šířka obrázku</Text>
              <HStack spacing={2}>
                <Input
                  size="sm"
                  type="number"
                  value={manualWidth}
                  onChange={(e) => setManualWidth(e.target.value)}
                  onKeyDown={(e) => { if (e.key === 'Enter') { e.stopPropagation(); applyManualWidth(); } }}
                  placeholder="Šířka v px"
                  min={50}
                />
                <Button
                  size="sm"
                  colorScheme="blue"
                  onClick={applyManualWidth}
                  minW="80px"
                >
                  Nastavit
                </Button>
              </HStack>
              <Text fontSize="xs" color="gray.500">Aktuální: {imageWidth}px ({widthPercent || 0}%)</Text>
              <HStack spacing={2}>
                <Button size="xs" variant="outline" onClick={() => applyPercent(25, { silent: true })}>25%</Button>
                <Button size="xs" variant="outline" onClick={() => applyPercent(50, { silent: true })}>50%</Button>
                <Button size="xs" variant="outline" onClick={() => applyPercent(75, { silent: true })}>75%</Button>
                <Button size="xs" variant="outline" onClick={() => applyPercent(100, { silent: true })}>100%</Button>
                <Button size="xs" colorScheme="gray" variant="ghost" onClick={resetWidth}>Reset</Button>
              </HStack>
              <FormControl>
                <HStack justify="space-between">
                  <FormLabel fontSize="xs" mb={0}>Šířka (%)</FormLabel>
                  <Text fontSize="xs" color="gray.500">{widthPercent || 0}%</Text>
                </HStack>
                <input
                  type="range"
                  min="5"
                  max="100"
                  value={widthPercent || 0}
                  onChange={(e) => applyPercent(Number(e.target.value), { silent: true })}
                  style={{ width: '100%' }}
                />
              </FormControl>
            </VStack>

            {/* Transform Buttons */}
            <VStack align="stretch" spacing={2}>
              <Text fontSize="xs" fontWeight="semibold" color="gray.600">Transformace</Text>
              <HStack spacing={2} flexWrap="wrap">
                <Tooltip label="Otočit doleva">
                  <IconButton
                    aria-label="Rotate left"
                    icon={<RotateCcw size={16} />}
                    size="sm"
                    onClick={() => updateFilter('rotation', (imageFilters.rotation - 90) % 360)}
                    colorScheme="blue"
                    variant="outline"
                  />
                </Tooltip>
                <Tooltip label="Otočit doprava">
                  <IconButton
                    aria-label="Rotate right"
                    icon={<RotateCw size={16} />}
                    size="sm"
                    onClick={() => updateFilter('rotation', (imageFilters.rotation + 90) % 360)}
                    colorScheme="blue"
                    variant="outline"
                  />
                </Tooltip>
                <Tooltip label="Převrátit horizontálně">
                  <IconButton
                    aria-label="Flip horizontal"
                    icon={<FlipHorizontal size={16} />}
                    size="sm"
                    onClick={() => updateFilter('flipH', !imageFilters.flipH)}
                    colorScheme="blue"
                    variant={imageFilters.flipH ? 'solid' : 'outline'}
                  />
                </Tooltip>
                <Tooltip label="Převrátit vertikálně">
                  <IconButton
                    aria-label="Flip vertical"
                    icon={<FlipVertical size={16} />}
                    size="sm"
                    onClick={() => updateFilter('flipV', !imageFilters.flipV)}
                    colorScheme="blue"
                    variant={imageFilters.flipV ? 'solid' : 'outline'}
                  />
                </Tooltip>
                <Tooltip label="Smazat obrázek">
                  <IconButton
                    aria-label="Delete image"
                    icon={<Trash2 size={16} />}
                    size="sm"
                    onClick={deleteSelectedImage}
                    colorScheme="red"
                    variant="outline"
                  />
                </Tooltip>
                <Tooltip label="Resetovat filtry">
                  <IconButton
                    aria-label="Reset filters"
                    icon={<RotateCcw size={16} />}
                    size="sm"
                    onClick={resetFilters}
                    colorScheme="gray"
                    variant="outline"
                  />
                </Tooltip>
              </HStack>
            </VStack>

            {/* Filter Sliders */}
            <VStack align="stretch" spacing={2}>
              <FormControl>
                <HStack justify="space-between">
                  <HStack spacing={1}>
                    <Sun size={14} />
                    <FormLabel fontSize="xs" mb={0}>Jas</FormLabel>
                  </HStack>
                  <Text fontSize="xs" color="gray.500">{imageFilters.brightness}%</Text>
                </HStack>
                <input
                  type="range"
                  min="0"
                  max="200"
                  value={imageFilters.brightness}
                  onChange={(e) => updateFilter('brightness', Number(e.target.value))}
                  style={{ width: '100%' }}
                />
              </FormControl>

              <FormControl>
                <HStack justify="space-between">
                  <HStack spacing={1}>
                    <Contrast size={14} />
                    <FormLabel fontSize="xs" mb={0}>Kontrast</FormLabel>
                  </HStack>
                  <Text fontSize="xs" color="gray.500">{imageFilters.contrast}%</Text>
                </HStack>
                <input
                  type="range"
                  min="0"
                  max="200"
                  value={imageFilters.contrast}
                  onChange={(e) => updateFilter('contrast', Number(e.target.value))}
                  style={{ width: '100%' }}
                />
              </FormControl>

              <FormControl>
                <HStack justify="space-between">
                  <HStack spacing={1}>
                    <Droplets size={14} />
                    <FormLabel fontSize="xs" mb={0}>Sytost</FormLabel>
                  </HStack>
                  <Text fontSize="xs" color="gray.500">{imageFilters.saturation}%</Text>
                </HStack>
                <input
                  type="range"
                  min="0"
                  max="200"
                  value={imageFilters.saturation}
                  onChange={(e) => updateFilter('saturation', Number(e.target.value))}
                  style={{ width: '100%' }}
                />
              </FormControl>

              <FormControl>
                <HStack justify="space-between">
                  <HStack spacing={1}>
                    <Eye size={14} />
                    <FormLabel fontSize="xs" mb={0}>Rozostření</FormLabel>
                  </HStack>
                  <Text fontSize="xs" color="gray.500">{imageFilters.blur}px</Text>
                </HStack>
                <input
                  type="range"
                  min="0"
                  max="10"
                  step="0.5"
                  value={imageFilters.blur}
                  onChange={(e) => updateFilter('blur', Number(e.target.value))}
                  style={{ width: '100%' }}
                />
              </FormControl>
            </VStack>

            {/* Quick Filters */}
            <HStack spacing={2} flexWrap="wrap">
              <Button
                size="xs"
                onClick={() => {
                  updateFilter('grayscale', imageFilters.grayscale === 100 ? 0 : 100);
                }}
                colorScheme={imageFilters.grayscale === 100 ? 'purple' : 'gray'}
                variant={imageFilters.grayscale === 100 ? 'solid' : 'outline'}
                leftIcon={<Filter size={12} />}
              >
                Černobílá
              </Button>
              <Button
                size="xs"
                onClick={() => {
                  updateFilter('sepia', imageFilters.sepia === 100 ? 0 : 100);
                }}
                colorScheme={imageFilters.sepia === 100 ? 'orange' : 'gray'}
                variant={imageFilters.sepia === 100 ? 'solid' : 'outline'}
                leftIcon={<Sparkles size={12} />}
              >
                Sepia
              </Button>
            </HStack>

            {/* Apply All Changes Button */}
            <Button
              colorScheme="green"
              size="md"
              width="full"
              onClick={applyFiltersToBackend}
              isLoading={isApplyingFilters}
              loadingText="Zpracování..."
              leftIcon={<Check size={16} />}
            >
              Aplikovat všechny změny
            </Button>
            <Text fontSize="xs" color="gray.500" textAlign="center">
              💡 Filtry jsou pouze náhled. Klikněte pro trvalou aplikaci.
            </Text>
          </VStack>
        </Box>
      )}

      {/* Crop Modal */}
      {/* Image Preview Modal */}
      <Modal isOpen={isPreviewOpen} onClose={() => setIsPreviewOpen(false)} size="6xl" isCentered>
        <ModalOverlay bg="blackAlpha.800" backdropFilter="blur(4px)" />
        <ModalContent maxW="90vw" maxH="90vh" bg="transparent" boxShadow="none">
          <ModalCloseButton color="white" bg="blackAlpha.600" _hover={{ bg: 'blackAlpha.700' }} />
          <ModalBody display="flex" alignItems="center" justifyContent="center" p={0}>
            {previewImage && (
              <ChakraImage
                src={previewImage}
                alt="Preview"
                maxW="100%"
                maxH="90vh"
                objectFit="contain"
                borderRadius="md"
                boxShadow="2xl"
              />
            )}
          </ModalBody>
        </ModalContent>
      </Modal>

      {/* Crop Modal */}
      <Modal isOpen={cropOpen} onClose={() => { setCropOpen(false); setCropSrc(null); }} size="6xl">
        <ModalOverlay bg="blackAlpha.700" backdropFilter="blur(4px)" />
        <ModalContent maxW="90vw" maxH="90vh">
          <ModalHeader>Oříznout a upravit obrázek</ModalHeader>
          <ModalCloseButton />
          <ModalBody maxH="calc(90vh - 140px)" overflowY="auto" overflowX="hidden">
            <VStack align="stretch" spacing={4}>
              {cropSrc && (
                <Box 
                  display="flex" 
                  justifyContent="center" 
                  alignItems="center" 
                  p={4}
                  bg="gray.50"
                  borderRadius="md"
                >
                  <ReactCrop 
                    crop={crop} 
                    onChange={(c: Crop) => setCrop(c)}
                    minWidth={50}
                    minHeight={50}
                    keepSelection
                  >
                    <img 
                      ref={imgRef as any} 
                      src={cropSrc || ''} 
                      alt="Crop preview" 
                      style={{ 
                        maxWidth: '100%', 
                        maxHeight: '60vh',
                        display: 'block',
                        margin: 'auto'
                      }} 
                    />
                  </ReactCrop>
                </Box>
              )}
              
              <SimpleGrid columns={{ base: 1, md: 2 }} spacing={4}>
                <FormControl>
                  <FormLabel fontSize="sm">Max. šířka (px)</FormLabel>
                  <HStack>
                    <Input 
                      type="number" 
                      value={cropMaxWidth} 
                      onChange={(e) => setCropMaxWidth(Math.max(100, Math.min(3000, Number(e.target.value))))}
                      min={100}
                      max={3000}
                      step={100}
                      size="sm"
                    />
                    <Text fontSize="sm" color="gray.600" whiteSpace="nowrap">px</Text>
                  </HStack>
                  <FormHelperText fontSize="xs">
                    Větší obrázky budou zmenšeny (optimalizace výkonu)
                  </FormHelperText>
                </FormControl>
                
                <FormControl>
                  <FormLabel fontSize="sm">Kvalita JPEG</FormLabel>
                  <HStack>
                    <Input 
                      type="number" 
                      value={cropQuality} 
                      onChange={(e) => setCropQuality(Math.max(1, Math.min(100, Number(e.target.value))))}
                      min={1}
                      max={100}
                      step={5}
                      size="sm"
                    />
                    <Text fontSize="sm" color="gray.600" whiteSpace="nowrap">%</Text>
                  </HStack>
                  <FormHelperText fontSize="xs">
                    85% je doporučená hodnota (menší velikost souboru)
                  </FormHelperText>
                </FormControl>
              </SimpleGrid>
              
              <Text fontSize="sm" color="gray.600">
                💡 Přetáhněte rohy a hrany modré oblasti pro výběr části obrázku k oříznutí.
              </Text>
            </VStack>
          </ModalBody>
          <ModalFooter>
            <Button variant="ghost" mr={3} onClick={() => { setCropOpen(false); setCropSrc(null); setCropFile(null); }} isDisabled={cropProcessing}>
              Zrušit
            </Button>
            <Button colorScheme="blue" onClick={confirmCropAndInsert} isLoading={cropProcessing} loadingText="Zpracování...">
              Oříznout a vložit
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </Box>
  );
};

export default CustomRichEditor;
