/**
 * Media Gallery API
 *
 * API client functions for managing media files and albums.
 */

import apiClient from './client';

// ============================================================================
// Types
// ============================================================================

/**
 * Album for organizing media files
 */
export interface Album {
  id: number;
  name: string;
  description: string;
  cover_image: number | null;
  file_count: number;
  cover_url: string | null;
  created_at: string;
  updated_at: string;
}

/**
 * Media file (uploaded image)
 */
export interface MediaFile {
  id: number;
  url: string;
  filename: string;
  alt_text: string;
  file_size: number;
  width: number | null;
  height: number | null;
  mime_type: string;
  album: number | null;
  album_name: string | null;
  created_at: string;
}

/**
 * Storage usage statistics
 */
export interface StorageUsage {
  bytes_used: number;
  bytes_total: number;
  file_count: number;
  percent_used: number;
  used_display: string;
  total_display: string;
}

/**
 * Album creation/update payload
 */
export interface AlbumPayload {
  name: string;
  description?: string;
  cover_image?: number | null;
}

/**
 * Media file update payload (can't change the actual file)
 */
export interface MediaFileUpdatePayload {
  alt_text?: string;
  album?: number | null;
}

// ============================================================================
// Album API
// ============================================================================

/**
 * List all albums
 */
export async function listAlbums(): Promise<Album[]> {
  const response = await apiClient.get('/albums/');
  return response.data;
}

/**
 * Get a single album
 */
export async function getAlbum(id: number): Promise<Album> {
  const response = await apiClient.get(`/albums/${id}/`);
  return response.data;
}

/**
 * Create a new album
 */
export async function createAlbum(data: AlbumPayload): Promise<Album> {
  const response = await apiClient.post('/albums/', data);
  return response.data;
}

/**
 * Update an album
 */
export async function updateAlbum(id: number, data: Partial<AlbumPayload>): Promise<Album> {
  const response = await apiClient.patch(`/albums/${id}/`, data);
  return response.data;
}

/**
 * Delete an album (files are moved to uncategorized)
 */
export async function deleteAlbum(id: number): Promise<void> {
  await apiClient.delete(`/albums/${id}/`);
}

// ============================================================================
// Media File API
// ============================================================================

/**
 * List media files
 * @param albumId - Filter by album ID, 'null' for uncategorized, undefined for all
 */
export async function listMediaFiles(albumId?: number | 'null'): Promise<MediaFile[]> {
  const params = albumId !== undefined ? { album: albumId } : {};
  const response = await apiClient.get('/media/', { params });
  return response.data;
}

/**
 * Get a single media file
 */
export async function getMediaFile(id: number): Promise<MediaFile> {
  const response = await apiClient.get(`/media/${id}/`);
  return response.data;
}

/**
 * Upload a new media file
 */
export async function uploadMediaFile(
  file: File,
  albumId?: number | null,
  altText?: string
): Promise<MediaFile> {
  const formData = new FormData();
  formData.append('file', file);
  if (albumId !== undefined && albumId !== null) {
    formData.append('album', albumId.toString());
  }
  if (altText) {
    formData.append('alt_text', altText);
  }

  const response = await apiClient.post('/media/', formData, {
    headers: {
      'Content-Type': 'multipart/form-data',
    },
  });
  return response.data;
}

/**
 * Update a media file (alt text, album assignment)
 */
export async function updateMediaFile(
  id: number,
  data: MediaFileUpdatePayload
): Promise<MediaFile> {
  const response = await apiClient.patch(`/media/${id}/`, data);
  return response.data;
}

/**
 * Delete a media file
 */
export async function deleteMediaFile(id: number): Promise<void> {
  await apiClient.delete(`/media/${id}/`);
}

/**
 * Move multiple files to an album
 */
export async function bulkMoveFiles(
  fileIds: number[],
  albumId: number | null
): Promise<{ updated: number }> {
  const response = await apiClient.post('/media/bulk_move/', {
    file_ids: fileIds,
    album_id: albumId,
  });
  return response.data;
}

/**
 * Delete multiple files
 */
export async function bulkDeleteFiles(fileIds: number[]): Promise<{ deleted: number }> {
  const response = await apiClient.post('/media/bulk_delete/', {
    file_ids: fileIds,
  });
  return response.data;
}

// ============================================================================
// Storage Usage API
// ============================================================================

/**
 * Get storage usage statistics
 */
export async function getStorageUsage(): Promise<StorageUsage> {
  const response = await apiClient.get('/storage-usage/');
  return response.data;
}

// ============================================================================
// Utility Functions
// ============================================================================

/**
 * Format file size in human-readable format
 */
export function formatFileSize(bytes: number): string {
  if (bytes >= 1024 * 1024 * 1024) {
    return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GB`;
  } else if (bytes >= 1024 * 1024) {
    return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
  } else if (bytes >= 1024) {
    return `${(bytes / 1024).toFixed(1)} KB`;
  }
  return `${bytes} B`;
}

/**
 * Check if a file type is allowed
 */
export function isAllowedFileType(file: File): boolean {
  const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
  return allowedTypes.includes(file.type);
}

/**
 * Get allowed file types for input accept attribute
 */
export function getAllowedFileTypes(): string {
  return 'image/jpeg,image/png,image/gif,image/webp';
}

/**
 * Maximum file size in bytes (10 MB)
 */
export const MAX_FILE_SIZE = 10 * 1024 * 1024;

/**
 * Check if file size is within limits
 */
export function isFileSizeAllowed(file: File): boolean {
  return file.size <= MAX_FILE_SIZE;
}
