/**
 * Shopping Cart Module
 * Handles cart operations and localStorage management
 */

class ShoppingCart {
  constructor() {
    this.items = [];
    this.loadFromStorage();
  }

  /**
   * Add product to cart
   * @param {number} productId - Product ID
   * @param {number} quantity - Quantity (default 1)
   */
  addItem(productId, quantity = 1) {
    const product = getProductById(productId);
    if (!product) {
      console.error(`Product with ID ${productId} not found`);
      return;
    }

    const existingItem = this.items.find(item => item.productId === productId);

    if (existingItem) {
      existingItem.quantity += quantity;
    } else {
      this.items.push({
        productId: productId,
        quantity: quantity,
        addedAt: new Date().toISOString(),
      });
    }

    this.saveToStorage();
    this.notifyListeners('itemAdded', { productId, quantity });
  }

  /**
   * Remove product from cart
   * @param {number} productId - Product ID
   */
  removeItem(productId) {
    this.items = this.items.filter(item => item.productId !== productId);
    this.saveToStorage();
    this.notifyListeners('itemRemoved', { productId });
  }

  /**
   * Update item quantity
   * @param {number} productId - Product ID
   * @param {number} quantity - New quantity
   */
  updateQuantity(productId, quantity) {
    if (quantity <= 0) {
      this.removeItem(productId);
      return;
    }

    const item = this.items.find(item => item.productId === productId);
    if (item) {
      item.quantity = quantity;
      this.saveToStorage();
      this.notifyListeners('quantityUpdated', { productId, quantity });
    }
  }

  /**
   * Clear all items from cart
   */
  clear() {
    this.items = [];
    this.saveToStorage();
    this.notifyListeners('cartCleared');
  }

  /**
   * Get all cart items with product details
   * @returns {Array} Cart items with full product information
   */
  getItems() {
    return this.items.map(item => ({
      ...item,
      product: getProductById(item.productId),
    }));
  }

  /**
   * Get cart item count
   * @returns {number} Total number of items
   */
  getItemCount() {
    return this.items.reduce((total, item) => total + item.quantity, 0);
  }

  /**
   * Get cart total price
   * @returns {number} Total price in KES
   */
  getTotal() {
    return this.items.reduce((total, item) => {
      const product = getProductById(item.productId);
      return total + (product.price * item.quantity);
    }, 0);
  }

  /**
   * Check if cart is empty
   * @returns {boolean}
   */
  isEmpty() {
    return this.items.length === 0;
  }

  /**
   * Check if product is in cart
   * @param {number} productId - Product ID
   * @returns {boolean}
   */
  hasItem(productId) {
    return this.items.some(item => item.productId === productId);
  }

  /**
   * Get quantity of specific product
   * @param {number} productId - Product ID
   * @returns {number} Quantity in cart
   */
  getQuantity(productId) {
    const item = this.items.find(item => item.productId === productId);
    return item ? item.quantity : 0;
  }

  /**
   * Save cart to localStorage
   */
  saveToStorage() {
    try {
      localStorage.setItem('guarulhos_cart', JSON.stringify(this.items));
    } catch (error) {
      console.error('Error saving cart to storage:', error);
    }
  }

  /**
   * Load cart from localStorage
   */
  loadFromStorage() {
    try {
      const stored = localStorage.getItem('guarulhos_cart');
      this.items = stored ? JSON.parse(stored) : [];
    } catch (error) {
      console.error('Error loading cart from storage:', error);
      this.items = [];
    }
  }

  /**
   * Subscribe to cart changes
   * @param {Function} callback - Function to call on changes
   * @returns {Function} Unsubscribe function
   */
  subscribe(callback) {
    if (!this.listeners) {
      this.listeners = [];
    }
    this.listeners.push(callback);

    // Return unsubscribe function
    return () => {
      this.listeners = this.listeners.filter(l => l !== callback);
    };
  }

