'use client';

import React, { useState, useCallback, useMemo } from 'react';
import {
  createEditor,
  Descendant,
  Element as SlateElement,
  Transforms,
  Editor,
  Range
} from 'slate';
import {
  Slate,
  Editable,
  withReact,
  ReactEditor,
  RenderElementProps,
  RenderLeafProps,
  useSlate as useEditor
} from 'slate-react';
import { withHistory } from 'slate-history';
import Button from '../ui/Button';
import { sanitizeHtmlSync } from '../../lib/sanitization';
import { debug } from '../../lib/debug';

interface SlateEditorProps {
  value: string; // HTML value for compatibility with existing code
  onChange: (value: string) => void; // Returns HTML for compatibility
  placeholder?: string;
  error?: string;
  storyId?: string;
  enableImageProcessing?: boolean;
}

// Custom types for our editor
type CustomElement = {
  type: 'paragraph' | 'heading-one' | 'heading-two' | 'heading-three' | 'image';
  children: CustomText[];
  src?: string; // for images
  alt?: string; // for images
  caption?: string; // for images
};

type CustomText = {
  text: string;
  bold?: boolean;
  italic?: boolean;
  underline?: boolean;
  strikethrough?: boolean;
};

declare module 'slate' {
  interface CustomTypes {
    Editor: ReactEditor;
    Element: CustomElement;
    Text: CustomText;
  }
}

// HTML to Slate conversion - preserves mixed content order
const htmlToSlate = (html: string): Descendant[] => {
  if (!html || html.trim() === '') {
    return [{ type: 'paragraph', children: [{ text: '' }] }];
  }

  const sanitizedHtml = sanitizeHtmlSync(html);
  const parser = new DOMParser();
  const doc = parser.parseFromString(sanitizedHtml, 'text/html');

  const nodes: Descendant[] = [];

  // Parse inline-formatted children of a block element into CustomText leaves,
  // preserving bold/italic/underline/strikethrough marks.
  const parseInlineChildren = (element: Element): CustomText[] => {
    const children: CustomText[] = [];

    const processNode = (node: Node, marks: Partial<CustomText> = {}) => {
      if (node.nodeType === Node.TEXT_NODE) {
        const text = node.textContent || '';
        if (text) {
          children.push({ text, ...marks });
        }
      } else if (node.nodeType === Node.ELEMENT_NODE) {
        const el = node as Element;
        const newMarks = { ...marks };
        const tag = el.tagName.toLowerCase();
        if (tag === 'strong' || tag === 'b') newMarks.bold = true;
        if (tag === 'em' || tag === 'i') newMarks.italic = true;
        if (tag === 'u') newMarks.underline = true;
        if (tag === 's' || tag === 'del' || tag === 'strike') newMarks.strikethrough = true;

        // Also detect bold/italic from inline CSS styles (e.g. pasted web content)
        const style = el.getAttribute('style');
        if (style) {
          const fwMatch = style.match(/font-weight\s*:\s*([^;]+)/i);
          if (fwMatch) {
            const fw = fwMatch[1].trim().toLowerCase();
            if (fw === 'bold' || fw === 'bolder' || Number(fw) >= 600) {
              newMarks.bold = true;
            }
          }
          const fsMatch = style.match(/font-style\s*:\s*([^;]+)/i);
          if (fsMatch) {
            const fs = fsMatch[1].trim().toLowerCase();
            if (fs === 'italic' || fs === 'oblique') {
              newMarks.italic = true;
            }
          }
        }

        el.childNodes.forEach(child => processNode(child, newMarks));
      }
    };

    element.childNodes.forEach(child => processNode(child));
    return children.length > 0 ? children : [{ text: '' }];
  };

  // Process all nodes in document order to maintain sequence
  const processChildNodes = (parentNode: Node): Descendant[] => {
    const results: Descendant[] = [];

    Array.from(parentNode.childNodes).forEach(node => {
      if (node.nodeType === Node.ELEMENT_NODE) {
        const element = node as Element;

        switch (element.tagName.toLowerCase()) {
          case 'h1':
            results.push({
              type: 'heading-one',
              children: parseInlineChildren(element)
            });
            break;
          case 'h2':
            results.push({
              type: 'heading-two',
              children: parseInlineChildren(element)
            });
            break;
          case 'h3':
            results.push({
              type: 'heading-three',
              children: parseInlineChildren(element)
            });
            break;
          case 'blockquote':
          case 'pre':
          case 'code': {
            // Filter out blockquotes, code blocks, and code - convert to paragraph
            const text = element.textContent || '';
            if (text.trim()) {
              results.push({
                type: 'paragraph',
                children: [{ text: text.trim() }]
              });
            }
            break;
          }
          case 'img': {
            const img = element as HTMLImageElement;
            results.push({
              type: 'image',
              // Use getAttribute to preserve relative URLs instead of .src which converts to absolute
              src: img.getAttribute('src') || '',
              alt: img.getAttribute('alt') || '',
              caption: img.getAttribute('title') || '',
              children: [{ text: '' }] // Images need children in Slate
            });
            break;
          }
          case 'p': {
            // Check if this paragraph contains mixed content (text + images)
            if (element.querySelector('img')) {
              // Process mixed content - handle both text and images in order
              results.push(...processChildNodes(element));
            } else {
              const inlineChildren = parseInlineChildren(element);
              if (inlineChildren.some(c => c.text.trim())) {
                results.push({ type: 'paragraph', children: inlineChildren });
              }
            }
            break;
          }
          case 'div': {
            // Always recurse into divs: they may wrap headings or other block elements.
            // Using textContent here would flatten everything into a single paragraph
            // and silently drop any headings nested inside.
            results.push(...processChildNodes(element));
            break;
          }
          case 'br':
            // Handle line breaks by creating empty paragraphs
            results.push({
              type: 'paragraph',
              children: [{ text: '' }]
            });
            break;
          default: {
            // For other elements, try to extract text or recurse
            const text = element.textContent || '';
            if (text.trim()) {
              results.push({
                type: 'paragraph',
                children: [{ text }]
              });
            }
            break;
          }
        }
      } else if (node.nodeType === Node.TEXT_NODE) {
        const text = node.textContent || '';
        if (text.trim()) {
          results.push({
            type: 'paragraph',
            children: [{ text: text.trim() }]
          });
        }
      }
    });

    return results;
  };

  // Process all content
  nodes.push(...processChildNodes(doc.body));

  // Fallback for simple text content
  if (nodes.length === 0 && doc.body.textContent?.trim()) {
    const text = doc.body.textContent.trim();
    const lines = text.split('\n').filter(line => line.trim());
    lines.forEach(line => {
      nodes.push({
        type: 'paragraph',
        children: [{ text: line.trim() }]
      });
    });
  }

  return nodes.length > 0 ? nodes : [{ type: 'paragraph', children: [{ text: '' }] }];
};

