import { NativeModules, NativeEventEmitter, Platform } from 'react-native';

// Debug information
console.log('[LevinEncryptedUploader] Debug Info:', {
  platform: Platform.OS,
  version: Platform.Version,
  availableModules: Object.keys(NativeModules),
  reactNativeVersion: Platform.constants.reactNativeVersion,
});

const { LevinEncryptedUploader } = NativeModules;

if (!LevinEncryptedUploader) {
  console.error(
    '[LevinEncryptedUploader] Native module is not available. Debug info:',
    {
      availableModules: Object.keys(NativeModules),
      platform: Platform.OS,
      version: Platform.Version,
    }
  );
  throw new Error(
    'LevinEncryptedUploader native module is not available. ' +
      'Please ensure the module is properly linked in your native code. ' +
      'Available modules: ' +
      Object.keys(NativeModules).join(', ')
  );
}

// Log available methods
console.log(
  '[LevinEncryptedUploader] Available methods:',
  Object.keys(LevinEncryptedUploader)
);

const eventEmitter = new NativeEventEmitter(LevinEncryptedUploader);

export interface FileInfo {
  mimeType: string;
  size: number;
  exists: boolean;
  name: string;
  extension: string;
}

export interface UploadOptions {
  url: string;
  path: string;
  method?: string;
  headers?: { [key: string]: string };
  encryptionKey: string;
  encryptionNonce: string;
  customTransferId?: string;
  appGroup?: string;
}

export interface DownloadOptions {
  url: string;
  path: string;
  method?: string;
  headers?: { [key: string]: string };
  customTransferId?: string;
  appGroup?: string;
}

export interface DownloadAndDecryptOptions {
  url: string;
  destination: string;
  headers?: { [key: string]: string };
  encryptionKey: string;
  encryptionNonce: string;
}

export interface Spec {
  // File info methods
  getFileInfo(path: string): Promise<FileInfo>;

  // Upload methods
  startUpload(options: UploadOptions): Promise<string>;
  cancelUpload(uploadId: string): Promise<boolean>;

  // Download methods
  startDownload(options: DownloadOptions): Promise<string>;
  cancelDownload(downloadId: string): Promise<boolean>;

  // Direct download and decrypt
  downloadAndDecrypt(
    options: DownloadAndDecryptOptions
  ): Promise<{ path: string }>;

  // Event emitter methods
  addListener(eventName: string): void;
  removeListeners(count: number): void;
}

// Add event emitter methods
const addEventListener = (eventName: string, callback: (data: any) => void) => {
  return eventEmitter.addListener(
    `levin-encrypted-uploader-${eventName}`,
    callback
  );
};

const removeEventListener = (subscription: { remove: () => void }) => {
  subscription.remove();
};

export { addEventListener, removeEventListener };

export default LevinEncryptedUploader as Spec;
