/**
 * Color Picker
 * 
 * Color selection dialog for text formatting
 * Extracted from Holy Habit holy-editor-pro.js
 */

import { ColorOption } from '../types/Editor';
import { ToastManager } from './ToastManager';

export class ColorPicker {
  private static instance: ColorPicker;
  private isVisible = false;
  private onColorSelect: ((color: string) => void) | null = null;

  // Default 8-color palette
  private static readonly DEFAULT_COLORS: ColorOption[] = [
    { color: '#ff0000', name: '빨간색' },
    { color: '#ff8c00', name: '주황색' },
    { color: '#ffd700', name: '노란색' },
    { color: '#008000', name: '초록색' },
    { color: '#0000ff', name: '파란색' },
    { color: '#000080', name: '남색' },
    { color: '#800080', name: '보라색' },
    { color: '#ff1493', name: '분홍색' }
  ];

  private colors: ColorOption[] = ColorPicker.DEFAULT_COLORS;
  private toastManager: ToastManager;

  private constructor() {
    this.toastManager = ToastManager.getInstance();
  }

  /**
   * Get singleton instance
   */
  public static getInstance(): ColorPicker {
    if (!ColorPicker.instance) {
      ColorPicker.instance = new ColorPicker();
    }
    return ColorPicker.instance;
  }

  /**
   * Show color picker dialog
   */
  public show(onColorSelect?: (color: string) => void): void {
    // Close existing picker
    if (this.isVisible) {
      this.hide();
      return;
    }

    this.onColorSelect = onColorSelect || null;
    this.createColorPickerDialog();
    this.isVisible = true;
  }

  /**
   * Hide color picker dialog
   */
  public hide(): void {
    const existingPicker = document.querySelector('.holy-color-picker');
    if (existingPicker) {
      existingPicker.remove();
    }
    this.isVisible = false;
    this.onColorSelect = null;
  }

  /**
   * Set custom color palette
   */
  public setColors(colors: ColorOption[]): void {
    this.colors = colors;
  }

  /**
   * Get current color palette
   */
  public getColors(): ColorOption[] {
    return [...this.colors];
  }

  /**
   * Add color to palette
   */
  public addColor(color: ColorOption): void {
    this.colors.push(color);
  }

  /**
   * Remove color from palette
   */
  public removeColor(colorValue: string): void {
    this.colors = this.colors.filter(c => c.color !== colorValue);
  }

  /**
   * Reset to default colors
   */
  public resetToDefaults(): void {
    this.colors = [...ColorPicker.DEFAULT_COLORS];
  }

  /**
   * Create color picker dialog
   */
  private createColorPickerDialog(): void {
    // Remove existing picker
    const existingPicker = document.querySelector('.holy-color-picker');
    if (existingPicker) {
      existingPicker.remove();
    }

    // Create dialog container
    const pickerContainer = document.createElement('div');
    pickerContainer.className = 'holy-color-picker';
    this.applyContainerStyles(pickerContainer);

    // Create title
    const title = this.createTitle();
    pickerContainer.appendChild(title);

    // Create color grid
    const colorGrid = this.createColorGrid();
    pickerContainer.appendChild(colorGrid);

    // Create close button
    const closeButton = this.createCloseButton();
    pickerContainer.appendChild(closeButton);

    // Add to document
    document.body.appendChild(pickerContainer);

    // Setup outside click handler
    this.setupOutsideClickHandler(pickerContainer);

    console.log('🎨 Color picker dialog shown');
  }

  /**
   * Apply container styles
   */
  private applyContainerStyles(container: HTMLElement): void {
    container.style.cssText = `
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: white;
      border: 1px solid #ccc;
      border-radius: 8px;
      padding: 20px;
      box-shadow: 0 4px 20px rgba(0,0,0,0.2);
      z-index: 10000;
      min-width: 280px;
      max-width: 90vw;
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    `;
  }

  /**
   * Create title element
   */
  private createTitle(): HTMLElement {
    const title = document.createElement('h3');
    title.textContent = '텍스트 색상 선택';
    title.style.cssText = `
      margin: 0 0 15px 0;
      font-size: 16px;
      text-align: center;
      color: #333;
      font-weight: 600;
    `;
    return title;
  }

  /**
   * Create color grid
   */
  private createColorGrid(): HTMLElement {
    const colorGrid = document.createElement('div');
    colorGrid.style.cssText = `
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 10px;
      margin-bottom: 15px;
    `;

    // Create color buttons
    this.colors.forEach((colorOption) => {
      const colorButton = this.createColorButton(colorOption);
      colorGrid.appendChild(colorButton);
    });

    return colorGrid;
  }

  /**
   * Create individual color button
   */
  private createColorButton(colorOption: ColorOption): HTMLElement {
    const colorButton = document.createElement('button');
    colorButton.style.cssText = `
      width: 50px;
      height: 50px;
      background-color: ${colorOption.color};
      border: 2px solid #ddd;
      border-radius: 4px;
      cursor: pointer;
      transition: all 0.2s ease;
      position: relative;
      overflow: hidden;
    `;
    colorButton.title = colorOption.name;
    colorButton.setAttribute('aria-label', `색상 선택: ${colorOption.name}`);

    // Add hover effects
    this.addButtonHoverEffects(colorButton);

    // Add click handler
    colorButton.addEventListener('click', () => {
      this.handleColorSelection(colorOption);
    });

    return colorButton;
  }

