import { useState, useCallback, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { api } from '@/lib/api/client';
import { toast } from 'sonner';

interface WishlistItem {
  product_id: number;
  name: string;
  slug: string;
  price: string;
  regular_price?: string;
  sale_price?: string;
  image?: string;
  on_sale?: boolean;
  stock_status?: string;
  type?: string;
  added_at: string;
}

const GUEST_WISHLIST_KEY = 'woonoow_guest_wishlist';

export function useWishlist() {
  const queryClient = useQueryClient();
  const [guestIds, setGuestIds] = useState<Set<number>>(() => {
    if (typeof window !== 'undefined' && !(window as any).woonoowCustomer?.user?.isLoggedIn) {
      try {
        const stored = localStorage.getItem(GUEST_WISHLIST_KEY);
        if (stored) {
          const ids = JSON.parse(stored) as number[];
          return new Set(ids);
        }
      } catch (error) {
        console.error('Failed to load guest wishlist:', error);
      }
    }
    return new Set<number>();
  });

  // Check if wishlist is enabled (default true if not explicitly set to false)
  const settings = (window as any).woonoowCustomer?.settings;
  const isEnabled = settings?.wishlist_enabled !== false;
  const isLoggedIn = (window as any).woonoowCustomer?.user?.isLoggedIn;

  // Save guest wishlist helper
  const saveGuestWishlist = useCallback((ids: Set<number>) => {
    try {
      localStorage.setItem(GUEST_WISHLIST_KEY, JSON.stringify(Array.from(ids)));
      setGuestIds(ids);
    } catch (error) {
      console.error('Failed to save guest wishlist:', error);
    }
  }, []);

  // Fetch wishlist items (Server)
  const { data: serverItems = [], isLoading: isServerLoading } = useQuery({
    queryKey: ['wishlist'],
    queryFn: async () => {
      return await api.get<WishlistItem[]>('/account/wishlist');
    },
    enabled: isEnabled && isLoggedIn,
    staleTime: 60 * 1000, // 1 minute cache
    retry: 1,
  });

  // Calculate merged state
  const items = isLoggedIn ? serverItems : []; // Guest items not stored as full objects here, usually handled by fetching products by ID elsewhere
  const isLoading = isLoggedIn ? isServerLoading : false;

  // Compute set of IDs for O(1) lookup
  const productIds = useMemo(() => {
    if (isLoggedIn) {
      return new Set(serverItems.map(item => item.product_id));
    }
    return guestIds;
  }, [isLoggedIn, serverItems, guestIds]);

  // Mutations
  const addMutation = useMutation({
    mutationFn: async (productId: number) => {
      return await api.post('/account/wishlist', { product_id: productId });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['wishlist'] });
      toast.success('Added to wishlist');
    },
    onError: (error: any) => {
      const message = error?.message || 'Failed to add to wishlist';
      toast.error(message);
    }
  });

  const removeMutation = useMutation({
    mutationFn: async (productId: number) => {
      return await api.delete(`/account/wishlist/${productId}`);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['wishlist'] });
      toast.success('Removed from wishlist');
    },
    onError: () => {
      toast.error('Failed to remove from wishlist');
    }
  });

  const addToWishlist = useCallback(async (productId: number) => {
    if (!isLoggedIn) {
      const newIds = new Set(guestIds);
      newIds.add(productId);
      saveGuestWishlist(newIds);
      toast.success('Added to wishlist');
      return true;
    }

    await addMutation.mutateAsync(productId);
    return true;
  }, [isLoggedIn, guestIds, saveGuestWishlist, addMutation]);

  const removeFromWishlist = useCallback(async (productId: number) => {
    if (!isLoggedIn) {
      const newIds = new Set(guestIds);
      newIds.delete(productId);
      saveGuestWishlist(newIds);
      toast.success('Removed from wishlist');
      return true;
    }

    await removeMutation.mutateAsync(productId);
    return true;
  }, [isLoggedIn, guestIds, saveGuestWishlist, removeMutation]);

  const toggleWishlist = useCallback(async (productId: number) => {
    if (productIds.has(productId)) {
      return await removeFromWishlist(productId);
    } else {
      return await addToWishlist(productId);
    }
  }, [productIds, addToWishlist, removeFromWishlist]);

  const isInWishlist = useCallback((productId: number) => {
    return productIds.has(productId);
  }, [productIds]);

  return {
    items,
    isLoading,
    isEnabled,
    isLoggedIn,
    count: productIds.size,
    productIds,
    addToWishlist,
    removeFromWishlist,
    toggleWishlist,
    isInWishlist,
    refresh: () => queryClient.invalidateQueries({ queryKey: ['wishlist'] }),
  };
}
