/**
 * Enhanced Swipe Card Component
 * Provides a more modern and interactive card interface for the swipe app
 */

class SwipeCard {
  constructor(options = {}) {
    this.container = options.container || document.querySelector('.swipe-container');
    this.onSwipe = options.onSwipe || (() => {});
    this.threshold = options.threshold || 100;
    this.rotationFactor = options.rotationFactor || 0.05;
    this.scaleFactor = options.scaleFactor || 0.0005;
    this.transitionDuration = options.transitionDuration || 500;
    
    this.state = {
      isDragging: false,
      startX: 0,
      startY: 0,
      moveX: 0,
      moveY: 0,
      hasMoved: false,
      touchStartTime: 0,
      currentImageInfo: null
    };
    
    this.card = null;
    this.actionHints = null;
    this.decisionIndicators = {};
    
    this.init();
  }
  
  init() {
    // Find or create the card element
    this.card = this.container.querySelector('.image-card') || this.createCardElement();
    
    // Find action hints
    this.actionHints = {
      left: this.container.querySelector('.left-hint'),
      right: this.container.querySelector('.right-hint'),
      up: this.container.querySelector('.up-hint'),
      down: this.container.querySelector('.down-hint')
    };
    
    // Create decision indicators if they don't exist
    this.createDecisionIndicators();
    
    // Add event listeners
    this.addEventListeners();
    
    // Add 3D tilt effect
    this.add3DTiltEffect();
    
    console.log('SwipeCard initialized');
  }
  
  createCardElement() {
    const card = document.createElement('div');
    card.className = 'image-card';
    card.id = 'current-card';
    card.setAttribute('role', 'img');
    card.setAttribute('aria-label', 'Image to be swiped');
    
    const img = document.createElement('img');
    img.src = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20width%3D%22400%22%20height%3D%22400%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Crect%20width%3D%22400%22%20height%3D%22400%22%20fill%3D%22%23e0e0e0%22%2F%3E%3Ctext%20x%3D%22200%22%20y%3D%22200%22%20font-size%3D%2220%22%20text-anchor%3D%22middle%22%20alignment-baseline%3D%22middle%22%20fill%3D%22%23999%22%3ELoading...%3C%2Ftext%3E%3C%2Fsvg%3E';
    img.alt = 'Image';
    
    const loadingIndicator = document.createElement('div');
    loadingIndicator.className = 'loading-indicator';
    loadingIndicator.innerHTML = `
      <div class="loading-spinner"></div>
      <div>Loading...</div>
    `;
    
    card.appendChild(img);
    card.appendChild(loadingIndicator);
    this.container.appendChild(card);
    
    return card;
  }
  
  createDecisionIndicators() {
    const directions = ['left', 'right', 'up', 'down'];
    const icons = ['fa-trash', 'fa-folder-plus', 'fa-star', 'fa-clock'];
    
    directions.forEach((direction, index) => {
      // Check if indicator already exists
      let indicator = this.container.querySelector(`.decision-${direction}`);
      
      if (!indicator) {
        indicator = document.createElement('div');
        indicator.className = `swipe-decision decision-${direction}`;
        indicator.innerHTML = `<i class="fa-solid ${icons[index]} fa-bounce"></i>`;
        this.container.appendChild(indicator);
      }
      
      this.decisionIndicators[direction] = indicator;
    });
  }
  
  addEventListeners() {
    // Mouse events
    this.card.addEventListener('mousedown', e => this.handlePointerDown(e.clientX, e.clientY));
    document.addEventListener('mousemove', e => this.handlePointerMove(e.clientX, e.clientY));
    document.addEventListener('mouseup', () => this.handlePointerUp());
    
    // Touch events
    this.card.addEventListener('touchstart', e => this.handlePointerDown(e.touches[0].clientX, e.touches[0].clientY), { passive: true });
    this.card.addEventListener('touchmove', e => this.handlePointerMove(e.touches[0].clientX, e.touches[0].clientY), { passive: true });
    this.card.addEventListener('touchend', () => this.handlePointerUp());
  }
  
