"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = exports.DownloadStatus = void 0;
var _reactNativeFs = _interopRequireDefault(require("react-native-fs"));
var _tsSdkReactNative = require("@amityco/ts-sdk-react-native");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
let DownloadStatus = exports.DownloadStatus = /*#__PURE__*/function (DownloadStatus) {
  DownloadStatus[DownloadStatus["NOT_DOWNLOADED"] = -1] = "NOT_DOWNLOADED";
  DownloadStatus[DownloadStatus["PENDING"] = 0] = "PENDING";
  DownloadStatus[DownloadStatus["DOWNLOADING"] = 1] = "DOWNLOADING";
  DownloadStatus[DownloadStatus["COMPLETED"] = 2] = "COMPLETED";
  DownloadStatus[DownloadStatus["FAILED"] = 3] = "FAILED";
  return DownloadStatus;
}({});
class AssetDownloader {
  static #instance;
  downloadJobs = new Map();
  statusListeners = new Map();
  constructor() {
    this.client = _tsSdkReactNative.Client.getActiveClient();
  }
  static get instance() {
    if (!AssetDownloader.#instance) {
      AssetDownloader.#instance = new AssetDownloader();
    }
    return AssetDownloader.#instance;
  }

  /**
   * Enqueue a file for download
   * @param url URL to download
   * @returns The download ID (jobId)
   */
  async enqueue(url) {
    // Create directory if it doesn't exist
    const dirPath = `${_reactNativeFs.default.DocumentDirectoryPath}/amityDir`;
    const exists = await _reactNativeFs.default.exists(dirPath);
    if (!exists) {
      await _reactNativeFs.default.mkdir(dirPath);
    }

    // Generate a filename from URL hash
    const fileName = `${Math.abs(this.hashCode(url))}.jpg`;
    const filePath = `${dirPath}/${fileName}`;

    // Check if file already exists
    const fileExists = await _reactNativeFs.default.exists(filePath);
    if (fileExists) {
      const dummyId = Date.now();
      this.downloadJobs.set(url, dummyId);
      // Notify as completed
      this.notifyListeners(url, DownloadStatus.COMPLETED);
      return dummyId;
    }

    // Start download
    const jobId = Date.now(); // Use timestamp as unique ID

    try {
      var _this$client;
      // Begin download
      const accessToken = this === null || this === void 0 || (_this$client = this.client) === null || _this$client === void 0 || (_this$client = _this$client.token) === null || _this$client === void 0 ? void 0 : _this$client.accessToken;
      const downloadOptions = {
        fromUrl: url,
        headers: {
          Authorization: `Bearer ${accessToken}`
        },
        toFile: filePath,
        background: true,
        discretionary: true,
        begin: () => {
          this.notifyListeners(url, DownloadStatus.DOWNLOADING);
        }
      };

      // Store job ID for tracking
      this.downloadJobs.set(url, jobId);

      // Start download
      const download = _reactNativeFs.default.downloadFile(downloadOptions);
      download.promise.then(data => {
        if (data.statusCode !== 200) {
          this.notifyListeners(url, DownloadStatus.FAILED);
        } else this.notifyListeners(url, DownloadStatus.COMPLETED);
      }).catch(error => {
        console.error('Download file failed:', error); // Log result
        this.notifyListeners(url, DownloadStatus.FAILED);
      });
      return jobId;
    } catch (error) {
      console.error('Failed to start download:', error);
      this.notifyListeners(url, DownloadStatus.FAILED);
      return -1;
    }
  }

  /**
   * Get the file path for a downloaded asset
   */
  getFilePath(url) {
    const fileName = `${Math.abs(this.hashCode(url))}.jpg`;
    return `${_reactNativeFs.default.DocumentDirectoryPath}/amityDir/${fileName}`;
  }

  /**
   * Check if a file is existed
   */
  async fileExists(url) {
    try {
      const localPath = this.getFilePath(url);
      return await _reactNativeFs.default.exists(localPath);
    } catch (error) {
      return false;
    }
  }

  /**
   * Check if a file is downloaded
   */
  async isDownloaded(url) {
    const filePath = this.getFilePath(url);
    return _reactNativeFs.default.exists(filePath);
  }

  /**
   * Get the download status for a job
   */
  getDownloadStatus(downloadId) {
    // In a real implementation, you'd track the status of each download
    // For now, this is a simplified version
    for (const [_, jobId] of this.downloadJobs.entries()) {
      if (jobId === downloadId) {
        return DownloadStatus.COMPLETED; // Simplified - you'd need to track real status
      }
    }
    return DownloadStatus.NOT_DOWNLOADED;
  }

  /**
   * Add a listener for download status changes
   */
  addStatusListener(url, listener) {
    var _this$statusListeners;
    if (!this.statusListeners.has(url)) {
      this.statusListeners.set(url, []);
    }
    (_this$statusListeners = this.statusListeners.get(url)) === null || _this$statusListeners === void 0 || _this$statusListeners.push(listener);
  }

  /**
   * Remove a listener
   */
  removeStatusListener(url, listener) {
    const listeners = this.statusListeners.get(url);
    if (listeners) {
      const index = listeners.indexOf(listener);
      if (index !== -1) {
        listeners.splice(index, 1);
      }
    }
  }

  /**
   * Notify all listeners for a URL about a status change
   */
  notifyListeners(url, status) {
    const listeners = this.statusListeners.get(url);
    if (listeners) {
      listeners.forEach(listener => listener(status));
    }
  }

  /**
   * Get a hash code from a string
   */
  hashCode(str) {
    let hash = 0;
    for (let i = 0; i < str.length; i++) {
      const char = str.charCodeAt(i);
      hash = (hash << 5) - hash + char;
      hash = hash & hash; // Convert to 32bit integer
    }
    return hash;
  }

  /**
   * Delete a downloaded file for a specific URL
   * @param url URL of the asset to delete
   * @returns Promise resolving to boolean indicating success
   */
  async deleteFile(url) {
    try {
      const filePath = this.getFilePath(url);
      const exists = await _reactNativeFs.default.exists(filePath);
      if (exists) {
        await _reactNativeFs.default.unlink(filePath);

        // Update tracking
        const jobId = this.downloadJobs.get(url);
        if (jobId) {
          this.downloadJobs.delete(url);
          this.notifyListeners(url, DownloadStatus.NOT_DOWNLOADED);
        }
        return true;
      } else {
        console.error(`File does not exist: ${filePath}`);
        return false;
      }
    } catch (error) {
      console.error(`Error deleting file for URL ${url}:`, error);
      return false;
    }
  }

  /**
   * Delete all downloaded files
   * @returns Promise resolving to boolean indicating success
   */
  async deleteAllFiles() {
    try {
      const dirPath = `${_reactNativeFs.default.DocumentDirectoryPath}/amityDir`;
      const exists = await _reactNativeFs.default.exists(dirPath);
      if (exists) {
        // Read directory and get all files
        const files = await _reactNativeFs.default.readDir(dirPath);

        // Delete all files
        await Promise.all(files.map(file => _reactNativeFs.default.unlink(file.path)));

        // Reset tracking
        for (const [url] of this.downloadJobs) {
          this.notifyListeners(url, DownloadStatus.NOT_DOWNLOADED);
        }
        this.downloadJobs.clear();
        return true;
      } else {
        return true; // Still consider this a success since end result is no files
      }
    } catch (error) {
      console.error('Error deleting asset files:', error);
      return false;
    }
  }
}
var _default = exports.default = AssetDownloader;
//# sourceMappingURL=AssetDownloader.js.map