import { API_BASE_URL } from "../config/api";

export interface Notification {
  id: string;
  userId: string;
  title: string;
  message: string;
  type: "payment_reminder" | "attendance" | "promotion" | "system";
  read: boolean;
  createdAt: Date;
}

interface ApiResponse<T> {
  success: boolean;
  data: T;
  meta?: {
    timestamp: string;
    count?: number;
  };
}

/**
 * Fetch all notifications for the authenticated user
 */
export async function fetchNotifications(
  token: string | null,
): Promise<Notification[]> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(`${API_BASE_URL}/api/notifications`, {
    method: "GET",
    headers,
  });

  if (!response.ok) {
    const errorText = await response.text();
    throw new Error(
      `Failed to fetch notifications: ${response.status} - ${errorText}`,
    );
  }

  const result: ApiResponse<Notification[]> = await response.json();

  if (result.success && result.data) {
    // Convert date strings to Date objects
    return result.data.map((notification) => ({
      ...notification,
      createdAt: new Date(notification.createdAt),
    }));
  }

  return [];
}

/**
 * Get unread notification count
 */
export async function fetchUnreadCount(token: string | null): Promise<number> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(
    `${API_BASE_URL}/api/notifications/unread-count`,
    {
      method: "GET",
      headers,
    },
  );

  if (!response.ok) {
    throw new Error(`Failed to fetch unread count: ${response.status}`);
  }

  const result: ApiResponse<{ count: number }> = await response.json();

  return result.success && result.data ? result.data.count : 0;
}

/**
 * Mark a notification as read
 */
export async function markAsRead(
  notificationId: string,
  token: string | null,
): Promise<Notification> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(
    `${API_BASE_URL}/api/notifications/${notificationId}`,
    {
      method: "PUT",
      headers,
    },
  );

  if (!response.ok) {
    throw new Error(`Failed to mark notification as read: ${response.status}`);
  }

  const result: ApiResponse<Notification> = await response.json();

  if (result.success && result.data) {
    return {
      ...result.data,
      createdAt: new Date(result.data.createdAt),
    };
  }

  throw new Error("Invalid response format");
}

/**
 * Mark all notifications as read
 */
export async function markAllAsRead(token: string | null): Promise<void> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(
    `${API_BASE_URL}/api/notifications/mark-all-read`,
    {
      method: "POST",
      headers,
    },
  );

  if (!response.ok) {
    throw new Error(
      `Failed to mark all notifications as read: ${response.status}`,
    );
  }
}

/**
 * Delete a notification
 */
export async function deleteNotification(
  notificationId: string,
  token: string | null,
): Promise<void> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(
    `${API_BASE_URL}/api/notifications/${notificationId}`,
    {
      method: "DELETE",
      headers,
    },
  );

  if (!response.ok) {
    throw new Error(`Failed to delete notification: ${response.status}`);
  }
}

/**
 * Save Expo push notification token
 */
export async function savePushToken(
  expoPushToken: string,
  deviceType: "ios" | "android",
  token: string | null,
): Promise<void> {
  const headers: Record<string, string> = {
    "Content-Type": "application/json",
  };

  if (token) {
    headers["Authorization"] = `Bearer ${token}`;
  }

  const response = await fetch(`${API_BASE_URL}/api/notifications/save-token`, {
    method: "POST",
    headers,
    body: JSON.stringify({ expoPushToken, deviceType }),
  });

  if (!response.ok) {
    throw new Error(`Failed to save push token: ${response.status}`);
  }
}
