/**
 * Cache Invalidation Service
 * Handles automatic cache invalidation when data is updated
 */

import { cache, cacheKeys } from './cache';

export interface CacheInvalidationOptions {
  productId?: string;
  categoryId?: number;
  slug?: string;
  invalidateAll?: boolean;
}

class CacheInvalidationService {
  private static instance: CacheInvalidationService;

  private constructor() {}

  static getInstance(): CacheInvalidationService {
    if (!CacheInvalidationService.instance) {
      CacheInvalidationService.instance = new CacheInvalidationService();
    }
    return CacheInvalidationService.instance;
  }

  /**
   * Invalidate product-related cache entries
   */
  invalidateProduct(options: CacheInvalidationOptions): void {
    const { productId, slug, categoryId } = options;

    // Invalidate specific product cache
    if (slug) {
      cache.delete(cacheKeys.product(slug));
    }

    // Invalidate all product listings that might contain this product
    this.invalidateProductListings(categoryId);

    // Invalidate featured products that might contain this product
    this.invalidateFeaturedProducts(categoryId);

    // Show notification to user
    this.showNotification('Product updated! Data refreshed.');

    console.log('Cache invalidated for product:', { productId, slug, categoryId });
  }

  /**
   * Invalidate category-related cache entries
   */
  invalidateCategory(categoryId?: number): void {
    // Invalidate categories cache
    cache.delete(cacheKeys.categories());

    // Invalidate product listings for this category
    this.invalidateProductListings(categoryId);

    // Invalidate featured products for this category
    this.invalidateFeaturedProducts(categoryId);

    this.showNotification('Category updated! Data refreshed.');

    console.log('Cache invalidated for category:', categoryId);
  }

  /**
   * Invalidate all product listings
   */
  private invalidateProductListings(categoryId?: number): void {
    // Get all localStorage keys
    const keys = Object.keys(localStorage);
    
    // Find and remove all product listing cache entries
    keys.forEach(key => {
      if (key.startsWith('cache_products_')) {
        // If specific category, only invalidate that category's listings
        if (categoryId) {
          const keyContent = key.replace('cache_products_', '');
          if (keyContent.includes(`category_id=${categoryId}`)) {
            localStorage.removeItem(key);
          }
        } else {
          // Invalidate all product listings
          localStorage.removeItem(key);
        }
      }
    });
  }

  /**
   * Invalidate featured products cache
   */
  private invalidateFeaturedProducts(categoryId?: number): void {
    if (categoryId) {
      cache.delete(cacheKeys.featuredProducts(categoryId));
    }
    // Also invalidate "all categories" featured products
    cache.delete(cacheKeys.featuredProducts());
  }

  /**
   * Invalidate home page cache
   */
  invalidateHomePage(): void {
    cache.delete(cacheKeys.homePageData());
    console.log('Home page cache invalidated');
  }

  /**
   * Complete cache clear
   */
  invalidateAll(): void {
    cache.clear();
    this.showNotification('All data refreshed!');
    console.log('All cache invalidated');
  }