// Slate to HTML conversion
const slateToHtml = (nodes: Descendant[]): string => {
  const htmlParts: string[] = [];

  // Serialize a single leaf with its inline marks applied as HTML tags.
  // Text content is escaped so literal <, >, & don't break the markup.
  const serializeLeaf = (leaf: CustomText): string => {
    let text = leaf.text
      .replace(/&/g, '&amp;')
      .replace(/</g, '&lt;')
      .replace(/>/g, '&gt;');
    if (leaf.bold) text = `<strong>${text}</strong>`;
    if (leaf.italic) text = `<em>${text}</em>`;
    if (leaf.underline) text = `<u>${text}</u>`;
    if (leaf.strikethrough) text = `<s>${text}</s>`;
    return text;
  };

  nodes.forEach(node => {
    if (SlateElement.isElement(node)) {
      const element = node as CustomElement;

      switch (element.type) {
        case 'heading-one': {
          const inner = element.children.map(serializeLeaf).join('');
          htmlParts.push(`<h1>${inner}</h1>`);
          break;
        }
        case 'heading-two': {
          const inner = element.children.map(serializeLeaf).join('');
          htmlParts.push(`<h2>${inner}</h2>`);
          break;
        }
        case 'heading-three': {
          const inner = element.children.map(serializeLeaf).join('');
          htmlParts.push(`<h3>${inner}</h3>`);
          break;
        }
        case 'image': {
          const attrs: string[] = [];
          if (element.src) attrs.push(`src="${element.src}"`);
          if (element.alt) attrs.push(`alt="${element.alt}"`);
          if (element.caption) attrs.push(`title="${element.caption}"`);
          htmlParts.push(`<img ${attrs.join(' ')} />`);
          break;
        }
        case 'paragraph':
        default: {
          const inner = element.children.map(serializeLeaf).join('');
          htmlParts.push(inner ? `<p>${inner}</p>` : '<p></p>');
          break;
        }
      }
    }
  });

  const html = htmlParts.join('\n');
  return sanitizeHtmlSync(html);
};

