// Image cache service - Handles lazy caching of thumbnails with LRU eviction
// TRACES: UR-007 | DR-016

import { convertFileSrc } from "@tauri-apps/api/core";
import { commands } from "$lib/api/bindings";

/**
 * Statistics about the thumbnail cache
 */
export interface ImageCacheStats {
  totalSizeBytes: number;
  itemCount: number;
  limitBytes: number;
}

/**
 * Get an image URL, checking cache first then falling back to server.
 * Triggers background caching if not cached.
 *
 * @param serverUrl - The Jellyfin server base URL
 * @param itemId - The Jellyfin item ID
 * @param imageType - The image type (Primary, Backdrop, etc.)
 * @param options - Image options (maxWidth, maxHeight, quality, tag)
 * @returns The image URL (local asset URL if cached, server URL otherwise)
 */
export async function getCachedImageUrl(
  serverUrl: string,
  itemId: string,
  imageType: string = "Primary",
  options: {
    maxWidth?: number;
    maxHeight?: number;
    quality?: number;
    tag?: string;
  } = {}
): Promise<string> {
  const tag = options.tag || "default";

  // Try to get cached version
  try {
    const cachedPath = await commands.thumbnailGetCached(itemId, imageType, tag);

    if (cachedPath) {
      // Convert file path to asset URL for Tauri
      return convertFileSrc(cachedPath);
    }
  } catch (e) {
    console.debug("Failed to check thumbnail cache:", e);
  }

  // Build server URL
  const params = new URLSearchParams();
  if (options.maxWidth) params.set("maxWidth", options.maxWidth.toString());
  if (options.maxHeight) params.set("maxHeight", options.maxHeight.toString());
  if (options.quality) params.set("quality", options.quality.toString());
  if (options.tag) params.set("tag", options.tag);

  const serverImageUrl = `${serverUrl}/Items/${itemId}/Images/${imageType}?${params.toString()}`;

  // Trigger background caching (fire and forget)
  commands.thumbnailSave(itemId, imageType, tag, serverImageUrl).catch((e) => {
    // Silently fail - caching is best-effort
    console.debug("Background thumbnail cache failed:", e);
  });

  // Return server URL for immediate display
  return serverImageUrl;
}

/**
 * Get thumbnail cache statistics
 */
export async function getCacheStats(): Promise<ImageCacheStats> {
  return commands.thumbnailGetStats();
}

/**
 * Set cache storage limit in bytes
 *
 * @param limitBytes - The maximum cache size in bytes (0 = unlimited)
 */
export async function setCacheLimit(limitBytes: number): Promise<void> {
  await commands.thumbnailSetLimit(limitBytes);
}

/**
 * Clear all cached thumbnails
 */
export async function clearCache(): Promise<void> {
  await commands.thumbnailClearCache();
}

/**
 * Delete cached thumbnails for a specific item
 *
 * @param itemId - The Jellyfin item ID
 */
export async function deleteItemCache(itemId: string): Promise<void> {
  await commands.thumbnailDeleteItem(itemId);
}

/**
 * Format bytes to human-readable string
 *
 * @param bytes - Number of bytes
 * @returns Human-readable string (e.g., "1.5 GB")
 */
export function formatBytes(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  if (bytes < 1024 * 1024 * 1024)
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
}

/**
 * Convert gigabytes to bytes
 */
export function gbToBytes(gb: number): number {
  return gb * 1024 * 1024 * 1024;
}

/**
 * Convert bytes to gigabytes
 */
export function bytesToGb(bytes: number): number {
  return bytes / (1024 * 1024 * 1024);
}
