import { create } from 'zustand';
import { toast } from 'react-toastify';
import {
  getFavorites,
  addFavorite,
  removeFavorite,
} from '../features/reviews/services/favoriteService';
import type { Favorite } from '../features/reviews/services/favoriteService';

// Helper function to check if user is authenticated and is a customer
const isAuthenticatedCustomer = (): boolean => {
  try {
    // Tokens are in httpOnly cookies, so we only check userInfo
    // Check if user is a customer
    const userInfo = localStorage.getItem('userInfo');
    if (!userInfo) {
      return false; // No user info
    }
    
    const user = JSON.parse(userInfo);
    const role = user?.role;
    // Only customers can have favorites
    return role === 'customer' || !role;
  } catch (error) {
    return false;
  }
};

interface FavoritesState {
  favorites: Favorite[];
  favoriteRoomIds: Set<number>;
  isLoading: boolean;
  error: string | null;
  
  
  fetchFavorites: () => Promise<void>;
  addToFavorites: (roomId: number) => Promise<void>;
  removeFromFavorites: (roomId: number) => Promise<void>;
  isFavorited: (roomId: number) => boolean;
  syncGuestFavorites: () => Promise<void>;
  clearFavorites: () => void;
  
  
  loadGuestFavorites: () => void;
  saveGuestFavorite: (roomId: number) => void;
  removeGuestFavorite: (roomId: number) => void;
}

const GUEST_FAVORITES_KEY = 'guestFavorites';

const getGuestFavorites = (): number[] => {
  try {
    const stored = localStorage.getItem(GUEST_FAVORITES_KEY);
    return stored ? JSON.parse(stored) : [];
  } catch (error) {
    console.error('Error loading guest favorites:', error);
    return [];
  }
};

const setGuestFavorites = (roomIds: number[]): void => {
  try {
    localStorage.setItem(
      GUEST_FAVORITES_KEY,
      JSON.stringify(roomIds)
    );
  } catch (error) {
    console.error('Error saving guest favorites:', error);
  }
};

