import { ApiRequestOptions } from '../hooks/useApi';

// ============================================================================
// TYPES & INTERFACES
// ============================================================================

export interface FileInfo {
  id: string;
  mandateId: string;
  fileName: string;
  mimeType: string;
  fileHash: string;
  fileSize: number;
  creationDate: number;
  [key: string]: any; // Allow additional properties
}

export interface AttributeDefinition {
  name: string;
  label: string;
  type: 'string' | 'number' | 'date' | 'boolean' | 'enum';
  sortable?: boolean;
  filterable?: boolean;
  searchable?: boolean;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  filterOptions?: string[];
}

export interface PaginationParams {
  page?: number;
  pageSize?: number;
  sort?: Array<{ field: string; direction: 'asc' | 'desc' }>;
  filters?: Record<string, any>;
  search?: string;
}

export interface PaginatedResponse<T> {
  items: T[];
  pagination?: {
    currentPage: number;
    pageSize: number;
    totalItems: number;
    totalPages: number;
  };
}

// Type for the request function passed to API functions
export type ApiRequestFunction = (options: ApiRequestOptions<any>) => Promise<any>;

// ============================================================================
// API REQUEST FUNCTIONS
// ============================================================================

/**
 * Fetch file attributes from backend
 * Endpoint: GET /api/attributes/FileItem
 */
export async function fetchFileAttributes(request: ApiRequestFunction): Promise<AttributeDefinition[]> {
  const data = await request({
    url: '/api/attributes/FileItem',
    method: 'get'
  });
  
  // Handle different response formats
  if (Array.isArray(data)) {
    return data;
  }
  if (data && typeof data === 'object' && 'attributes' in data && Array.isArray(data.attributes)) {
    return data.attributes;
  }
  
  // Try to find any array property in the response
  if (data && typeof data === 'object') {
    const keys = Object.keys(data);
    for (const key of keys) {
      if (Array.isArray((data as any)[key])) {
        return (data as any)[key];
      }
    }
  }
  
  return [];
}

/**
 * Fetch list of files with optional pagination
 * Endpoint: GET /api/files/list
 */
export async function fetchFiles(
  request: ApiRequestFunction,
  params?: PaginationParams
): Promise<PaginatedResponse<FileInfo> | FileInfo[]> {
  const requestParams: any = {};
  
  // Build pagination object if provided
  if (params) {
    const paginationObj: any = {};
    
    if (params.page !== undefined) paginationObj.page = params.page;
    if (params.pageSize !== undefined) paginationObj.pageSize = params.pageSize;
    if (params.sort) paginationObj.sort = params.sort;
    if (params.filters) paginationObj.filters = params.filters;
    if (params.search) paginationObj.search = params.search;
    
    if (Object.keys(paginationObj).length > 0) {
      requestParams.pagination = JSON.stringify(paginationObj);
    }
  }
  
  const data = await request({
    url: '/api/files/list',
    method: 'get',
    params: requestParams
  });
  
  return data;
}

/**
 * Fetch a single file by ID
 * Endpoint: GET /api/files/{fileId}
 */
export async function fetchFileById(
  request: ApiRequestFunction,
  fileId: string
): Promise<FileInfo | null> {
  try {
    const data = await request({
      url: `/api/files/${fileId}`,
      method: 'get'
    });
    return data || null;
  } catch (error: any) {
    console.error('Error fetching file by ID:', error);
    return null;
  }
}

/**
 * Update a file
 * Endpoint: PUT /api/files/{fileId}
 */
export async function updateFile(
  request: ApiRequestFunction,
  fileId: string,
  fileData: Partial<FileInfo>
): Promise<FileInfo> {
  return await request({
    url: `/api/files/${fileId}`,
    method: 'put',
    data: fileData
  });
}

/**
 * Delete a file
 * Endpoint: DELETE /api/files/{fileId}
 */
export async function deleteFile(
  request: ApiRequestFunction,
  fileId: string
): Promise<void> {
  await request({
    url: `/api/files/${fileId}`,
    method: 'delete'
  });
}

/**
 * Delete multiple files
 * Endpoint: DELETE /api/files/{fileId} (called multiple times)
 */
export async function deleteFiles(
  request: ApiRequestFunction,
  fileIds: string[]
): Promise<Array<{ success: boolean; fileId: string; error?: any }>> {
  const uniqueIds = [...new Set(fileIds.filter(Boolean))];
  if (uniqueIds.length === 0) return [];
  await request({
    url: '/api/files/batch-delete',
    method: 'post',
    data: { fileIds: uniqueIds }
  });
  return uniqueIds.map(fileId => ({ success: true, fileId }));
}

export async function deleteFolders(
  request: ApiRequestFunction,
  folderIds: string[],
  recursiveFolders: boolean = true
): Promise<{ deletedFiles: number; deletedFolders: number }> {
  const uniqueIds = [...new Set(folderIds.filter(Boolean))];
  if (uniqueIds.length === 0) return { deletedFiles: 0, deletedFolders: 0 };
  return await request({
    url: '/api/files/batch-delete',
    method: 'post',
    data: { folderIds: uniqueIds, recursiveFolders }
  });
}

// ============================================================================
// FOLDER API FUNCTIONS
// ============================================================================

export interface FolderInfo {
  id: string;
  name: string;
  parentId: string | null;
  fileCount?: number;
  mandateId?: string;
  featureInstanceId?: string;
  createdAt?: number;
}

export async function fetchFolders(
  request: ApiRequestFunction,
  parentId?: string | null
): Promise<FolderInfo[]> {
  const params: any = {};
  if (parentId !== undefined && parentId !== null) {
    params.parentId = parentId;
  }
  const data = await request({
    url: '/api/files/folders',
    method: 'get',
    params,
  });
  return Array.isArray(data) ? data : [];
}

export async function createFolder(
  request: ApiRequestFunction,
  name: string,
  parentId?: string | null
): Promise<FolderInfo> {
  return await request({
    url: '/api/files/folders',
    method: 'post',
    data: { name, parentId: parentId || null },
  });
}

export async function renameFolder(
  request: ApiRequestFunction,
  folderId: string,
  name: string
): Promise<any> {
  return await request({
    url: `/api/files/folders/${folderId}`,
    method: 'put',
    data: { name },
  });
}

export async function deleteFolderApi(
  request: ApiRequestFunction,
  folderId: string,
  recursive: boolean = false
): Promise<any> {
  return await request({
    url: `/api/files/folders/${folderId}`,
    method: 'delete',
    params: { recursive },
  });
}

export async function moveFolder(
  request: ApiRequestFunction,
  folderId: string,
  targetParentId: string | null
): Promise<any> {
  return await request({
    url: `/api/files/folders/${folderId}/move`,
    method: 'post',
    data: { targetParentId },
  });
}

export async function moveFile(
  request: ApiRequestFunction,
  fileId: string,
  targetFolderId: string | null
): Promise<any> {
  return await request({
    url: `/api/files/${fileId}/move`,
    method: 'post',
    data: { targetFolderId },
  });
}

// Note: The following operations require special handling (FormData, blob responses)
// and should use the api instance directly from '../api' rather than the request function:
// - uploadFile: Requires FormData with multipart/form-data
// - downloadFile: Requires blob responseType
// - previewFile: Requires flexible responseType (json or blob)
// These are kept in the hooks for now due to their special requirements

