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

/**
 * AttachmentBlockHandler - Handles file attachments
 * 
 * Features:
 * - Multiple file upload support
 * - Click to upload or drag and drop
 * - File type icons
 * - Remove individual files
 * - Base64 encoding (TODO: server upload in production)
 */
export class AttachmentBlockHandler extends BaseBlockHandler {
  type = 'attachment';
  
  render(block: IBlock, isSelected: boolean): string {
    const files = block.metadata?.files || [];
    
    return `
      <div class="attachment-block-container${isSelected ? ' selected' : ''}" 
           data-block-id="${block.id}"
           tabindex="0">
        <div class="attachment-header">
          <div class="attachment-icon">📎</div>
          <div class="attachment-title">File Attachments</div>
        </div>
        <div class="attachment-list">
          ${files.length > 0 ? this.renderFiles(files) : this.renderPlaceholder()}
        </div>
        <input type="file" 
               class="attachment-file-input" 
               multiple 
               style="display: none;" />
        ${files.length > 0 ? '<button class="add-more-files">Add More Files</button>' : ''}
      </div>
    `;
  }
  
  private renderPlaceholder(): string {
    return `
      <div class="attachment-placeholder">
        <div class="placeholder-text">Click to add files</div>
        <div class="placeholder-hint">or drag and drop</div>
      </div>
    `;
  }
  
  private renderFiles(files: any[]): string {
    return files.map((file: any) => `
      <div class="attachment-item" data-file-id="${file.id}">
        <div class="file-icon">${this.getFileIcon(file.type)}</div>
        <div class="file-info">
          <div class="file-name">${this.escapeHtml(file.name)}</div>
          <div class="file-size">${this.formatFileSize(file.size)}</div>
        </div>
        <button class="remove-file" data-file-id="${file.id}">×</button>
      </div>
    `).join('');
  }
  
  setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
    const container = element.querySelector('.attachment-block-container') as HTMLElement;
    const fileInput = element.querySelector('.attachment-file-input') as HTMLInputElement;
    
    if (!container || !fileInput) {
      console.error('AttachmentBlockHandler: Could not find required elements');
      return;
    }
    
    // Initialize files array if needed
    if (!block.metadata) block.metadata = {};
    if (!block.metadata.files) block.metadata.files = [];
    
