import { BaseBlockHandler, type IBlockEventHandlers } from '../block.base.js';
import type { IBlock } from '../../wysiwyg.types.js';
import { cssManager } from '@design.estate/dees-element';

/**
 * MarkdownBlockHandler - Handles markdown content with preview/edit toggle
 * 
 * Features:
 * - Live markdown preview
 * - Edit/preview mode toggle
 * - Syntax highlighting in edit mode
 * - Common markdown shortcuts
 * - Auto-save on mode switch
 */
export class MarkdownBlockHandler extends BaseBlockHandler {
  type = 'markdown';
  
  render(block: IBlock, isSelected: boolean): string {
    const isEditMode = block.metadata?.isEditMode ?? true;
    const content = block.content || '';
    
    return `
      <div class="markdown-block-container${isSelected ? ' selected' : ''}" 
           data-block-id="${block.id}"
           data-edit-mode="${isEditMode}">
        <div class="markdown-header">
          <div class="markdown-icon">M↓</div>
          <div class="markdown-title">Markdown</div>
          <button class="markdown-toggle-mode" title="${isEditMode ? 'Preview' : 'Edit'}">
            ${isEditMode ? '👁️' : '✏️'}
          </button>
        </div>
        <div class="markdown-content">
          ${isEditMode ? this.renderEditor(content) : this.renderPreview(content)}
        </div>
      </div>
    `;
  }
  
  private renderEditor(content: string): string {
    return `
      <textarea class="markdown-editor" 
                placeholder="Enter markdown content..."
                spellcheck="false">${this.escapeHtml(content)}</textarea>
    `;
  }
  
  private renderPreview(content: string): string {
    const html = this.parseMarkdown(content);
    return `
      <div class="markdown-preview">
        ${html || '<div class="preview-empty">No content to preview</div>'}
      </div>
    `;
  }
  
  setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
    const container = element.querySelector('.markdown-block-container') as HTMLElement;
    const toggleBtn = element.querySelector('.markdown-toggle-mode') as HTMLButtonElement;
    
    if (!container || !toggleBtn) {
      console.error('MarkdownBlockHandler: Could not find required elements');
      return;
    }
    
    // Initialize metadata
    if (!block.metadata) block.metadata = {};
    if (block.metadata.isEditMode === undefined) block.metadata.isEditMode = true;
    
    // Toggle mode button
    toggleBtn.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
      
      // Save current content if in edit mode
      if (block.metadata.isEditMode) {
        const editor = container.querySelector('.markdown-editor') as HTMLTextAreaElement;
        if (editor) {
          block.content = editor.value;
        }
      }
      
      // Toggle mode
      block.metadata.isEditMode = !block.metadata.isEditMode;
      
