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

/**
 * ImageBlockHandler - Handles image upload, display, and interactions
 * 
 * Features:
 * - Click to upload
 * - Drag and drop support
 * - Base64 encoding (TODO: server upload in production)
 * - Loading states
 * - Alt text from filename
 */
export class ImageBlockHandler extends BaseBlockHandler {
  type = 'image';
  
  render(block: IBlock, isSelected: boolean): string {
    const imageUrl = block.metadata?.url;
    const altText = block.content || 'Image';
    const isLoading = block.metadata?.loading;
    
    return `
      <div class="image-block-container${isSelected ? ' selected' : ''}" 
           data-block-id="${block.id}"
           data-has-image="${!!imageUrl}"
           tabindex="0">
        ${isLoading ? this.renderLoading() : 
          imageUrl ? this.renderImage(imageUrl, altText) : 
          this.renderPlaceholder()}
        <input type="file" 
               class="image-file-input" 
               accept="image/*" 
               style="display: none;" />
      </div>
    `;
  }
  
  private renderPlaceholder(): string {
    return `
      <div class="image-upload-placeholder" style="cursor: pointer;">
        <div class="upload-icon" style="pointer-events: none;">
          <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
            <rect x="3" y="3" width="18" height="18" rx="2" ry="2"/>
            <circle cx="8.5" cy="8.5" r="1.5"/>
            <polyline points="21 15 16 10 5 21"/>
          </svg>
        </div>
        <div class="upload-text" style="pointer-events: none;">Click to upload an image</div>
        <div class="upload-hint" style="pointer-events: none;">or drag and drop</div>
      </div>
    `;
  }
  
  private renderImage(url: string, altText: string): string {
    return `
      <div class="image-container">
        <img src="${url}" alt="${this.escapeHtml(altText)}" />
      </div>
    `;
  }
  
  private renderLoading(): string {
    return `
      <div class="image-loading">
        <div class="loading-spinner"></div>
        <div class="loading-text">Uploading image...</div>
      </div>
    `;
  }
  
  setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
    const container = element.querySelector('.image-block-container') as HTMLElement;
    const fileInput = element.querySelector('.image-file-input') as HTMLInputElement;
    
    if (!container) {
      console.error('ImageBlockHandler: Could not find container');
      return;
    }
    
    if (!fileInput) {
      console.error('ImageBlockHandler: Could not find file input');
      return;
    }
    