// Custom plugin to handle images
const withImages = (editor: ReactEditor) => {
  const { insertData, isVoid } = editor;

  editor.isVoid = element => {
    return element.type === 'image' ? true : isVoid(element);
  };

  editor.insertData = (data) => {
    const html = data.getData('text/html');

    if (html) {
      debug.log('📋 HTML paste detected in Slate editor');

      const slateNodes = htmlToSlate(html);

      slateNodes.forEach(node => {
        Transforms.insertNodes(editor, node);
      });

      debug.log(`📋 Inserted ${slateNodes.length} nodes from pasted HTML`);
      return;
    }

    insertData(data);
  };

  return editor;
};

// Interactive Image Component
const ImageElement = ({ attributes, element, children }: {
  attributes: any;
  element: CustomElement;
  children: React.ReactNode;
}) => {
  const editor = useEditor();
  const [isEditing, setIsEditing] = useState(false);
  const [editUrl, setEditUrl] = useState(element.src || '');
  const [editAlt, setEditAlt] = useState(element.alt || '');
  const [editCaption, setEditCaption] = useState(element.caption || '');

  const handleDelete = () => {
    const path = ReactEditor.findPath(editor, element);
    Transforms.removeNodes(editor, { at: path });
  };

  const handleSave = () => {
    const path = ReactEditor.findPath(editor, element);
    const newProperties: Partial<CustomElement> = {
      src: editUrl,
      alt: editAlt,
      caption: editCaption,
    };
    Transforms.setNodes(editor, newProperties, { at: path });
    setIsEditing(false);
  };

  const handleCancel = () => {
    setEditUrl(element.src || '');
    setEditAlt(element.alt || '');
    setEditCaption(element.caption || '');
    setIsEditing(false);
  };

  if (isEditing) {
    return (
      <div {...attributes} contentEditable={false} className="my-4">
        <div className="border border-blue-300 rounded-lg p-4 bg-blue-50">
          <h4 className="font-medium text-blue-900 mb-3">Edit Image</h4>
          <div className="space-y-3">
            <div>
              <label className="block text-sm font-medium text-blue-800 mb-1">
                Image URL *
              </label>
              <input
                type="url"
                value={editUrl}
                onChange={(e) => setEditUrl(e.target.value)}
                className="w-full px-3 py-2 border border-blue-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="https://example.com/image.jpg"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-blue-800 mb-1">
                Alt Text
              </label>
              <input
                type="text"
                value={editAlt}
                onChange={(e) => setEditAlt(e.target.value)}
                className="w-full px-3 py-2 border border-blue-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="Describe the image"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-blue-800 mb-1">
                Caption
              </label>
              <input
                type="text"
                value={editCaption}
                onChange={(e) => setEditCaption(e.target.value)}
                className="w-full px-3 py-2 border border-blue-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder="Image caption"
              />
            </div>
          </div>
          <div className="flex gap-2 mt-4">
            <button
              onClick={handleSave}
              className="px-3 py-1 bg-blue-600 text-white text-sm rounded hover:bg-blue-700 focus:ring-2 focus:ring-blue-500"
            >
              Save
            </button>
            <button
              onClick={handleCancel}
              className="px-3 py-1 bg-gray-300 text-gray-700 text-sm rounded hover:bg-gray-400 focus:ring-2 focus:ring-gray-500"
            >
              Cancel
            </button>
          </div>
        </div>
        {children}
      </div>
    );
  }

  return (
    <div {...attributes} contentEditable={false} className="my-4">
      <div
        className="relative border border-gray-200 rounded-lg overflow-hidden bg-white shadow-sm group hover:shadow-md transition-shadow focus-within:ring-2 focus-within:ring-blue-500 focus-within:border-blue-500"
        tabIndex={0}
        onKeyDown={(event) => {
          // Handle delete/backspace on focused image
          if (event.key === 'Delete' || event.key === 'Backspace') {
            event.preventDefault();
            handleDelete();
          }
          // Handle Enter to edit
          if (event.key === 'Enter') {
            event.preventDefault();
            setIsEditing(true);
          }
        }}
        onClick={() => {
          // Focus the image element when clicked
          const path = ReactEditor.findPath(editor, element);
          const start = Editor.start(editor, path);
          Transforms.select(editor, start);
        }}
      >
        {/* Control buttons - show on hover */}
        <div className="absolute top-2 left-2 opacity-0 group-hover:opacity-100 transition-opacity z-10">
          <div className="flex gap-1">
            <button
              onClick={() => setIsEditing(true)}
              className="p-1 bg-white rounded-full shadow-sm hover:bg-blue-50 border border-gray-200 text-blue-600 hover:text-blue-700"
              title="Edit image"
            >
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
              </svg>
            </button>
            <button
              onClick={handleDelete}
              className="p-1 bg-white rounded-full shadow-sm hover:bg-red-50 border border-gray-200 text-red-600 hover:text-red-700"
              title="Delete image"
            >
              <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
              </svg>
            </button>
          </div>
        </div>

        {element.src ? (
          <>
            <img
              src={element.src}
              alt={element.alt || ''}
              className="w-full h-auto max-h-96 object-contain cursor-pointer"
              onDoubleClick={() => setIsEditing(true)}
              onError={(e) => {
                // Fallback to text block if image fails to load
                const target = e.target as HTMLImageElement;
                const parent = target.parentElement;
                if (parent) {
                  parent.innerHTML = `
                    <div class="p-3 border border-dashed border-red-300 rounded-lg bg-red-50">
                      <div class="flex items-center gap-2 mb-2">
                        <span class="text-lg">⚠️</span>
                        <span class="font-medium text-red-700">Image failed to load</span>
                      </div>
                      <div class="text-sm text-red-600 space-y-1">
                        <p><strong>Source:</strong> ${element.src}</p>
                        ${element.alt ? `<p><strong>Alt:</strong> ${element.alt}</p>` : ''}
                        ${element.caption ? `<p><strong>Caption:</strong> ${element.caption}</p>` : ''}
                      </div>
                    </div>
                  `;
                }
              }}
            />
            {(element.alt || element.caption) && (
              <div className="p-2 bg-gray-50 border-t border-gray-200">
                <div className="text-sm text-gray-600">
                  {element.caption && (
                    <p className="font-medium">{element.caption}</p>
                  )}
                  {element.alt && element.alt !== element.caption && (
                    <p className="italic">{element.alt}</p>
                  )}
                </div>
              </div>
            )}

            {/* External image indicator */}
            {element.src.startsWith('http') && (
              <div className="absolute top-2 right-2">
                <div className="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full flex items-center gap-1">
                  <span>🌐</span>
                  <span>External</span>
                </div>
              </div>
            )}
          </>
        ) : (
          <div className="p-3 border border-dashed border-gray-300 rounded-lg bg-gray-50">
            <div className="flex items-center gap-2 mb-2">
              <span className="text-lg">🖼️</span>
              <span className="font-medium text-gray-700">Image (No Source)</span>
            </div>
            <div className="text-sm text-gray-600 space-y-1">
              {element.alt && <p><strong>Alt:</strong> {element.alt}</p>}
              {element.caption && <p><strong>Caption:</strong> {element.caption}</p>}
            </div>
          </div>
        )}
      </div>
      {children}
    </div>
  );
};

