import { WCProduct } from './woocommerce';

const WISHLIST_STORAGE_KEY = 'tnl_wishlist_v1';

// In-memory fallback if localStorage quota is completely full or disabled
let memoryWishlistFallback: WCProduct[] = [];

/**
 * Compact format for storing wishlist items in localStorage to prevent QuotaExceededError
 */
interface CompactWishlistItem {
  id: number;
  name: string;
  slug: string;
  price: string;
  regular_price?: string;
  sale_price?: string;
  on_sale?: boolean;
  images: Array<{ src: string }>;
  categories?: Array<{ id: number; name: string }>;
  permalink?: string;
  rating_count?: number;
  average_rating?: string;
}

/**
 * Compacts a full WCProduct into an ultra-lean object to maximize stored items
 */
function toCompactProduct(product: WCProduct): CompactWishlistItem {
  return {
    id: Number(product.id),
    name: (product.name || '').trim(),
    slug: (product.slug || '').trim(),
    price: String(product.price ?? ''),
    regular_price: String(product.regular_price ?? ''),
    sale_price: String(product.sale_price ?? ''),
    on_sale: Boolean(product.on_sale),
    images: (product.images || []).slice(0, 1).map((img) => ({
      src: typeof img === 'string' ? img : img?.src || '',
    })),
    categories: (product.categories || []).slice(0, 2).map((cat) => ({
      id: Number(cat.id),
      name: cat.name || '',
    })),
    permalink: product.permalink || '',
    rating_count: product.rating_count || 0,
    average_rating: String(product.average_rating || '0'),
  };
}

/**
 * Reconstitutes a compact object into a valid WCProduct
 */
function fromCompactProduct(item: any): WCProduct {
  return {
    id: Number(item.id),
    name: item.name || '',
    slug: item.slug || '',
    price: String(item.price ?? ''),
    regular_price: String(item.regular_price ?? item.price ?? ''),
    sale_price: String(item.sale_price ?? ''),
    on_sale: Boolean(item.on_sale),
    images: Array.isArray(item.images) && item.images.length > 0
      ? item.images.map((img: any) => ({ src: typeof img === 'string' ? img : img?.src || '', alt: '' }))
      : [{ src: 'https://timenlife.com/wp-content/uploads/2025/01/TimeNLifeLogo-300x300-1.png', alt: '' }],
    categories: Array.isArray(item.categories) ? item.categories : [],
    permalink: item.permalink || '',
    rating_count: item.rating_count || 0,
    average_rating: String(item.average_rating || '0'),
    description: '',
    short_description: '',
  };
}

/**
 * Frees up non-critical localStorage space if quota is reached
 */
function freeUpLocalStorageSpace(): void {
  if (typeof window === 'undefined') return;
  const nonCriticalKeys = [
    'tnl_products_cache_v1',
    'tnl_categories_cache_v1',
    'tnl_recently_viewed_v1',
  ];
  nonCriticalKeys.forEach((key) => {
    try {
      localStorage.removeItem(key);
    } catch {
      // ignore
    }
  });
}

/**
 * Reads all wishlist items directly from localStorage or in-memory fallback
 */
export function getWishlistItems(): WCProduct[] {
  if (typeof window === 'undefined') return memoryWishlistFallback;
  try {
    const raw = localStorage.getItem(WISHLIST_STORAGE_KEY);
    if (!raw) return memoryWishlistFallback;
    const parsed = JSON.parse(raw);
    if (Array.isArray(parsed)) {
      const items = parsed.map(fromCompactProduct);
      memoryWishlistFallback = items;
      return items;
    }
  } catch (err) {
    console.warn('Error reading wishlist from localStorage:', err);
  }
  return memoryWishlistFallback;
}

/**
 * Saves wishlist items directly into localStorage (compacted) and notifies all subscribers.
 * Handles QuotaExceededError seamlessly.
 */
export function saveWishlistToStorage(items: WCProduct[]): void {
  memoryWishlistFallback = items;
  if (typeof window === 'undefined') return;

  const compactItems = items.map(toCompactProduct);
  const serialized = JSON.stringify(compactItems);

  // Attempt 1: Direct save
  try {
    localStorage.setItem(WISHLIST_STORAGE_KEY, serialized);
    window.dispatchEvent(new Event('tnl_wishlist_updated'));
    return;
  } catch {
    // Quota exceeded: free non-critical caches and retry
    freeUpLocalStorageSpace();
  }

  // Attempt 2: Retry after clearing non-critical caches
  try {
    localStorage.setItem(WISHLIST_STORAGE_KEY, serialized);
    window.dispatchEvent(new Event('tnl_wishlist_updated'));
    return;
  } catch {
    // Attempt 3: Save top 100 items if storage is still constrained
    try {
      const reducedItems = items.slice(0, 100).map(toCompactProduct);
      localStorage.setItem(WISHLIST_STORAGE_KEY, JSON.stringify(reducedItems));
      window.dispatchEvent(new Event('tnl_wishlist_updated'));
      return;
    } catch (e) {
      // Fallback to smoothly updating state in memory
      console.warn('LocalStorage unavailable for wishlist, using active session state.', e);
      window.dispatchEvent(new Event('tnl_wishlist_updated'));
    }
  }
}

/**
 * Checks if an item is present in the wishlist
 */
export function isItemInWishlist(productId: number | string): boolean {
  if (productId === undefined || productId === null) return false;
  const items = getWishlistItems();
  const targetId = String(productId);
  return items.some((p) => String(p.id) === targetId);
}

/**
 * Toggles an item in the wishlist (adds if absent, removes if present)
 */
export function toggleWishlist(product: WCProduct): boolean {
  if (!product || product.id === undefined) return false;
  const current = getWishlistItems();
  const targetId = String(product.id);
  const exists = current.some((p) => String(p.id) === targetId);

  let updated: WCProduct[];
  if (exists) {
    updated = current.filter((p) => String(p.id) !== targetId);
  } else {
    // Add product to top of list, allow unlimited items
    updated = [product, ...current.filter((p) => String(p.id) !== targetId)];
  }

  saveWishlistToStorage(updated);
  return !exists; // returns true if added, false if removed
}

/**
 * Removes a specific item from the wishlist
 */
export function removeFromWishlist(productId: number | string): void {
  if (productId === undefined || productId === null) return;
  const current = getWishlistItems();
  const targetId = String(productId);
  const updated = current.filter((p) => String(p.id) !== targetId);
  saveWishlistToStorage(updated);
}

/**
 * Clears all items from the wishlist
 */
export function clearWishlist(): void {
  saveWishlistToStorage([]);
}

/**
 * Subscribes to wishlist changes across all components and browser tabs
 */
export function subscribeToWishlist(callback: (items: WCProduct[]) => void): () => void {
  // Trigger initial callback with current persisted state
  callback(getWishlistItems());

  const handleUpdate = () => {
    callback(getWishlistItems());
  };

  if (typeof window !== 'undefined') {
    window.addEventListener('tnl_wishlist_updated', handleUpdate);
    window.addEventListener('storage', handleUpdate);
  }

  return () => {
    if (typeof window !== 'undefined') {
      window.removeEventListener('tnl_wishlist_updated', handleUpdate);
      window.removeEventListener('storage', handleUpdate);
    }
  };
}