  /**
   * Notify all listeners of cart changes
   * @param {string} eventType - Type of change
   * @param {Object} data - Event data
   */
  notifyListeners(eventType, data = {}) {
    if (!this.listeners) return;

    this.listeners.forEach(callback => {
      callback({
        eventType,
        data,
        cart: this,
      });
    });
  }

  /**
   * Get cart summary for checkout
   * @returns {Object} Cart summary
   */
  getSummary() {
    return {
      items: this.getItems(),
      itemCount: this.getItemCount(),
      total: this.getTotal(),
      formattedTotal: formatPrice(this.getTotal()),
      timestamp: new Date().toISOString(),
    };
  }

  /**
   * Validate cart before checkout
   * @returns {Object} Validation result
   */
  validate() {
    const errors = [];

    if (this.isEmpty()) {
      errors.push('Cart is empty');
    }

    this.items.forEach(item => {
      if (item.quantity <= 0) {
        errors.push(`Invalid quantity for product ID ${item.productId}`);
      }

      const product = getProductById(item.productId);
      if (!product) {
        errors.push(`Product with ID ${item.productId} not found`);
      }
    });

    return {
      isValid: errors.length === 0,
      errors,
    };
  }
}

/**
 * Create a global cart instance
 */
const cart = new ShoppingCart();

/**
 * Helper function to add item to cart with feedback
 * @param {number} productId - Product ID
 * @param {number} quantity - Quantity
 */
function addToCart(productId, quantity = 1) {
  const product = getProductById(productId);
  if (product) {
    cart.addItem(productId, quantity);
    showNotification(`${product.name} added to cart!`);
  }
}

/**
 * Show notification to user
 * @param {string} message - Notification message
 * @param {string} type - Notification type (success, error, info)
 */
function showNotification(message, type = 'success') {
  // Create notification container
  const notification = document.createElement('div');
  notification.className = `notification notification-${type}`;
  notification.style.cssText = `
    position: fixed;
    bottom: 30px;
    left: 50%;
    transform: translateX(-50%);
    background-color: ${
      type === 'success' ? '#4caf50' :
      type === 'error' ? '#f44336' :
      '#2196f3'
    };
    color: white;
    padding: 18px 25px;
    border-radius: 8px;
    z-index: 3000;
    animation: slideUpFade 0.4s ease-out;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 15px;
    max-width: 90%;
    min-width: 280px;
    word-break: break-word;
  `;

  // Create message span
  const messageSpan = document.createElement('span');
  messageSpan.textContent = message;
  messageSpan.style.cssText = `
    flex: 1;
    font-size: 0.95rem;
    font-weight: 500;
  `;
  notification.appendChild(messageSpan);

  // Create close button
  const closeBtn = document.createElement('button');
  closeBtn.textContent = '✕';
  closeBtn.style.cssText = `
    background: none;
    border: none;
    color: white;
    font-size: 1.5rem;
    cursor: pointer;
    padding: 0;
    width: 25px;
    height: 25px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: opacity 0.2s ease;
    flex-shrink: 0;
  `;
  
  closeBtn.addEventListener('mouseover', () => {
    closeBtn.style.opacity = '0.7';
  });
  closeBtn.addEventListener('mouseout', () => {
    closeBtn.style.opacity = '1';
  });
  
  closeBtn.addEventListener('click', () => {
    notification.style.animation = 'slideDownFade 0.3s ease-in';
    setTimeout(() => notification.remove(), 300);
  });
  
  notification.appendChild(closeBtn);

  document.body.appendChild(notification);

  // Remove after 4 seconds automatically
  const autoRemoveTimer = setTimeout(() => {
    notification.style.animation = 'slideDownFade 0.3s ease-in';
    setTimeout(() => notification.remove(), 300);
  }, 4000);

  // Clear timer if user manually closes
  closeBtn.addEventListener('click', () => {
    clearTimeout(autoRemoveTimer);
  });
}

/**
 * Export cart for use in other modules
 */
// cart is already global, but making it explicit for module systems