  /**
   * Show a simple notification to the user
   */
  private showNotification(message: string): void {
    // Create a simple toast notification
    if (typeof window !== 'undefined') {
      const notification = document.createElement('div');
      notification.textContent = message;
      notification.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        background: #10b981;
        color: white;
        padding: 12px 20px;
        border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        z-index: 10000;
        font-family: system-ui, -apple-system, sans-serif;
        font-size: 14px;
        transition: all 0.3s ease;
      `;
      
      document.body.appendChild(notification);
      
      // Animate in
      setTimeout(() => {
        notification.style.opacity = '1';
        notification.style.transform = 'translateY(0)';
      }, 10);
      
      // Remove after 3 seconds
      setTimeout(() => {
        notification.style.opacity = '0';
        notification.style.transform = 'translateY(-20px)';
        setTimeout(() => {
          document.body.removeChild(notification);
        }, 300);
      }, 3000);
    }
  }

  /**
   * Listen for product updates from admin panel
   * This uses localStorage events to communicate between admin and frontend
   */
  startListening(): void {
    // Listen for storage events (when admin updates products)
    window.addEventListener('storage', this.handleStorageEvent.bind(this));

    // Also listen for custom events within the same window
    window.addEventListener('productUpdated', this.handleProductUpdate.bind(this) as EventListener);
    window.addEventListener('categoryUpdated', this.handleCategoryUpdate.bind(this) as EventListener);
  }

  /**
   * Stop listening for cache invalidation events
   */
  stopListening(): void {
    window.removeEventListener('storage', this.handleStorageEvent.bind(this));
    window.removeEventListener('productUpdated', this.handleProductUpdate.bind(this) as EventListener);
    window.removeEventListener('categoryUpdated', this.handleCategoryUpdate.bind(this) as EventListener);
  }

  /**
   * Handle storage events from other tabs/windows
   */
  private handleStorageEvent(event: StorageEvent): void {
    if (event.key === 'product_updated') {
      try {
        const data = JSON.parse(event.newValue || '{}');
        this.invalidateProduct(data);
        localStorage.removeItem('product_updated'); // Clean up
      } catch (error) {
        console.warn('Failed to handle product update event:', error);
      }
    }

    if (event.key === 'category_updated') {
      try {
        const data = JSON.parse(event.newValue || '{}');
        this.invalidateCategory(data.categoryId);
        localStorage.removeItem('category_updated'); // Clean up
      } catch (error) {
        console.warn('Failed to handle category update event:', error);
      }
    }

    if (event.key === 'cache_clear_all') {
      try {
        this.invalidateAll();
        localStorage.removeItem('cache_clear_all'); // Clean up
      } catch (error) {
        console.warn('Failed to handle cache clear event:', error);
      }
    }
  }

  /**
   * Handle custom product update events
   */
  private handleProductUpdate(event: Event): void {
    const customEvent = event as CustomEvent;
    this.invalidateProduct(customEvent.detail);
  }

  /**
   * Handle custom category update events
   */
  private handleCategoryUpdate(event: Event): void {
    const customEvent = event as CustomEvent;
    this.invalidateCategory(customEvent.detail.categoryId);
  }

  /**
   * Trigger product update notification
   * Call this from admin panel after updating a product
   */
  notifyProductUpdate(options: CacheInvalidationOptions): void {
    // Store in localStorage to notify other tabs
    localStorage.setItem('product_updated', JSON.stringify(options));
    
    // Dispatch custom event for same window
    window.dispatchEvent(new CustomEvent('productUpdated', { detail: options }));
    
    // Also invalidate locally
    this.invalidateProduct(options);
  }

  /**
   * Trigger category update notification
   */
  notifyCategoryUpdate(categoryId?: number): void {
    const data = { categoryId };
    
    // Store in localStorage to notify other tabs
    localStorage.setItem('category_updated', JSON.stringify(data));
    
    // Dispatch custom event for same window
    window.dispatchEvent(new CustomEvent('categoryUpdated', { detail: data }));
    
    // Also invalidate locally
    this.invalidateCategory(categoryId);
  }
}

export const cacheInvalidation = CacheInvalidationService.getInstance();

// Auto-start listening when imported
if (typeof window !== 'undefined') {
  cacheInvalidation.startListening();
}

// Utility functions for common operations
export const invalidateCache = {
  product: (productId: string, slug?: string, categoryId?: number) => {
    cacheInvalidation.invalidateProduct({ productId, slug, categoryId });
  },
  
  category: (categoryId?: number) => {
    cacheInvalidation.invalidateCategory(categoryId);
  },
  
  homePage: () => {
    cacheInvalidation.invalidateHomePage();
  },
  
  all: () => {
    cacheInvalidation.invalidateAll();
  }
};

// Functions to call from admin panel
export const notifyUpdate = {
  product: (productId: string, slug?: string, categoryId?: number) => {
    cacheInvalidation.notifyProductUpdate({ productId, slug, categoryId });
  },
  
  category: (categoryId?: number) => {
    cacheInvalidation.notifyCategoryUpdate(categoryId);
  }
};