    // Click to upload (only on placeholder)
    const placeholder = container.querySelector('.image-upload-placeholder');
    if (placeholder) {
      placeholder.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        console.log('ImageBlockHandler: Placeholder clicked, opening file selector');
        fileInput.click();
      });
    }
    
    // Container click for focus
    container.addEventListener('click', () => {
      handlers.onFocus();
    });
    
    // File input change
    fileInput.addEventListener('change', async (e) => {
      const input = e.target as HTMLInputElement;
      const file = input.files?.[0];
      if (file) {
        console.log('ImageBlockHandler: File selected:', file.name);
        await this.handleFileUpload(file, block, handlers);
      }
    });
    
    // Drag and drop
    container.addEventListener('dragover', (e) => {
      e.preventDefault();
      e.stopPropagation();
      if (!block.metadata?.url) {
        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 file = e.dataTransfer?.files[0];
      if (file && file.type.startsWith('image/') && !block.metadata?.url) {
        await this.handleFileUpload(file, 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') {
        if (block.metadata?.url) {
          // Clear the image
          block.metadata.url = undefined;
          block.metadata.loading = false;
          block.content = '';
          handlers.onInput(new InputEvent('input'));
          return;
        }
      }
      handlers.onKeyDown(e);
    });
  }
  
  private async handleFileUpload(
    file: File, 
    block: IBlock, 
    handlers: IBlockEventHandlers
  ): Promise<void> {
    console.log('ImageBlockHandler: Starting file upload', { 
      fileName: file.name, 
      fileSize: file.size,
      blockId: block.id 
    });
    
    // Validate file
    if (!file.type.startsWith('image/')) {
      console.error('Invalid file type:', file.type);
      return;
    }
    
    // Check file size (10MB limit)
    const maxSize = 10 * 1024 * 1024;
    if (file.size > maxSize) {
      console.error('File too large. Maximum size is 10MB');
      return;
    }
    
    // Set loading state
    if (!block.metadata) block.metadata = {};
    block.metadata.loading = true;
    block.metadata.fileName = file.name;
    block.metadata.fileSize = file.size;
    block.metadata.mimeType = file.type;
    
    console.log('ImageBlockHandler: Set loading state, requesting update');
    // Request immediate UI update for loading state
    handlers.onRequestUpdate?.();
    
    try {
      // Convert to base64
      const dataUrl = await this.fileToDataUrl(file);
      
      // Update block
      block.metadata.url = dataUrl;
      block.metadata.loading = false;
      
      // Set default alt text from filename
      const nameWithoutExt = file.name.replace(/\.[^/.]+$/, '');
      block.content = nameWithoutExt;
      
      console.log('ImageBlockHandler: Upload complete, requesting update', {
        hasUrl: !!block.metadata.url,
        urlLength: dataUrl.length,
        altText: block.content
      });
      
      // Request immediate UI update to show uploaded image
      handlers.onRequestUpdate?.();
      
    } catch (error) {
      console.error('Failed to upload image:', error);
      block.metadata.loading = false;
      // Request UI update to clear loading state
      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 escapeHtml(text: string): string {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
  
  getContent(element: HTMLElement): string {
    // Content is the alt text
    const block = this.getBlockFromElement(element);
    return block?.content || '';
  }
  
  setContent(element: HTMLElement, content: string): void {
    // Content is the alt text
    const block = this.getBlockFromElement(element);
    if (block) {
      block.content = content;
    }
  }
  
  private getBlockFromElement(element: HTMLElement): IBlock | null {
    const container = element.querySelector('.image-block-container');
    const blockId = container?.getAttribute('data-block-id');
    if (!blockId) return null;
    
    // This is a simplified version - in real implementation,
    // we'd need access to the block data
    return {
      id: blockId,
      type: 'image',
      content: '',
      metadata: {}
    };
  }
  
  getCursorPosition(element: HTMLElement): number | null {
    return null; // Images 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('.image-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; // Images can't be split
  }
  
  getStyles(): string {
    return `
      /* Image Block Container */
      .image-block-container {
        position: relative;
        margin: 12px 0;
        border-radius: 6px;
        overflow: hidden;
        transition: all 0.15s ease;
        outline: none;
        cursor: pointer;
      }
      
      .image-block-container.selected {
        box-shadow: 0 0 0 2px ${cssManager.bdTheme('#6366f1', '#818cf8')};
      }
      
      /* Upload Placeholder */
      .image-upload-placeholder {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 48px 24px;
        border: 2px dashed ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-radius: 6px;
        background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
        transition: all 0.15s ease;
      }
      
      .image-block-container:hover .image-upload-placeholder {
        border-color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
        background: ${cssManager.bdTheme('#f9fafb', '#111827')};
      }
      
      .image-block-container.drag-over .image-upload-placeholder {
        border-color: ${cssManager.bdTheme('#6366f1', '#818cf8')};
        background: ${cssManager.bdTheme('#eff6ff', '#1e1b4b')};
      }
      
      .upload-icon {
        margin-bottom: 12px;
        color: ${cssManager.bdTheme('#9ca3af', '#4b5563')};
      }
      
      .upload-text {
        font-size: 14px;
        font-weight: 500;
        color: ${cssManager.bdTheme('#374151', '#e5e7eb')};
        margin-bottom: 4px;
      }
      
      .upload-hint {
        font-size: 12px;
        color: ${cssManager.bdTheme('#9ca3af', '#6b7280')};
      }
      
      /* Image Container */
      .image-container {
        display: flex;
        justify-content: center;
        align-items: center;
        min-height: 200px;
        background: ${cssManager.bdTheme('#f9fafb', '#111827')};
      }
      
      .image-container img {
        max-width: 100%;
        height: auto;
        display: block;
        border-radius: 4px;
      }
      
      /* Loading State */
      .image-loading {
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        padding: 48px 24px;
        background: ${cssManager.bdTheme('#fafafa', '#0a0a0a')};
      }
      
      .loading-spinner {
        width: 32px;
        height: 32px;
        border: 3px solid ${cssManager.bdTheme('#e5e7eb', '#374151')};
        border-top-color: ${cssManager.bdTheme('#6366f1', '#818cf8')};
        border-radius: 50%;
        animation: spin 0.8s linear infinite;
        margin-bottom: 12px;
      }
      
      @keyframes spin {
        to { transform: rotate(360deg); }
      }
      
      .loading-text {
        font-size: 14px;
        color: ${cssManager.bdTheme('#6b7280', '#9ca3af')};
      }
      
      /* File input hidden */
      .image-file-input {
        display: none !important;
      }
    `;
  }
}