const useFavoritesStore = create<FavoritesState>(
  (set, get) => ({
    favorites: [],
    favoriteRoomIds: new Set(),
    isLoading: false,
    error: null,

    
    fetchFavorites: async () => {
      // Don't fetch favorites if user is not authenticated or not a customer
      if (!isAuthenticatedCustomer()) {
        set({ isLoading: false, error: null });
        return;
      }

      set({ isLoading: true, error: null });
      try {
        const response = await getFavorites();
        
        if (
          response.status === 'success' && 
          response.data
        ) {
          const favorites = response.data.favorites;
          const roomIds = new Set(
            favorites.map((f) => f.room_id)
          );
          
          set({
            favorites,
            favoriteRoomIds: roomIds,
            isLoading: false,
          });
        }
      } catch (error: unknown) {
        console.error('Error fetching favorites:', error);
        
        
        const status = (error as { response?: { status?: number } })?.response?.status;
        if (status === 401) {
          get().loadGuestFavorites();
        } else {
          set({
            error: 
              (error as { response?: { data?: { message?: string } } })?.response?.data?.message ||
              'Unable to load favorites list',
            isLoading: false,
          });
        }
      }
    },

    
    addToFavorites: async (roomId: number) => {
      // Require authentication - only logged-in customers can add favorites
      if (!isAuthenticatedCustomer()) {
        toast.error('Please login as a customer to add favorites');
        throw new Error('Authentication required');
      }

      try {
        const response = await addFavorite(roomId);
        
        if (response.status === 'success') {
          
          set((state) => {
            const newFavoriteIds = new Set(
              state.favoriteRoomIds
            );
            newFavoriteIds.add(roomId);
            
            return {
              favoriteRoomIds: newFavoriteIds,
            };
          });

          
          await get().fetchFavorites();
          
          toast.success(
            response.message || 
            'Added to favorites'
          );
        }
      } catch (error: unknown) {
        console.error('Error adding favorite:', error);
        
        // Don't fallback to guest favorites - require authentication
        const status = (error as { response?: { status?: number } })?.response?.status;
        if (status === 401 || status === 403) {
          toast.error('Please login as a customer to add favorites');
        } else {
          const message =
            (error as { response?: { data?: { message?: string } } })?.response?.data?.message ||
            'Unable to add to favorites';
          toast.error(message);
        }
        throw error; // Re-throw to let caller handle
      }
    },

    
    removeFromFavorites: async (roomId: number) => {
      // Require authentication - only logged-in customers can remove favorites
      if (!isAuthenticatedCustomer()) {
        toast.error('Please login as a customer to manage favorites');
        throw new Error('Authentication required');
      }

      try {
        const response = await removeFavorite(roomId);
        
        if (response.status === 'success') {
          
          set((state) => {
            const newFavoriteIds = new Set(
              state.favoriteRoomIds
            );
            newFavoriteIds.delete(roomId);
            
            const newFavorites = state.favorites.filter(
              (f) => f.room_id !== roomId
            );
            
            return {
              favorites: newFavorites,
              favoriteRoomIds: newFavoriteIds,
            };
          });
          
          toast.success(
            response.message || 
            'Removed from favorites'
          );
        }
      } catch (error: unknown) {
        console.error('Error removing favorite:', error);
        
        // Don't fallback to guest favorites - require authentication
        const status = (error as { response?: { status?: number } })?.response?.status;
        if (status === 401 || status === 403) {
          toast.error('Please login as a customer to manage favorites');
        } else {
          const message =
            (error as { response?: { data?: { message?: string } } })?.response?.data?.message ||
            'Unable to remove from favorites';
          toast.error(message);
        }
        throw error; // Re-throw to let caller handle
      }
    },

    
    isFavorited: (roomId: number) => {
      return get().favoriteRoomIds.has(roomId);
    },

    
    syncGuestFavorites: async () => {
      // Don't sync favorites if user is not authenticated or not a customer
      if (!isAuthenticatedCustomer()) {
        return;
      }

      const guestFavorites = getGuestFavorites();
      
      if (guestFavorites.length === 0) {
        return;
      }

      try {
        
        await Promise.all(
          guestFavorites.map((roomId) =>
            addFavorite(roomId).catch(() => {
              
            })
          )
        );

        
        localStorage.removeItem(GUEST_FAVORITES_KEY);
        
        
        await get().fetchFavorites();
        
        toast.success(
          'Favorites list synced'
        );
      } catch (error) {
        console.error(
          'Error syncing guest favorites:', 
          error
        );
      }
    },

    
    clearFavorites: () => {
      set({
        favorites: [],
        favoriteRoomIds: new Set(),
        error: null,
      });
      localStorage.removeItem(GUEST_FAVORITES_KEY);
    },

    
    loadGuestFavorites: () => {
      const guestFavorites = getGuestFavorites();
      set({
        favoriteRoomIds: new Set(guestFavorites),
        isLoading: false,
      });
    },

    saveGuestFavorite: (roomId: number) => {
      const guestFavorites = getGuestFavorites();
      
      if (!guestFavorites.includes(roomId)) {
        const updated = [...guestFavorites, roomId];
        setGuestFavorites(updated);
        
        set((state) => {
          const newFavoriteIds = new Set(
            state.favoriteRoomIds
          );
          newFavoriteIds.add(roomId);
          return { favoriteRoomIds: newFavoriteIds };
        });
      }
    },

    removeGuestFavorite: (roomId: number) => {
      const guestFavorites = getGuestFavorites();
      const updated = guestFavorites.filter(
        (id) => id !== roomId
      );
      setGuestFavorites(updated);
      
      set((state) => {
        const newFavoriteIds = new Set(
          state.favoriteRoomIds
        );
        newFavoriteIds.delete(roomId);
        return { favoriteRoomIds: newFavoriteIds };
      });
    },
  })
);

export default useFavoritesStore;
