import { apiClient } from '@/services/api/client';
import { AxiosError } from 'axios';

// FE-PAGE-014: Add Notifications page - Notification Service
// FE-API-009: Notifications service integration

export interface Notification {
  id: string;
  user_id: string;
  type:
    | 'new_message'
    | 'track_uploaded'
    | 'user_mentioned'
    | 'system'
    | 'friend_request'
    | 'conversation_invite'
    | 'playlist_collaborator_added'
    | 'playlist_track_added'
    | 'playlist_updated'
    | string; // Allow for future types
  title: string;
  content: string;
  link?: string;
  read: boolean;
  created_at: string;
  metadata?: Record<string, unknown>; // Additional data for specific notification types
}

export interface GetNotificationsParams {
  read?: boolean; // true = only read, false = only unread, undefined = all
  type?: string;
  page?: number;
  limit?: number;
}

export interface NotificationsResponse {
  notifications: Notification[];
  total?: number;
  page?: number;
  limit?: number;
  totalPages?: number;
  unreadCount?: number;
}

/**
 * Get notifications for the current user
 * @param params Query parameters for filtering and pagination
 * @returns Notifications response with pagination info
 * @throws Error if the request fails
 */
export async function getNotifications(
  params?: GetNotificationsParams,
): Promise<NotificationsResponse> {
  try {
    const queryParams = new URLSearchParams();
    if (params?.read !== undefined) {
      queryParams.append('read', params.read.toString());
    }
    if (params?.type) {
      queryParams.append('type', params.type);
    }
    if (params?.page) {
      queryParams.append('page', params.page.toString());
    }
    if (params?.limit) {
      queryParams.append('limit', params.limit.toString());
    }

    const response = await apiClient.get<{
      notifications: Notification[];
      total?: number;
      page?: number;
      limit?: number;
      totalPages?: number;
      unread_count?: number;
    }>(`/notifications?${queryParams.toString()}`);

    return {
      notifications: response.data.notifications || [],
      total: response.data.total,
      page: response.data.page || params?.page || 1,
      limit: response.data.limit || params?.limit || 20,
      totalPages: response.data.totalPages,
      unreadCount: response.data.unread_count,
    };
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to fetch notifications',
      );
    }
    throw error;
  }
}

/**
 * Mark a notification as read
 * @param notificationId The ID of the notification to mark as read
 * @throws Error if the request fails
 */
export async function markNotificationAsRead(
  notificationId: string,
): Promise<void> {
  try {
    await apiClient.post(`/notifications/${notificationId}/read`);
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to mark notification as read',
      );
    }
    throw error;
  }
}

/**
 * Mark all notifications as read for the current user
 * @throws Error if the request fails
 */
export async function markAllNotificationsAsRead(): Promise<void> {
  try {
    await apiClient.post('/notifications/read-all');
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to mark all notifications as read',
      );
    }
    throw error;
  }
}

/**
 * Get unread notifications count for the current user
 * @returns The number of unread notifications
 * @throws Error if the request fails
 */
export async function getUnreadCount(): Promise<number> {
  try {
    const response = await apiClient.get<{ count: number }>(
      '/notifications/unread-count',
    );
    return response.data.count || 0;
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to get unread count',
      );
    }
    throw error;
  }
}

/**
 * Delete a notification
 * @param notificationId The ID of the notification to delete
 * @throws Error if the request fails
 */
export async function deleteNotification(
  notificationId: string,
): Promise<void> {
  try {
    await apiClient.delete(`/notifications/${notificationId}`);
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to delete notification',
      );
    }
    throw error;
  }
}

/**
 * Delete all notifications for the current user
 * @throws Error if the request fails
 */
export async function deleteAllNotifications(): Promise<void> {
  try {
    await apiClient.delete('/notifications');
  } catch (error) {
    if (error instanceof AxiosError) {
      throw new Error(
        error.response?.data?.error ||
          error.message ||
          'Failed to delete all notifications',
      );
    }
    throw error;
  }
}