  add3DTiltEffect() {
    this.container.addEventListener('mousemove', e => {
      if (window.innerWidth < 992) return; // Skip on mobile
      
      // Only apply when not dragging
      if (this.state.isDragging) return;
      
      const rect = this.container.getBoundingClientRect();
      const x = e.clientX - rect.left;
      const y = e.clientY - rect.top;
      
      // Calculate rotation based on mouse position
      const centerX = rect.width / 2;
      const centerY = rect.height / 2;
      
      const rotateY = ((x - centerX) / centerX) * 5; // Max 5 degrees
      const rotateX = ((centerY - y) / centerY) * 5; // Max 5 degrees
      
      // Apply the transform
      this.card.style.transform = `perspective(1000px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
    });
    
    this.container.addEventListener('mouseleave', () => {
      // Reset transform when mouse leaves
      if (!this.state.isDragging) {
        this.card.style.transition = 'transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)';
        this.card.style.transform = '';
        setTimeout(() => {
          this.card.style.transition = '';
        }, 500);
      }
    });
  }
  
  handlePointerDown(x, y) {
    this.state.isDragging = true;
    this.state.startX = x;
    this.state.startY = y;
    this.state.hasMoved = false;
    this.state.touchStartTime = Date.now();
    this.card.classList.add('swiping');
    this.card.style.transition = '';
  }
  
  handlePointerMove(x, y) {
    if (!this.state.isDragging) return;
    
    this.state.moveX = x - this.state.startX;
    this.state.moveY = y - this.state.startY;
    
    if (Math.abs(this.state.moveX) > 10 || Math.abs(this.state.moveY) > 10) {
      this.state.hasMoved = true;
    }
    
    // Apply transform with smoother rotation and scale effect
    this.card.style.transform = `translate(${this.state.moveX}px, ${this.state.moveY}px) rotate(${this.state.moveX * this.rotationFactor}deg) scale(${1 - Math.abs(this.state.moveX) * this.scaleFactor})`;
    
    // Show appropriate hint based on direction
    const absX = Math.abs(this.state.moveX);
    const absY = Math.abs(this.state.moveY);
    
    // Hide all hints first
    Object.values(this.actionHints).forEach(hint => hint && hint.classList.remove('visible'));
    
    // Show the appropriate hint based on the direction of movement
    if (absX > 50 || absY > 50) {
      if (absX > absY) {
        if (this.state.moveX > 0) {
          this.actionHints.right && this.actionHints.right.classList.add('visible');
        } else {
          this.actionHints.left && this.actionHints.left.classList.add('visible');
        }
      } else {
        if (this.state.moveY > 0) {
          this.actionHints.down && this.actionHints.down.classList.add('visible');
        } else {
          this.actionHints.up && this.actionHints.up.classList.add('visible');
        }
      }
    }
  }
  
  handlePointerUp() {
    if (!this.state.isDragging) return;
    this.state.isDragging = false;
    this.card.classList.remove('swiping');
    
    // Hide all hints
    Object.values(this.actionHints).forEach(hint => hint && hint.classList.remove('visible'));
    
    const absX = Math.abs(this.state.moveX);
    const absY = Math.abs(this.state.moveY);
    
    if (this.state.hasMoved && (absX > this.threshold || absY > this.threshold)) {
      let direction;
      
      if (absX > absY) {
        direction = this.state.moveX > 0 ? 'right' : 'left';
      } else {
        direction = this.state.moveY > 0 ? 'down' : 'up';
      }
      
      this.performSwipe(direction);
    } else {
      // Animate card back to center with a spring effect
      this.card.style.transition = 'transform 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275)';
      this.card.style.transform = '';
      setTimeout(() => {
        this.card.style.transition = '';
      }, 500);
    }
    
    this.state.moveX = 0;
    this.state.moveY = 0;
  }
  
  performSwipe(direction) {
    // Show the decision indicator
    this.showDecisionIndicator(direction);
    
    // Add swipe animation class
    this.card.classList.add(`swipe-${direction}`);
    
    // Call the onSwipe callback
    this.onSwipe(direction);
    
    // Reset card after animation completes
    setTimeout(() => {
      this.card.classList.remove(`swipe-${direction}`);
    }, this.transitionDuration);
  }
  
  showDecisionIndicator(direction) {
    const indicator = this.decisionIndicators[direction];
    if (indicator) {
      indicator.classList.add('visible');
      
      setTimeout(() => {
        indicator.classList.remove('visible');
      }, 800);
    }
  }
  
  setImage(imageInfo) {
    this.state.currentImageInfo = imageInfo;
    
    if (!imageInfo) {
      this.card.innerHTML = '<div class="no-images-message">No more images available.</div>';
      return;
    }
    
    const cardImage = this.card.querySelector('img');
    if (!cardImage) return;
    
    // Preload the image
    const preloadImg = new Image();
    preloadImg.onload = () => {
      cardImage.src = imageInfo.path;
      // Add a subtle fade-in effect
      cardImage.style.opacity = 0;
      setTimeout(() => {
        cardImage.style.opacity = 1;
      }, 50);
    };
    preloadImg.src = imageInfo.path;
  }
  
  showLoading() {
    this.card.classList.add('loading');
  }
  
  hideLoading() {
    this.card.classList.remove('loading');
  }
}

export default SwipeCard;
