import { create } from 'zustand';
import { AppNotification } from '../types/notifications';
import { notificationService } from '../services/notificationService';

interface NotificationState {
  notifications: AppNotification[];
  unreadCount: number;
  isLoading: boolean;
  error: string | null;
  
  fetchNotifications: (userId: string, tenantId: string) => Promise<void>;
  markAsRead: (notificationId: string) => Promise<void>;
  markAllAsRead: (userId: string) => Promise<void>;
  markByEntityAsRead: (entityId: string, entityType: string, userId?: string) => Promise<void>;
  addNotification: (notification: AppNotification) => void;
}

export const useNotificationStore = create<NotificationState>((set, get) => ({
  notifications: [],
  unreadCount: 0,
  isLoading: false,
  error: null,

  fetchNotifications: async (userId: string, tenantId: string) => {
    set({ isLoading: true, error: null });
    try {
      const data = await notificationService.getNotifications(userId, tenantId);
      const unreadCount = data.filter(n => !n.isRead).length;
      set({ notifications: data, unreadCount, isLoading: false });
    } catch (error: any) {
      set({ error: error.message, isLoading: false });
    }
  },

  markAsRead: async (notificationId: string) => {
    try {
      await notificationService.markAsRead(notificationId);
      const { notifications } = get();
      const updated = notifications.map(n => 
        n.id === notificationId ? { ...n, isRead: true } : n
      );
      const unreadCount = updated.filter(n => !n.isRead).length;
      set({ notifications: updated, unreadCount });
    } catch (error) {
      console.error('Failed to mark notification as read', error);
    }
  },

  markAllAsRead: async (userId: string) => {
    try {
      await notificationService.markAllAsRead(userId);
      const { notifications } = get();
      const updated = notifications.map(n => 
        (n.recipientId === userId) 
          ? { ...n, isRead: true } 
          : n
      );
      const unreadCount = updated.filter(n => !n.isRead).length;
      set({ notifications: updated, unreadCount });
    } catch (error) {
      console.error('Failed to mark all notifications as read', error);
    }
  },

  markByEntityAsRead: async (entityId: string, entityType: string, userId?: string) => {
    try {
      await notificationService.markByEntityAsRead(entityId, entityType, userId);
      const { notifications } = get();
      const updated = notifications.map(n => 
        (n.payload?.entityId === entityId && n.payload?.entityType === entityType && (!userId || n.recipientId === userId)) 
          ? { ...n, isRead: true } 
          : n
      );
      const unreadCount = updated.filter(n => !n.isRead).length;
      set({ notifications: updated, unreadCount });
    } catch (error) {
      console.error('Failed to mark entity notifications as read', error);
    }
  },

  addNotification: (notification: AppNotification) => {
    const { notifications } = get();
    const updated = [notification, ...notifications];
    const unreadCount = updated.filter(n => !n.isRead).length;
    set({ notifications: updated, unreadCount });
  }
}));