// Component for rendering elements
const Element = ({ attributes, children, element }: RenderElementProps) => {
  const customElement = element as CustomElement;

  switch (customElement.type) {
    case 'heading-one':
      return <h1 {...attributes} className="text-3xl font-bold mb-4">{children}</h1>;
    case 'heading-two':
      return <h2 {...attributes} className="text-2xl font-bold mb-3">{children}</h2>;
    case 'heading-three':
      return <h3 {...attributes} className="text-xl font-bold mb-3">{children}</h3>;
    case 'image':
      return (
        <ImageElement
          attributes={attributes}
          element={customElement}
          children={children}
        />
      );
    default:
      return <p {...attributes} className="mb-2">{children}</p>;
  }
};

// Component for rendering leaves (text formatting)
const Leaf = ({ attributes, children, leaf }: RenderLeafProps) => {
  const customLeaf = leaf as CustomText;

  if (customLeaf.bold) {
    children = <strong>{children}</strong>;
  }

  if (customLeaf.italic) {
    children = <em>{children}</em>;
  }

  if (customLeaf.underline) {
    children = <u>{children}</u>;
  }

  if (customLeaf.strikethrough) {
    children = <s>{children}</s>;
  }

  return <span {...attributes}>{children}</span>;
};

// Toolbar component
const Toolbar = ({ editor }: { editor: ReactEditor }) => {
  type MarkFormat = 'bold' | 'italic' | 'underline' | 'strikethrough';

  const isMarkActive = (format: MarkFormat) => {
    const marks = Editor.marks(editor);
    return marks ? marks[format] === true : false;
  };

  const toggleMark = (format: MarkFormat) => {
    const isActive = isMarkActive(format);
    if (isActive) {
      Editor.removeMark(editor, format);
    } else {
      Editor.addMark(editor, format, true);
    }
  };

  const isBlockActive = (format: CustomElement['type']) => {
    const { selection } = editor;
    if (!selection) return false;

    const [match] = Array.from(
      Editor.nodes(editor, {
        at: Editor.unhangRange(editor, selection),
        match: n =>
          !Editor.isEditor(n) &&
          SlateElement.isElement(n) &&
          n.type === format,
      })
    );

    return !!match;
  };

  const toggleBlock = (format: CustomElement['type']) => {
    const isActive = isBlockActive(format);

    Transforms.setNodes(
      editor,
      { type: isActive ? 'paragraph' : format },
      { match: n => SlateElement.isElement(n) && Editor.isBlock(editor, n) }
    );
  };

  const insertImage = () => {
    const url = prompt('Enter image URL:', 'https://');
    if (url && url.trim() !== 'https://') {
      const imageNode: CustomElement = {
        type: 'image',
        src: url.trim(),
        alt: '',
        caption: '',
        children: [{ text: '' }],
      };

      Transforms.insertNodes(editor, imageNode);
      // Add a paragraph after the image
      Transforms.insertNodes(editor, {
        type: 'paragraph',
        children: [{ text: '' }],
      });
    }
  };

  return (
    <div className="flex items-center gap-2 p-2 theme-card border theme-border rounded-t-lg">
      <div className="text-xs bg-green-100 text-green-800 px-2 py-1 rounded">
        ✨ Slate.js Editor
      </div>

      {/* Block type buttons */}
      <div className="flex items-center gap-1 border-r pr-2 mr-2">
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleBlock('paragraph')}
          className={isBlockActive('paragraph') ? 'theme-accent-bg text-white' : ''}
          title="Normal paragraph (Ctrl+Shift+0)"
        >
          P
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleBlock('heading-one')}
          className={`text-lg font-bold ${isBlockActive('heading-one') ? 'theme-accent-bg text-white' : ''}`}
          title="Heading 1 (Ctrl+Shift+1)"
        >
          H1
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleBlock('heading-two')}
          className={`text-base font-bold ${isBlockActive('heading-two') ? 'theme-accent-bg text-white' : ''}`}
          title="Heading 2 (Ctrl+Shift+2)"
        >
          H2
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleBlock('heading-three')}
          className={`text-sm font-bold ${isBlockActive('heading-three') ? 'theme-accent-bg text-white' : ''}`}
          title="Heading 3 (Ctrl+Shift+3)"
        >
          H3
        </Button>
      </div>

      {/* Text formatting buttons */}
      <div className="flex items-center gap-1">
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleMark('bold')}
          className={`font-bold ${isMarkActive('bold') ? 'theme-accent-bg text-white' : ''}`}
          title="Bold (Ctrl+B)"
        >
          B
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleMark('italic')}
          className={`italic ${isMarkActive('italic') ? 'theme-accent-bg text-white' : ''}`}
          title="Italic (Ctrl+I)"
        >
          I
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleMark('underline')}
          className={`underline ${isMarkActive('underline') ? 'theme-accent-bg text-white' : ''}`}
          title="Underline (Ctrl+U)"
        >
          U
        </Button>
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={() => toggleMark('strikethrough')}
          className={`line-through ${isMarkActive('strikethrough') ? 'theme-accent-bg text-white' : ''}`}
          title="Strikethrough (Ctrl+D)"
        >
          S
        </Button>
      </div>

      {/* Image insertion button */}
      <div className="flex items-center gap-1 border-l pl-2 ml-2">
        <Button
          type="button"
          size="sm"
          variant="ghost"
          onClick={insertImage}
          className="text-green-600 hover:bg-green-50"
          title="Insert Image"
        >
          🖼️
        </Button>
      </div>
    </div>
  );
};

