import { create } from 'zustand';
import type { Notification } from '../types/notification';
import { notificationsService } from '../services/notifications';

interface NotificationsState {
  notifications: Notification[];
  unreadCount: number;
  cursor: string | null;
  hasMore: boolean;
  isLoading: boolean;
  isLoadingMore: boolean;
  error: string | null;
  filter: 'all' | 'unread';

  setFilter: (filter: 'all' | 'unread') => void;
  fetchNotifications: (refresh?: boolean) => Promise<void>;
  fetchMoreNotifications: () => Promise<void>;
  fetchUnreadCount: () => Promise<void>;
  markAsRead: (id: string) => Promise<void>;
  markAllAsRead: () => Promise<void>;
  clearError: () => void;
}

export const useNotificationsStore = create<NotificationsState>((set, get) => ({
  notifications: [],
  unreadCount: 0,
  cursor: null,
  hasMore: false,
  isLoading: false,
  isLoadingMore: false,
  error: null,
  filter: 'all',

  setFilter: (filter) => {
    set({ filter, notifications: [], cursor: null, hasMore: false });
    get().fetchNotifications(true);
  },

  fetchNotifications: async (refresh = false) => {
    const { filter } = get();
    set({ isLoading: true, error: null });
    try {
      const response = await notificationsService.getNotifications({
        limit: 20,
        isRead: filter === 'unread' ? false : undefined,
      });
      set({
        notifications: response.data,
        cursor: response.nextCursor ?? null,
        hasMore: response.hasMore ?? false,
        isLoading: false,
      });
    } catch (err) {
      set({
        error: err instanceof Error ? err.message : 'Ошибка загрузки',
        isLoading: false,
      });
    }
  },

  fetchMoreNotifications: async () => {
    const { cursor, hasMore, isLoadingMore, filter } = get();
    if (!cursor || !hasMore || isLoadingMore) return;

    set({ isLoadingMore: true });
    try {
      const response = await notificationsService.getNotifications({
        cursor,
        limit: 20,
        isRead: filter === 'unread' ? false : undefined,
      });
      set((state) => ({
        notifications: [...state.notifications, ...response.data],
        cursor: response.nextCursor ?? null,
        hasMore: response.hasMore ?? false,
        isLoadingMore: false,
      }));
    } catch {
      set({ isLoadingMore: false });
    }
  },

  fetchUnreadCount: async () => {
    try {
      const { count } = await notificationsService.getUnreadCount();
      set({ unreadCount: count });
    } catch {
      // ignore
    }
  },

  markAsRead: async (id) => {
    try {
      await notificationsService.markAsRead(id);
      set((state) => ({
        notifications: state.notifications.map((n) =>
          n.id === id ? { ...n, isRead: true } : n
        ),
        unreadCount: Math.max(0, state.unreadCount - 1),
      }));
    } catch {
      // ignore
    }
  },

  markAllAsRead: async () => {
    try {
      await notificationsService.markAllAsRead();
      set((state) => ({
        notifications: state.notifications.map((n) => ({ ...n, isRead: true })),
        unreadCount: 0,
      }));
    } catch {
      // ignore
    }
  },

  clearError: () => set({ error: null }),
}));