      // Request UI update
      handlers.onRequestUpdate?.();
    });
    
    // Setup based on mode
    if (block.metadata.isEditMode) {
      this.setupEditor(element, block, handlers);
    } else {
      this.setupPreview(element, block, handlers);
    }
  }
  
  private setupEditor(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (!editor) return;
    
    // Focus handling
    editor.addEventListener('focus', () => handlers.onFocus());
    editor.addEventListener('blur', () => handlers.onBlur());
    
    // Content changes
    editor.addEventListener('input', () => {
      block.content = editor.value;
    });
    
    // Keyboard shortcuts
    editor.addEventListener('keydown', (e) => {
      // Tab handling for indentation
      if (e.key === 'Tab') {
        e.preventDefault();
        const start = editor.selectionStart;
        const end = editor.selectionEnd;
        const value = editor.value;
        
        if (e.shiftKey) {
          // Unindent
          const beforeCursor = value.substring(0, start);
          const lastNewline = beforeCursor.lastIndexOf('\n');
          const lineStart = lastNewline + 1;
          const lineContent = value.substring(lineStart, start);
          
          if (lineContent.startsWith('  ')) {
            editor.value = value.substring(0, lineStart) + lineContent.substring(2) + value.substring(start);
            editor.selectionStart = editor.selectionEnd = start - 2;
          }
        } else {
          // Indent
          editor.value = value.substring(0, start) + '  ' + value.substring(end);
          editor.selectionStart = editor.selectionEnd = start + 2;
        }
        
        block.content = editor.value;
        return;
      }
      
      // Bold shortcut (Ctrl/Cmd + B)
      if ((e.ctrlKey || e.metaKey) && e.key === 'b') {
        e.preventDefault();
        this.wrapSelection(editor, '**', '**');
        block.content = editor.value;
        return;
      }
      
      // Italic shortcut (Ctrl/Cmd + I)
      if ((e.ctrlKey || e.metaKey) && e.key === 'i') {
        e.preventDefault();
        this.wrapSelection(editor, '_', '_');
        block.content = editor.value;
        return;
      }
      
      // Link shortcut (Ctrl/Cmd + K)
      if ((e.ctrlKey || e.metaKey) && e.key === 'k') {
        e.preventDefault();
        this.insertLink(editor);
        block.content = editor.value;
        return;
      }
      
      // Pass other key events to handlers
      handlers.onKeyDown(e);
    });
    
    // Auto-resize
    this.autoResize(editor);
    editor.addEventListener('input', () => this.autoResize(editor));
  }
  
  private setupPreview(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
    const container = element.querySelector('.markdown-block-container') as HTMLElement;
    const preview = element.querySelector('.markdown-preview') as HTMLElement;
    
    if (!container || !preview) return;
    
    // Make preview focusable
    preview.setAttribute('tabindex', '0');
    
    // Focus handling
    preview.addEventListener('focus', () => handlers.onFocus());
    preview.addEventListener('blur', () => handlers.onBlur());
    
    // Keyboard navigation
    preview.addEventListener('keydown', (e) => {
      // Switch to edit mode on Enter
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        block.metadata.isEditMode = true;
        handlers.onRequestUpdate?.();
        return;
      }
      
      handlers.onKeyDown(e);
    });
  }
  
  private wrapSelection(editor: HTMLTextAreaElement, before: string, after: string): void {
    const start = editor.selectionStart;
    const end = editor.selectionEnd;
    const selectedText = editor.value.substring(start, end);
    const replacement = before + (selectedText || 'text') + after;
    
    editor.value = editor.value.substring(0, start) + replacement + editor.value.substring(end);
    
    if (selectedText) {
      editor.selectionStart = start;
      editor.selectionEnd = start + replacement.length;
    } else {
      editor.selectionStart = start + before.length;
      editor.selectionEnd = start + before.length + 4; // 'text'.length
    }
    
    editor.focus();
  }
  
  private insertLink(editor: HTMLTextAreaElement): void {
    const start = editor.selectionStart;
    const end = editor.selectionEnd;
    const selectedText = editor.value.substring(start, end);
    const linkText = selectedText || 'link text';
    const replacement = `[${linkText}](url)`;
    
    editor.value = editor.value.substring(0, start) + replacement + editor.value.substring(end);
    
    // Select the URL part
    editor.selectionStart = start + linkText.length + 3; // '[linktext]('.length
    editor.selectionEnd = start + linkText.length + 6; // '[linktext](url'.length
    
    editor.focus();
  }
  
  private autoResize(editor: HTMLTextAreaElement): void {
    editor.style.height = 'auto';
    editor.style.height = editor.scrollHeight + 'px';
  }
  
  private parseMarkdown(markdown: string): string {
    // Basic markdown parsing - in production, use a proper markdown parser
    let html = this.escapeHtml(markdown);
    
    // Headers
    html = html.replace(/^### (.+)$/gm, '<h3>$1</h3>');
    html = html.replace(/^## (.+)$/gm, '<h2>$1</h2>');
    html = html.replace(/^# (.+)$/gm, '<h1>$1</h1>');
    
    // Bold
    html = html.replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>');
    html = html.replace(/__(.+?)__/g, '<strong>$1</strong>');
    
    // Italic
    html = html.replace(/\*(.+?)\*/g, '<em>$1</em>');
    html = html.replace(/_(.+?)_/g, '<em>$1</em>');
    
    // Code blocks
    html = html.replace(/```([\s\S]*?)```/g, '<pre><code>$1</code></pre>');
    
    // Inline code
    html = html.replace(/`(.+?)`/g, '<code>$1</code>');
    
    // Links
    html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
    
    // Lists
    html = html.replace(/^\* (.+)$/gm, '<li>$1</li>');
    html = html.replace(/^- (.+)$/gm, '<li>$1</li>');
    html = html.replace(/^\d+\. (.+)$/gm, '<li>$1</li>');
    
    // Wrap consecutive list items
    html = html.replace(/(<li>.*<\/li>\n?)+/g, (match) => {
      return '<ul>' + match + '</ul>';
    });
    
    // Paragraphs
    html = html.replace(/\n\n/g, '</p><p>');
    html = '<p>' + html + '</p>';
    
    // Clean up empty paragraphs
    html = html.replace(/<p><\/p>/g, '');
    html = html.replace(/<p>(<h[1-3]>)/g, '$1');
    html = html.replace(/(<\/h[1-3]>)<\/p>/g, '$1');
    html = html.replace(/<p>(<ul>)/g, '$1');
    html = html.replace(/(<\/ul>)<\/p>/g, '$1');
    html = html.replace(/<p>(<pre>)/g, '$1');
    html = html.replace(/(<\/pre>)<\/p>/g, '$1');
    
    return html;
  }
  
  private escapeHtml(text: string): string {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
  
  getContent(element: HTMLElement): string {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      return editor.value;
    }
    
    // If in preview mode, return the stored content
    const container = element.querySelector('.markdown-block-container');
    const blockId = container?.getAttribute('data-block-id');
    // In real implementation, would need access to block data
    return '';
  }
  
  setContent(element: HTMLElement, content: string): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      editor.value = content;
      this.autoResize(editor);
    }
  }
  
  getCursorPosition(element: HTMLElement): number | null {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    return editor ? editor.selectionStart : null;
  }
  
  setCursorToStart(element: HTMLElement): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      editor.selectionStart = editor.selectionEnd = 0;
      editor.focus();
    } else {
      this.focus(element);
    }
  }
  
  setCursorToEnd(element: HTMLElement): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      const length = editor.value.length;
      editor.selectionStart = editor.selectionEnd = length;
      editor.focus();
    } else {
      this.focus(element);
    }
  }
  
  focus(element: HTMLElement): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      editor.focus();
    } else {
      const preview = element.querySelector('.markdown-preview') as HTMLElement;
      preview?.focus();
    }
  }
  
  focusWithCursor(element: HTMLElement, position: 'start' | 'end' | number = 'end'): void {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (editor) {
      if (position === 'start') {
        this.setCursorToStart(element);
      } else if (position === 'end') {
        this.setCursorToEnd(element);
      } else if (typeof position === 'number') {
        editor.selectionStart = editor.selectionEnd = position;
        editor.focus();
      }
    } else {
      this.focus(element);
    }
  }
  
  getSplitContent(element: HTMLElement): { before: string; after: string } | null {
    const editor = element.querySelector('.markdown-editor') as HTMLTextAreaElement;
    if (!editor) return null;
    
    const cursorPos = editor.selectionStart;
    return {
      before: editor.value.substring(0, cursorPos),
      after: editor.value.substring(cursorPos)
    };
  }
  
  getStyles(): string {
    return `
      /* Markdown Block Container */
      .markdown-block-container {
        position: relative;
        margin: 12px 0;
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 6px;
        overflow: hidden;
        transition: all 0.15s ease;
        background: ${cssManager.bdTheme('#ffffff', '#111827')};
      }
      
      .markdown-block-container.selected {
        border-color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
      }
      
      /* Header */
      .markdown-header {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 8px 12px;
        border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        background: ${cssManager.bdTheme('#f9fafb', '#0a0a0a')};
      }
      
      .markdown-icon {
        font-size: 14px;
        font-weight: 600;
        opacity: 0.8;
      }
      
      .markdown-title {
        flex: 1;
        font-size: 13px;
        font-weight: 500;
        color: ${cssManager.bdTheme('#374151', '#e5e7eb')};
      }
      
      .markdown-toggle-mode {
        padding: 4px 8px;
        background: transparent;
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 4px;
        font-size: 14px;
        cursor: pointer;
        transition: all 0.15s ease;
      }
      
      .markdown-toggle-mode:hover {
        background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
        border-color: ${cssManager.bdTheme('#d1d5db', '#4b5563')};
      }
      
      /* Content */
      .markdown-content {
        position: relative;
        min-height: 120px;
      }
      
      /* Editor */
      .markdown-editor {
        width: 100%;
        min-height: 120px;
        padding: 12px;
        background: transparent;
        border: none;
        outline: none;
        resize: none;
        font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
        font-size: 13px;
        line-height: 1.6;
        color: ${cssManager.bdTheme('#1f2937', '#f3f4f6')};
        overflow: hidden;
      }
      
      .markdown-editor::placeholder {
        color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
      }
      
      /* Preview */
      .markdown-preview {
        padding: 12px;
        min-height: 96px;
        outline: none;
        font-size: 14px;
        line-height: 1.6;
        color: ${cssManager.bdTheme('#1f2937', '#f3f4f6')};
      }
      
      .preview-empty {
        color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
        font-style: italic;
      }
      
      /* Markdown preview styles */
      .markdown-preview h1 {
        font-size: 24px;
        font-weight: 600;
        margin: 16px 0 8px 0;
        color: ${cssManager.bdTheme('#111827', '#f9fafb')};
      }
      
      .markdown-preview h2 {
        font-size: 20px;
        font-weight: 600;
        margin: 14px 0 6px 0;
        color: ${cssManager.bdTheme('#111827', '#f9fafb')};
      }
      
      .markdown-preview h3 {
        font-size: 18px;
        font-weight: 600;
        margin: 12px 0 4px 0;
        color: ${cssManager.bdTheme('#111827', '#f9fafb')};
      }
      
      .markdown-preview p {
        margin: 8px 0;
      }
      
      .markdown-preview ul,
      .markdown-preview ol {
        margin: 8px 0;
        padding-left: 24px;
      }
      
      .markdown-preview li {
        margin: 4px 0;
      }
      
      .markdown-preview code {
        background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
        padding: 2px 4px;
        border-radius: 3px;
        font-family: 'Monaco', 'Consolas', 'Courier New', monospace;
        font-size: 0.9em;
      }
      
      .markdown-preview pre {
        background: ${cssManager.bdTheme('#f3f4f6', '#1f2937')};
        padding: 12px;
        border-radius: 4px;
        overflow-x: auto;
        margin: 8px 0;
      }
      
      .markdown-preview pre code {
        background: transparent;
        padding: 0;
      }
      
      .markdown-preview strong {
        font-weight: 600;
        color: ${cssManager.bdTheme('#111827', '#f9fafb')};
      }
      
      .markdown-preview em {
        font-style: italic;
      }
      
      .markdown-preview a {
        color: ${cssManager.bdTheme('#3b82f6', '#60a5fa')};
        text-decoration: none;
      }
      
      .markdown-preview a:hover {
        text-decoration: underline;
      }
      
      .markdown-preview blockquote {
        border-left: 3px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        padding-left: 12px;
        margin: 8px 0;
        color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
      }
    `;
  }
}