export default function SlateEditor({
  value,
  onChange,
  placeholder = 'Write your story here...',
  error,
  storyId,
  enableImageProcessing = false
}: SlateEditorProps) {
  const [isScrollable, setIsScrollable] = useState(true);

  // Create editor with plugins
  const editor = useMemo(
    () => withImages(withHistory(withReact(createEditor()))),
    []
  );

  // Convert HTML to Slate format for initial value
  const initialValue = useMemo(() => {
    debug.log('🚀 Slate Editor initializing with HTML:', { htmlLength: value?.length });
    return htmlToSlate(value);
  }, [value]);

  // Handle changes
  const handleChange = useCallback((newValue: Descendant[]) => {
    // Convert back to HTML and call onChange
    const html = slateToHtml(newValue);
    onChange(html);

    debug.log('📝 Slate Editor changed:', {
      htmlLength: html.length,
      nodeCount: newValue.length
    });
  }, [onChange]);

  debug.log('🎯 Slate Editor loaded!', {
    valueLength: value?.length,
    enableImageProcessing,
    hasStoryId: !!storyId
  });

  return (
    <div className="space-y-2">
      <Slate editor={editor} initialValue={initialValue} onChange={handleChange}>
        <Toolbar editor={editor} />
        <div className="border theme-border rounded-b-lg overflow-hidden">
          <Editable
            className={`p-3 focus:outline-none focus:ring-0 resize-none ${
              isScrollable
                ? 'h-[400px] overflow-y-auto'
                : 'min-h-[300px]'
            }`}
            placeholder={placeholder}
            renderElement={Element}
            renderLeaf={Leaf}
            onKeyDown={(event) => {
              // Handle delete/backspace for selected content (including images)
              if (event.key === 'Delete' || event.key === 'Backspace') {
                const { selection } = editor;
                if (!selection) return;

                // If there's an expanded selection, let Slate handle it naturally
                // This will delete all selected content including images
                if (!Range.isCollapsed(selection)) {
                  // Slate will handle this automatically, including void elements
                  return;
                }

                // Handle single point deletions near images
                const { anchor } = selection;

                if (event.key === 'Delete') {
                  // Delete key - check if next node is an image
                  try {
                    const [nextNode] = Editor.next(editor, { at: anchor }) || [];
                    if (nextNode && SlateElement.isElement(nextNode) && nextNode.type === 'image') {
                      event.preventDefault();
                      const path = ReactEditor.findPath(editor, nextNode);
                      Transforms.removeNodes(editor, { at: path });
                      return;
                    }
                  } catch (error) {
                    // Ignore navigation errors at document boundaries
                  }
                } else if (event.key === 'Backspace') {
                  // Backspace key - check if previous node is an image
                  try {
                    const [prevNode] = Editor.previous(editor, { at: anchor }) || [];
                    if (prevNode && SlateElement.isElement(prevNode) && prevNode.type === 'image') {
                      event.preventDefault();
                      const path = ReactEditor.findPath(editor, prevNode);
                      Transforms.removeNodes(editor, { at: path });
                      return;
                    }
                  } catch (error) {
                    // Ignore navigation errors at document boundaries
                  }
                }
              }

              // Handle keyboard shortcuts
              if (!event.ctrlKey && !event.metaKey) return;

              // Helper function to toggle marks
              const toggleMarkShortcut = (format: 'bold' | 'italic' | 'underline' | 'strikethrough') => {
                event.preventDefault();
                const marks = Editor.marks(editor);
                const isActive = marks ? marks[format] === true : false;
                if (isActive) {
                  Editor.removeMark(editor, format);
                } else {
                  Editor.addMark(editor, format, true);
                }
              };

              // Helper function to toggle blocks
              const toggleBlockShortcut = (format: CustomElement['type']) => {
                event.preventDefault();
                const isActive = isBlockActive(format);
                Transforms.setNodes(
                  editor,
                  { type: isActive ? 'paragraph' : format },
                  { match: n => SlateElement.isElement(n) && Editor.isBlock(editor, n) }
                );
              };

              // Check if block is active
              const isBlockActive = (format: CustomElement['type']) => {
                const { selection } = editor;
                if (!selection) return false;
                const [match] = Array.from(
                  Editor.nodes(editor, {
                    at: Editor.unhangRange(editor, selection),
                    match: n => !Editor.isEditor(n) && SlateElement.isElement(n) && n.type === format,
                  })
                );
                return !!match;
              };

              switch (event.key) {
                // Text formatting shortcuts
                case 'b':
                  toggleMarkShortcut('bold');
                  break;
                case 'i':
                  toggleMarkShortcut('italic');
                  break;
                case 'u':
                  toggleMarkShortcut('underline');
                  break;
                case 'd':
                  // Ctrl+D for strikethrough
                  toggleMarkShortcut('strikethrough');
                  break;

                // Block formatting shortcuts
                case '1':
                  if (event.shiftKey) {
                    // Ctrl+Shift+1 for H1
                    toggleBlockShortcut('heading-one');
                  }
                  break;
                case '2':
                  if (event.shiftKey) {
                    // Ctrl+Shift+2 for H2
                    toggleBlockShortcut('heading-two');
                  }
                  break;
                case '3':
                  if (event.shiftKey) {
                    // Ctrl+Shift+3 for H3
                    toggleBlockShortcut('heading-three');
                  }
                  break;
                case '0':
                  if (event.shiftKey) {
                    // Ctrl+Shift+0 for normal paragraph
                    toggleBlockShortcut('paragraph');
                  }
                  break;

                // Select all
                case 'a':
                  event.preventDefault();
                  Transforms.select(editor, {
                    anchor: Editor.start(editor, []),
                    focus: Editor.end(editor, []),
                  });
                  break;
              }
            }}
          />
        </div>

        <div className="flex justify-between items-center">
          <div className="text-xs theme-text space-y-1">
            <p>
              <strong>Slate.js Editor:</strong> Rich text editor with advanced image paste handling.
              {isScrollable ? ' Fixed height with scrolling.' : ' Auto-expanding height.'}
            </p>
            <details className="text-xs">
              <summary className="cursor-pointer hover:theme-accent-text font-medium">⌨️ Keyboard Shortcuts</summary>
              <div className="mt-2 grid grid-cols-2 gap-x-4 gap-y-1 p-2 theme-card border theme-border rounded">
                <div>
                  <p className="font-semibold mb-1">Text Formatting:</p>
                  <ul className="space-y-0.5">
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+B</kbd> Bold</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+I</kbd> Italic</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+U</kbd> Underline</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+D</kbd> Strikethrough</li>
                  </ul>
                </div>
                <div>
                  <p className="font-semibold mb-1">Block Formatting:</p>
                  <ul className="space-y-0.5">
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+Shift+0</kbd> Paragraph</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+Shift+1</kbd> Heading 1</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+Shift+2</kbd> Heading 2</li>
                    <li><kbd className="px-1 py-0.5 bg-gray-200 dark:bg-gray-700 rounded text-xs">Ctrl+Shift+3</kbd> Heading 3</li>
                  </ul>
                </div>
              </div>
            </details>
          </div>

          <Button
            type="button"
            size="sm"
            variant="ghost"
            onClick={() => setIsScrollable(!isScrollable)}
            className={isScrollable ? 'theme-accent-bg text-white' : ''}
            title={isScrollable ? 'Switch to auto-expand mode' : 'Switch to scrollable mode'}
          >
            {isScrollable ? '📜' : '📏'}
          </Button>
        </div>
      </Slate>

      {error && (
        <p className="text-sm text-red-600 dark:text-red-400">{error}</p>
      )}
    </div>
  );
}