  /**
   * Add hover effects to color button
   */
  private addButtonHoverEffects(button: HTMLElement): void {
    button.addEventListener('mouseenter', () => {
      button.style.transform = 'scale(1.1)';
      button.style.borderColor = '#333';
      button.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)';
    });

    button.addEventListener('mouseleave', () => {
      button.style.transform = 'scale(1)';
      button.style.borderColor = '#ddd';
      button.style.boxShadow = 'none';
    });

    // Add ripple effect on click
    button.addEventListener('click', (e) => {
      const ripple = document.createElement('div');
      const rect = button.getBoundingClientRect();
      const size = Math.max(rect.width, rect.height);
      const x = e.clientX - rect.left - size / 2;
      const y = e.clientY - rect.top - size / 2;

      ripple.style.cssText = `
        position: absolute;
        width: ${size}px;
        height: ${size}px;
        left: ${x}px;
        top: ${y}px;
        background: rgba(255,255,255,0.6);
        border-radius: 50%;
        transform: scale(0);
        animation: ripple 0.6s linear;
        pointer-events: none;
      `;

      // Add ripple animation if not exists
      this.addRippleAnimation();

      button.appendChild(ripple);

      setTimeout(() => {
        ripple.remove();
      }, 600);
    });
  }

  /**
   * Create close button
   */
  private createCloseButton(): HTMLElement {
    const closeButton = document.createElement('button');
    closeButton.textContent = '닫기';
    closeButton.style.cssText = `
      width: 100%;
      padding: 8px 16px;
      background-color: #f0f0f0;
      border: 1px solid #ddd;
      border-radius: 4px;
      cursor: pointer;
      font-size: 14px;
      transition: background-color 0.2s ease;
      font-family: inherit;
    `;

    closeButton.addEventListener('mouseenter', () => {
      closeButton.style.backgroundColor = '#e0e0e0';
    });

    closeButton.addEventListener('mouseleave', () => {
      closeButton.style.backgroundColor = '#f0f0f0';
    });

    closeButton.addEventListener('click', () => {
      this.hide();
    });

    return closeButton;
  }

  /**
   * Handle color selection
   */
  private handleColorSelection(colorOption: ColorOption): void {
    console.log('🎨 Color selected:', colorOption);

    // Call callback if provided
    if (this.onColorSelect) {
      this.onColorSelect(colorOption.color);
    }

    // Show success toast
    this.toastManager.success(`${colorOption.name} 적용`);

    // Hide picker
    this.hide();
  }

  /**
   * Setup outside click handler
   */
  private setupOutsideClickHandler(container: HTMLElement): void {
    const handleOutsideClick = (e: MouseEvent) => {
      if (!container.contains(e.target as Node)) {
        this.hide();
        document.removeEventListener('click', handleOutsideClick);
      }
    };

    // Add handler with slight delay to prevent immediate closure
    setTimeout(() => {
      document.addEventListener('click', handleOutsideClick);
    }, 100);

    // Prevent clicks inside container from bubbling
    container.addEventListener('click', (e) => {
      e.stopPropagation();
    });
  }

  /**
   * Add ripple animation CSS
   */
  private addRippleAnimation(): void {
    if (!document.querySelector('#holy-color-picker-ripple-styles')) {
      const style = document.createElement('style');
      style.id = 'holy-color-picker-ripple-styles';
      style.textContent = `
        @keyframes ripple {
          to {
            transform: scale(2);
            opacity: 0;
          }
        }
      `;
      document.head.appendChild(style);
    }
  }

  /**
   * Check if picker is currently visible
   */
  public isOpen(): boolean {
    return this.isVisible;
  }

  /**
   * Get color name by value
   */
  public getColorName(colorValue: string): string | undefined {
    const colorOption = this.colors.find(c => c.color.toLowerCase() === colorValue.toLowerCase());
    return colorOption?.name;
  }

  /**
   * Show color picker with custom position
   */
  public showAt(x: number, y: number, onColorSelect?: (color: string) => void): void {
    this.show(onColorSelect);
    
    // Adjust position after creation
    setTimeout(() => {
      const picker = document.querySelector('.holy-color-picker') as HTMLElement;
      if (picker) {
        picker.style.position = 'fixed';
        picker.style.top = `${y}px`;
        picker.style.left = `${x}px`;
        picker.style.transform = 'none';
        
        // Ensure picker stays within viewport
        this.adjustPositionToViewport(picker);
      }
    }, 0);
  }

  /**
   * Adjust picker position to stay within viewport
   */
  private adjustPositionToViewport(picker: HTMLElement): void {
    const rect = picker.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    // Adjust horizontal position
    if (rect.right > viewportWidth) {
      picker.style.left = `${viewportWidth - rect.width - 10}px`;
    }
    if (rect.left < 0) {
      picker.style.left = '10px';
    }

    // Adjust vertical position
    if (rect.bottom > viewportHeight) {
      picker.style.top = `${viewportHeight - rect.height - 10}px`;
    }
    if (rect.top < 0) {
      picker.style.top = '10px';
    }
  }
}