"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.confirmAction = confirmAction;
exports.convertDocumentPickerAssetToFile = convertDocumentPickerAssetToFile;
exports.createAvatarPickerHandler = createAvatarPickerHandler;
exports.formatFileSize = formatFileSize;
exports.getFileIcon = getFileIcon;
exports.getSafeDownloadUrl = getSafeDownloadUrl;
exports.uploadFileRaw = uploadFileRaw;
var _reactNative = require("react-native");
var _sonner = require("../../lib/sonner");
var _avatarUtils = require("./avatarUtils");
/**
 * Format file size in bytes to human-readable string
 */
function formatFileSize(bytes) {
  if (bytes === 0) return '0 Bytes';
  const k = 1024;
  const sizes = ['Bytes', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return Number.parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
}

/**
 * Get icon name for file based on content type
 */
function getFileIcon(contentType) {
  if (contentType.startsWith('image/')) return 'image';
  if (contentType.startsWith('video/')) return 'videocam';
  if (contentType.startsWith('audio/')) return 'musical-notes';
  if (contentType.includes('pdf')) return 'document-text';
  if (contentType.includes('word') || contentType.includes('doc')) return 'document';
  if (contentType.includes('excel') || contentType.includes('sheet')) return 'grid';
  if (contentType.includes('zip') || contentType.includes('archive')) return 'archive';
  return 'document-outline';
}

/**
 * Unified confirmation dialog - uses Alert.alert for all platforms
 */
function confirmAction(message, title, confirmText = 'OK', cancelText = 'Cancel') {
  return new Promise(resolve => {
    _reactNative.Alert.alert(title || 'Confirm', message, [{
      text: cancelText,
      style: 'cancel',
      onPress: () => resolve(false)
    }, {
      text: confirmText,
      onPress: () => resolve(true)
    }], {
      cancelable: true,
      onDismiss: () => resolve(false)
    });
  });
}

/**
 * Convert DocumentPicker asset to File object
 * Handles both web (native File API) and mobile (URI-based) file sources
 * Expo 54 compatible - works across all platforms
 */
async function convertDocumentPickerAssetToFile(doc, index) {
  try {
    let file = null;

    // Priority 1: Use doc.file if available (web native File API)
    // This is the most efficient path as it doesn't require fetching
    if (doc.file && doc.file instanceof globalThis.File) {
      file = doc.file;
      // Ensure file has required properties
      if (!file.name && doc.name) {
        // Create new File with proper name if missing
        file = new globalThis.File([file], doc.name, {
          type: file.type || doc.mimeType || 'application/octet-stream'
        });
      }
      // Preserve URI for preview if available (useful for mobile previews)
      if (doc.uri) {
        file.uri = doc.uri;
      }
      return file;
    }

    // Priority 2: Use uri to create File using Expo 54 FileSystem API
    // This path handles mobile file URIs (file://, content://) and web blob URLs
    if (doc.uri) {
      try {
        // Check if it's a web blob URL - use fetch for those
        if (doc.uri.startsWith('blob:') || doc.uri.startsWith('http://') || doc.uri.startsWith('https://')) {
          const response = await fetch(doc.uri);
          if (!response.ok) {
            throw new Error(`Failed to fetch file: ${response.statusText}`);
          }
          const blob = await response.blob();
          const fileName = doc.name || `file-${index + 1}`;
          const fileType = doc.mimeType || blob.type || 'application/octet-stream';
          file = new globalThis.File([blob], fileName, {
            type: fileType
          });
          // Preserve URI for preview
          file.uri = doc.uri;
          return file;
        }

        // For mobile file URIs (file://, content://), use fetch to get blob
        // React Native's Blob doesn't support Uint8Array directly, so we use fetch
        const fileName = doc.name || `file-${index + 1}`;
        const fileType = doc.mimeType || 'application/octet-stream';

        // Use fetch to get the file as a blob (works with file:// and content:// URIs in React Native)
        const response = await fetch(doc.uri);
        if (!response.ok) {
          throw new Error(`Failed to fetch file: ${response.statusText}`);
        }
        const blob = await response.blob();
        file = new globalThis.File([blob], fileName, {
          type: fileType
        });
        // Preserve URI for preview (especially important for mobile)
        file.uri = doc.uri;
        return file;
      } catch (error) {
        console.error('Failed to read file from URI:', error);
        throw new Error(`Failed to load file: ${error.message || 'Unknown error'}`);
      }
    }

    // No file or URI available - this shouldn't happen with Expo 54
    throw new Error('Missing file data (no file or uri property)');
  } catch (error) {
    console.error('Error converting document to file:', error);
    throw error;
  }
}

/**
 * Helper to safely request a thumbnail variant only for image mime types.
 * Prevents backend warnings: "Variant thumb not supported for mime application/pdf".
 * 
 * @param file - File metadata
 * @param variant - Variant type (default: 'thumb')
 * @param getFileDownloadUrl - Function to get download URL from oxyServices
 */
function getSafeDownloadUrl(file, variant = 'thumb', getFileDownloadUrl) {
  const isImage = file.contentType.startsWith('image/');
  const isVideo = file.contentType.startsWith('video/');

  // Prefer explicit variant key if variants metadata present
  if (file.variants && file.variants.length > 0) {
    // For videos, try 'poster' regardless of requested variant
    if (isVideo) {
      const poster = file.variants.find(v => v.type === 'poster');
      if (poster) return getFileDownloadUrl(file.id, 'poster');
    }
    if (isImage) {
      const desired = file.variants.find(v => v.type === variant);
      if (desired) return getFileDownloadUrl(file.id, variant);
    }
  }
  if (isImage) {
    return getFileDownloadUrl(file.id, variant);
  }
  if (isVideo) {
    // Fallback to poster if backend supports implicit generation
    try {
      return getFileDownloadUrl(file.id, 'poster');
    } catch {
      return getFileDownloadUrl(file.id);
    }
  }
  // Other mime types: no variant
  return getFileDownloadUrl(file.id);
}

/**
 * Upload file raw - helper function for file uploads
 */
async function uploadFileRaw(file, userId, oxyServices, visibility) {
  return await oxyServices.uploadRawFile(file, visibility);
}

/**
 * Configuration for creating an avatar picker handler
 */

/**
 * Creates a reusable avatar picker handler function.
 * 
 * This function navigates to the FileManagement screen and handles:
 * - Image file validation
 * - File visibility update to public
 * - Profile avatar update via mutation
 * - Success/error toast notifications
 * 
 * @example
 * ```tsx
 * const openAvatarPicker = createAvatarPickerHandler({
 *   navigate,
 *   oxyServices,
 *   updateProfileMutation,
 *   onAvatarSelected: setAvatarFileId,
 *   t,
 *   contextName: 'AccountSettings'
 * });
 * 
 * <TouchableOpacity onPress={openAvatarPicker}>
 *   <Text>Change Avatar</Text>
 * </TouchableOpacity>
 * ```
 */
function createAvatarPickerHandler(config) {
  const {
    navigate,
    oxyServices,
    updateProfileMutation,
    onAvatarSelected,
    t,
    contextName = 'AvatarPicker'
  } = config;
  return () => {
    if (!navigate) {
      console.warn(`[${contextName}] navigate function is not available`);
      return;
    }
    navigate('FileManagement', {
      selectMode: true,
      multiSelect: false,
      disabledMimeTypes: ['video/', 'audio/', 'application/pdf'],
      afterSelect: 'none',
      // Don't navigate away - stay on current screen
      onSelect: async file => {
        if (!file.contentType.startsWith('image/')) {
          _sonner.toast.error(t('editProfile.toasts.selectImage') || 'Please select an image file');
          return;
        }
        try {
          // Update file visibility to public for avatar
          await (0, _avatarUtils.updateAvatarVisibility)(file.id, oxyServices, contextName);

          // Update local state if callback provided
          if (onAvatarSelected) {
            onAvatarSelected(file.id);
          }

          // Update user using TanStack Query mutation
          await updateProfileMutation.mutateAsync({
            avatar: file.id
          });
          _sonner.toast.success(t('editProfile.toasts.avatarUpdated') || 'Avatar updated');
        } catch (e) {
          _sonner.toast.error(e.message || t('editProfile.toasts.updateAvatarFailed') || 'Failed to update avatar');
        }
      }
    });
  };
}
//# sourceMappingURL=fileManagement.js.map