"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.OxyServicesAssetsMixin = OxyServicesAssetsMixin;
function OxyServicesAssetsMixin(Base) {
  return class extends Base {
    constructor(...args) {
      super(...args);
    }

    /**
     * Delete file
     */
    async deleteFile(fileId) {
      try {
        return await this.makeRequest('DELETE', `/api/assets/${encodeURIComponent(fileId)}`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get file download URL (synchronous - uses stream endpoint for images to avoid ORB blocking)
     */
    getFileDownloadUrl(fileId, variant, expiresIn) {
      const base = this.getBaseURL();
      const params = new URLSearchParams();
      if (variant) params.set('variant', variant);
      if (expiresIn) params.set('expiresIn', String(expiresIn));
      params.set('fallback', 'placeholderVisible');
      const token = this.getClient().getAccessToken();
      if (token) params.set('token', token);
      const qs = params.toString();
      return `${base}/api/assets/${encodeURIComponent(fileId)}/stream${qs ? `?${qs}` : ''}`;
    }

    /**
     * Get file download URL asynchronously (returns signed URL directly from CDN)
     */
    async getFileDownloadUrlAsync(fileId, variant, expiresIn) {
      try {
        const url = await this.fetchAssetDownloadUrl(fileId, variant, this.getAssetUrlCacheTTL(expiresIn), expiresIn);
        return url || this.getFileDownloadUrl(fileId, variant, expiresIn);
      } catch (error) {
        return this.getFileDownloadUrl(fileId, variant, expiresIn);
      }
    }

    /**
     * List user files
     */
    async listUserFiles(limit, offset) {
      try {
        const paramsObj = {};
        if (limit) paramsObj.limit = limit;
        if (offset) paramsObj.offset = offset;
        return await this.makeRequest('GET', '/api/assets', paramsObj, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get account storage usage (server-side usage aggregated from assets)
     */
    async getAccountStorageUsage() {
      try {
        return await this.makeRequest('GET', '/api/storage/usage', undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get file content as text
     */
    async getFileContentAsText(fileId, variant) {
      try {
        const downloadUrl = await this.fetchAssetDownloadUrl(fileId, variant, this.getAssetUrlCacheTTL());
        if (!downloadUrl) {
          throw new Error('No download URL returned for asset');
        }
        return await this.fetchAssetContent(downloadUrl, 'text');
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get file content as blob
     */
    async getFileContentAsBlob(fileId, variant) {
      try {
        const downloadUrl = await this.fetchAssetDownloadUrl(fileId, variant, this.getAssetUrlCacheTTL());
        if (!downloadUrl) {
          throw new Error('No download URL returned for asset');
        }
        return await this.fetchAssetContent(downloadUrl, 'blob');
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get batch access to multiple files
     */
    async getBatchFileAccess(fileIds, context) {
      try {
        return await this.makeRequest('POST', '/api/assets/batch-access', {
          fileIds,
          context
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get download URLs for multiple files efficiently
     */
    async getFileDownloadUrls(fileIds, context) {
      const response = await this.getBatchFileAccess(fileIds, context);
      const urls = {};
      const results = response.results || {};
      for (const [id, result] of Object.entries(results)) {
        if (result.allowed && result.url) {
          urls[id] = result.url;
        }
      }
      return urls;
    }

    /**
     * Upload raw file data
     */
    async uploadRawFile(file, visibility, metadata) {
      return this.assetUpload(file, visibility, metadata);
    }

    /**
     * Upload file using Central Asset Service
     */
    async assetUpload(file, visibility, metadata, onProgress) {
      const fileName = file.name || 'unknown';
      const fileSize = file.size;
      try {
        const formData = new FormData();
        // In React Native, pass filename as third parameter to avoid read-only name property error
        // This prevents "Cannot assign to property 'name' which has only a getter" error
        formData.append('file', file, fileName);
        if (visibility) {
          formData.append('visibility', visibility);
        }
        if (metadata) {
          formData.append('metadata', JSON.stringify(metadata));
        }
        const response = await this.getClient().request({
          method: 'POST',
          url: '/api/assets/upload',
          data: formData,
          cache: false
        });
        if (onProgress && response) {
          onProgress(100);
        }
        return response;
      } catch (error) {
        console.error('File upload error:', error);
        let errorMessage = 'File upload failed';
        if (error instanceof Error) {
          errorMessage = error.message || errorMessage;
        } else if (error && typeof error === 'object') {
          if ('message' in error) {
            errorMessage = String(error.message) || errorMessage;
          } else if ('error' in error && typeof error.error === 'string') {
            errorMessage = error.error;
          } else if ('data' in error && error.data?.message) {
            errorMessage = String(error.data.message);
          }
        } else if (error) {
          errorMessage = String(error) || errorMessage;
        }
        const contextError = error;
        if (!contextError.fileContext) {
          contextError.fileContext = {
            fileName,
            fileSize
          };
        }
        if (error instanceof Error && error.message) {
          const handledError = this.handleError(contextError);
          if (!handledError.message || handledError.message.trim() === 'An unexpected error occurred') {
            handledError.message = errorMessage;
          }
          throw handledError;
        }
        const newError = new Error(errorMessage);
        newError.fileContext = contextError.fileContext;
        throw this.handleError(newError);
      }
    }

    /**
     * Link asset to an entity
     */
    async assetLink(fileId, app, entityType, entityId, visibility, webhookUrl) {
      try {
        const body = {
          app,
          entityType,
          entityId
        };
        if (visibility) body.visibility = visibility;
        if (webhookUrl) body.webhookUrl = webhookUrl;
        return await this.makeRequest('POST', `/api/assets/${fileId}/links`, body, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Unlink asset from an entity
     */
    async assetUnlink(fileId, app, entityType, entityId) {
      try {
        return await this.makeRequest('DELETE', `/api/assets/${fileId}/links`, {
          app,
          entityType,
          entityId
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get asset metadata
     */
    async assetGet(fileId) {
      try {
        return await this.makeRequest('GET', `/api/assets/${fileId}`, undefined, {
          cache: true,
          cacheTTL: 5 * 60 * 1000
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get asset URL (CDN or signed URL)
     */
    async assetGetUrl(fileId, variant, expiresIn) {
      try {
        const params = {};
        if (variant) params.variant = variant;
        if (expiresIn) params.expiresIn = expiresIn;
        return await this.makeRequest('GET', `/api/assets/${fileId}/url`, params, {
          cache: true,
          cacheTTL: 10 * 60 * 1000
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Restore asset from trash
     */
    async assetRestore(fileId) {
      try {
        return await this.makeRequest('POST', `/api/assets/${fileId}/restore`, undefined, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Delete asset with optional force
     */
    async assetDelete(fileId, force = false) {
      try {
        const params = force ? {
          force: 'true'
        } : undefined;
        return await this.makeRequest('DELETE', `/api/assets/${fileId}`, params, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Get list of available variants for an asset
     */
    async assetGetVariants(fileId) {
      try {
        const assetData = await this.assetGet(fileId);
        return assetData.file?.variants || [];
      } catch (error) {
        throw this.handleError(error);
      }
    }

    /**
     * Update asset visibility
     */
    async assetUpdateVisibility(fileId, visibility) {
      try {
        return await this.makeRequest('PATCH', `/api/assets/${fileId}/visibility`, {
          visibility
        }, {
          cache: false
        });
      } catch (error) {
        throw this.handleError(error);
      }
    }
    async uploadAvatar(file, userId, app = 'profiles') {
      try {
        const asset = await this.assetUpload(file, 'public');
        await this.assetLink(asset.file.id, app, 'avatar', userId, 'public');
        return asset;
      } catch (error) {
        throw this.handleError(error);
      }
    }
    async uploadProfileBanner(file, userId, app = 'profiles') {
      try {
        const asset = await this.assetUpload(file, 'public');
        await this.assetLink(asset.file.id, app, 'profile-banner', userId, 'public');
        return asset;
      } catch (error) {
        throw this.handleError(error);
      }
    }
    getAssetUrlCacheTTL(expiresIn) {
      const desiredTtlMs = (expiresIn ?? 3600) * 1000;
      return Math.min(desiredTtlMs, 10 * 60 * 1000);
    }
    async fetchAssetDownloadUrl(fileId, variant, cacheTTL, expiresIn) {
      const params = {};
      if (variant) params.variant = variant;
      if (expiresIn) params.expiresIn = expiresIn;
      const urlRes = await this.makeRequest('GET', `/api/assets/${encodeURIComponent(fileId)}/url`, Object.keys(params).length ? params : undefined, {
        cache: true,
        cacheTTL: cacheTTL ?? 10 * 60 * 1000
      });
      return urlRes?.url || null;
    }
    async fetchAssetContent(url, type) {
      const response = await fetch(url);
      if (!response?.ok) {
        throw new Error(`Failed to fetch asset content (status ${response?.status})`);
      }
      return type === 'text' ? response.text() : response.blob();
    }
  };
}
//# sourceMappingURL=OxyServices.assets.js.map