// Favorites service - Handles toggling favorite status with optimistic updates
// TRACES: UR-017, UR-068 | DR-021, DR-119

import { get } from "svelte/store";
import { commands } from "$lib/api/bindings";
import { auth } from "$lib/stores/auth";
import { isConnected } from "$lib/stores/connectivity";
import { setFavorite } from "$lib/stores/favorites";

/**
 * Toggle the favorite status of an item.
 *
 * Flow:
 * 1. Update local database immediately (optimistic update)
 * 2. Sync to Jellyfin server
 * 3. Mark as synced on success, or leave pending_sync flag on failure
 *
 * @param itemId - The Jellyfin item ID
 * @param currentIsFavorite - The current favorite status
 * @returns The new favorite status
 * @throws Error if not authenticated or database update fails
 */
export async function toggleFavorite(
  itemId: string,
  currentIsFavorite: boolean
): Promise<boolean> {
  const userId = auth.getUserId();
  if (!userId) {
    throw new Error("Not authenticated");
  }

  const newIsFavorite = !currentIsFavorite;

  // 1. Update local database first (optimistic update)
  await commands.storageToggleFavorite(userId, itemId, newIsFavorite);

  // Publish to every mounted view at once, so the heart on a card, the detail
  // page and the Favourites grid never disagree. TRACES: UR-068 | DR-119
  setFavorite(itemId, newIsFavorite);

  // 2. Sync to Jellyfin server.
  //
  // Only attempt this when we're actually connected. When offline, the server
  // call can hang on a long network timeout rather than failing fast — which
  // blocks the caller (and leaves the favorite button greyed out with a wait
  // cursor) until the request finally gives up, effectively only recovering
  // once we're back online. The local DB write above keeps the pending_sync
  // flag set, so the change still syncs later; we just don't block the UI on
  // an unreachable server here.
  if (get(isConnected)) {
    try {
      const repo = auth.getRepository();
      if (newIsFavorite) {
        await repo.markFavorite(itemId);
      } else {
        await repo.unmarkFavorite(itemId);
      }

      // 3. Mark as synced
      await commands.storageMarkSynced(userId, itemId);
    } catch (error) {
      console.error("Failed to sync favorite to server:", error);
      // Favorite is stored locally and will be synced later
      // via sync queue (when implemented)
    }
  }

  return newIsFavorite;
}