    // Click to upload on placeholder
    const placeholder = container.querySelector('.attachment-placeholder');
    if (placeholder) {
      placeholder.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        fileInput.click();
      });
    }
    
    // Add more files button
    const addMoreBtn = container.querySelector('.add-more-files') as HTMLButtonElement;
    if (addMoreBtn) {
      addMoreBtn.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        fileInput.click();
      });
    }
    
    // File input change
    fileInput.addEventListener('change', async (e) => {
      const input = e.target as HTMLInputElement;
      const files = input.files;
      if (files && files.length > 0) {
        await this.handleFileAttachments(files, block, handlers);
        input.value = ''; // Clear input for next selection
      }
    });
    
    // Remove file buttons
    container.addEventListener('click', (e) => {
      const target = e.target as HTMLElement;
      if (target.classList.contains('remove-file')) {
        e.preventDefault();
        e.stopPropagation();
        const fileId = target.getAttribute('data-file-id');
        if (fileId) {
          this.removeFile(fileId, block, handlers);
        }
      }
    });
    
    // Drag and drop
    container.addEventListener('dragover', (e) => {
      e.preventDefault();
      e.stopPropagation();
      container.classList.add('drag-over');
    });
    
    container.addEventListener('dragleave', (e) => {
      e.preventDefault();
      e.stopPropagation();
      container.classList.remove('drag-over');
    });
    
    container.addEventListener('drop', async (e) => {
      e.preventDefault();
      e.stopPropagation();
      container.classList.remove('drag-over');
      
      const files = e.dataTransfer?.files;
      if (files && files.length > 0) {
        await this.handleFileAttachments(files, block, handlers);
      }
    });
    
    // Focus/blur
    container.addEventListener('focus', () => handlers.onFocus());
    container.addEventListener('blur', () => handlers.onBlur());
    
    // Keyboard navigation
    container.addEventListener('keydown', (e) => {
      if (e.key === 'Delete' || e.key === 'Backspace') {
        // Only remove all files if container is focused, not when removing individual files
        if (document.activeElement === container && block.metadata?.files?.length > 0) {
          e.preventDefault();
          block.metadata.files = [];
          handlers.onRequestUpdate?.();
          return;
        }
      }
      handlers.onKeyDown(e);
    });
  }
  
  private async handleFileAttachments(
    files: FileList,
    block: IBlock,
    handlers: IBlockEventHandlers
  ): Promise<void> {
    if (!block.metadata) block.metadata = {};
    if (!block.metadata.files) block.metadata.files = [];
    
    for (const file of Array.from(files)) {
      try {
        const dataUrl = await this.fileToDataUrl(file);
        const fileData = {
          id: this.generateId(),
          name: file.name,
          size: file.size,
          type: file.type,
          data: dataUrl
        };
        
        block.metadata.files.push(fileData);
      } catch (error) {
        console.error('Failed to attach file:', file.name, error);
      }
    }
    
    // Update block content with file count
    block.content = `${block.metadata.files.length} file${block.metadata.files.length !== 1 ? 's' : ''} attached`;
    
    // Request UI update
    handlers.onRequestUpdate?.();
  }
  
  private removeFile(fileId: string, block: IBlock, handlers: IBlockEventHandlers): void {
    if (!block.metadata?.files) return;
    
    block.metadata.files = block.metadata.files.filter((f: any) => f.id !== fileId);
    
    // Update content
    block.content = block.metadata.files.length > 0 
      ? `${block.metadata.files.length} file${block.metadata.files.length !== 1 ? 's' : ''} attached`
      : '';
    
    // Request UI update
    handlers.onRequestUpdate?.();
  }
  
  private fileToDataUrl(file: File): Promise<string> {
    return new Promise((resolve, reject) => {
      const reader = new FileReader();
      reader.onload = (e) => {
        const result = e.target?.result;
        if (typeof result === 'string') {
          resolve(result);
        } else {
          reject(new Error('Failed to read file'));
        }
      };
      reader.onerror = reject;
      reader.readAsDataURL(file);
    });
  }
  
  private getFileIcon(mimeType: string): string {
    if (mimeType.startsWith('image/')) return '🖼️';
    if (mimeType.startsWith('video/')) return '🎥';
    if (mimeType.startsWith('audio/')) return '🎵';
    if (mimeType.includes('pdf')) return '📄';
    if (mimeType.includes('zip') || mimeType.includes('rar') || mimeType.includes('tar')) return '🗄️';
    if (mimeType.includes('sheet')) return '📊';
    if (mimeType.includes('document') || mimeType.includes('msword')) return '📝';
    if (mimeType.includes('presentation')) return '📋';
    if (mimeType.includes('text')) return '📃';
    return '📁';
  }
  
  private formatFileSize(bytes: number): string {
    if (bytes === 0) return '0 Bytes';
    const k = 1024;
    const sizes = ['Bytes', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  }
  
  private generateId(): string {
    return `file-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
  }
  
  private escapeHtml(text: string): string {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
  
  getContent(element: HTMLElement): string {
    // Content is the description of attached files
    const block = this.getBlockFromElement(element);
    return block?.content || '';
  }
  
  setContent(element: HTMLElement, content: string): void {
    // Content is the description of attached files
    const block = this.getBlockFromElement(element);
    if (block) {
      block.content = content;
    }
  }
  
  private getBlockFromElement(element: HTMLElement): IBlock | null {
    const container = element.querySelector('.attachment-block-container');
    const blockId = container?.getAttribute('data-block-id');
    if (!blockId) return null;
    
    // Simplified version - in real implementation would need access to block data
    return {
      id: blockId,
      type: 'attachment',
      content: '',
      metadata: {}
    };
  }
  
  getCursorPosition(element: HTMLElement): number | null {
    return null; // Attachment blocks don't have cursor position
  }
  
  setCursorToStart(element: HTMLElement): void {
    this.focus(element);
  }
  
  setCursorToEnd(element: HTMLElement): void {
    this.focus(element);
  }
  
  focus(element: HTMLElement): void {
    const container = element.querySelector('.attachment-block-container') as HTMLElement;
    container?.focus();
  }
  
  focusWithCursor(element: HTMLElement, position: 'start' | 'end' | number = 'end'): void {
    this.focus(element);
  }
  
  getSplitContent(element: HTMLElement): { before: string; after: string } | null {
    return null; // Attachment blocks can't be split
  }
  
  getStyles(): string {
    return `
      /* Attachment Block Container */
      .attachment-block-container {
        position: relative;
        margin: 12px 0;
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 6px;
        overflow: hidden;
        transition: all 0.15s ease;
        outline: none;
        background: ${cssManager.bdTheme('#ffffff', '#111827')};
      }
      
      .attachment-block-container.selected {
        border-color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
      }
      
      .attachment-block-container.drag-over {
        background: ${cssManager.bdTheme('#f9fafb', '#1f2937')};
        border-color: ${cssManager.bdTheme('#6366f1', '#818cf8')};
      }
      
      /* Header */
      .attachment-header {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 12px 16px;
        border-bottom: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        background: ${cssManager.bdTheme('#f9fafb', '#0a0a0a')};
      }
      
      .attachment-icon {
        font-size: 18px;
        opacity: 0.8;
      }
      
      .attachment-title {
        font-size: 14px;
        font-weight: 500;
        color: ${cssManager.bdTheme('#374151', '#e5e7eb')};
      }
      
      /* File List */
      .attachment-list {
        padding: 8px;
        min-height: 80px;
        display: flex;
        flex-direction: column;
        gap: 4px;
      }
      
      /* Placeholder */
      .attachment-placeholder {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 24px;
        cursor: pointer;
        transition: all 0.15s ease;
      }
      
      .attachment-placeholder:hover {
        background: ${cssManager.bdTheme('#f9fafb', '#1f2937')};
      }
      
      .placeholder-text {
        font-size: 14px;
        color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
        margin-bottom: 4px;
      }
      
      .placeholder-hint {
        font-size: 12px;
        color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
      }
      
      /* File Items */
      .attachment-item {
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 8px 12px;
        background: ${cssManager.bdTheme('#f9fafb', '#1f2937')};
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 4px;
        transition: all 0.15s ease;
      }
      
      .attachment-item:hover {
        background: ${cssManager.bdTheme('#f3f4f6', '#374151')};
      }
      
      .file-icon {
        font-size: 20px;
        flex-shrink: 0;
      }
      
      .file-info {
        flex: 1;
        min-width: 0;
      }
      
      .file-name {
        font-size: 13px;
        font-weight: 500;
        color: ${cssManager.bdTheme('#111827', '#f9fafb')};
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
      }
      
      .file-size {
        font-size: 11px;
        color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
        margin-top: 2px;
      }
      
      .remove-file {
        flex-shrink: 0;
        width: 24px;
        height: 24px;
        display: flex;
        align-items: center;
        justify-content: center;
        background: transparent;
        border: 1px solid transparent;
        border-radius: 4px;
        color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
        font-size: 18px;
        line-height: 1;
        cursor: pointer;
        transition: all 0.15s ease;
        padding: 0;
      }
      
      .remove-file:hover {
        background: ${cssManager.bdTheme('#fee2e2', '#991b1b')};
        border-color: ${cssManager.bdTheme('#fca5a5', '#dc2626')};
        color: ${cssManager.bdTheme('#dc2626', '#fca5a5')};
      }
      
      /* Add More Files Button */
      .add-more-files {
        margin: 8px;
        padding: 6px 12px;
        background: transparent;
        border: 1px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 4px;
        font-size: 13px;
        color: ${cssManager.bdTheme('#374151', '#e5e7eb')};
        cursor: pointer;
        transition: all 0.15s ease;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
      }
      
      .add-more-files:hover {
        background: ${cssManager.bdTheme('#f9fafb', '#1f2937')};
        border-color: ${cssManager.bdTheme('#d1d5db', '#4b5563')};
      }
      
      /* Hidden file input */
      .attachment-file-input {
        display: none !important;
      }
    `;
  }
}