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

import {
  BarcodeScannerConfiguration,
  BatchBarcodeScannerConfiguration,
  ScanbotBarcodeSdkConfiguration,
} from './configurations';
import { BarcodeScannerResult, BatchBarcodeScannerResult, LicenseInfoResult } from './results';

import {
  DetectBarcodesOnImageArguments,
  ExtractImagesFromPdfArguments,
} from './customConfigurations';
import { ScanbotBarcodeCameraView } from './component/barcode-camera-view/ScanbotBarcodeCameraView';
import { ResultWrapper } from './customTypes';

const LINKING_ERROR =
  `The package 'react-native-scanbot-barcode-scanner-sdk' doesn't seem to be linked. Make sure: \n\n` +
  Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
  '- You rebuilt the app after installing the package\n' +
  '- You are not using Expo Go\n';

const ScanbotBarcodeSDKImpl = NativeModules.ScanbotBarcodeSdk
  ? NativeModules.ScanbotBarcodeSdk
  : new Proxy(
      {},
      {
        get() {
          throw new Error(LINKING_ERROR);
        },
      }
    );

const ScanbotBarcodeSDK = {
  /**
   * Initialize the Scanbot Barcode Scanner SDK with the preferred configuration.
   *
   * @param {ScanbotBarcodeSdkConfiguration} config
   * @returns {Promise<ResultWrapper<string>>}
   */
  initializeSdk: (config: ScanbotBarcodeSdkConfiguration): Promise<ResultWrapper<string>> => {
    return ScanbotBarcodeSDKImpl.initializeSdk(config);
  },
  /**
   * Provides complete information about the current license status.
   *
   * @returns {Promise<ResultWrapper<LicenseInfoResult>>}
   */
  getLicenseInfo: (): Promise<ResultWrapper<LicenseInfoResult>> => {
    return ScanbotBarcodeSDKImpl.getLicenseInfo();
  },
  /**
   * Remove all files generated by this plugin.
   *
   * @returns {Promise<ResultWrapper<string>>}
   */
  cleanup: (): Promise<ResultWrapper<string>> => {
    return ScanbotBarcodeSDKImpl.cleanup();
  },
  /**
   * Opens the Ready-To-Use UI screen for barcode scanning with the desired configuration.
   *
   * @param {BarcodeScannerConfiguration} config
   * @returns {Promise<ResultWrapper<BarcodeScannerResult>>}
   *
   * @deprecated Use ***startBarcodeScanner*** from ***'react-native-scanbot-barcode-scanner-sdk/ui_v2'*** instead.
   */
  startBarcodeScanner: (
    config: BarcodeScannerConfiguration
  ): Promise<ResultWrapper<BarcodeScannerResult>> => {
    return ScanbotBarcodeSDKImpl.startBarcodeScanner(config);
  },
  /**
   * Force the barcode scanning Ready-To-Use UI screen to close while it is running.
   *
   * @returns {Promise<ResultWrapper<undefined>>}
   *
   * @deprecated
   */
  closeBarcodeScanner: (): Promise<ResultWrapper<undefined>> => {
    return ScanbotBarcodeSDKImpl.closeBarcodeScanner();
  },
  /**
   * Opens the Ready-To-Use UI screen for batch barcode scanning with the desired configuration.
   *
   * @param {BatchBarcodeScannerConfiguration} config
   * @returns {Promise<ResultWrapper<BatchBarcodeScannerResult>>}
   *
   * @deprecated Use ***startBarcodeScanner*** from ***'react-native-scanbot-barcode-scanner-sdk/ui_v2'*** instead.
   */
  startBatchBarcodeScanner: (
    config: BatchBarcodeScannerConfiguration
  ): Promise<ResultWrapper<BatchBarcodeScannerResult>> => {
    return ScanbotBarcodeSDKImpl.startBatchBarcodeScanner(config);
  },
  /**
   * Force the batch barcode scanning Ready-To-Use UI screen to close while it is running.
   *
   * @returns {Promise<ResultWrapper<undefined>>}
   *
   * @deprecated
   */
  closeBatchBarcodeScanner: (): Promise<ResultWrapper<undefined>> => {
    return ScanbotBarcodeSDKImpl.closeBatchBarcodeScanner();
  },
  /**
   * Detect barcodes on the image represented by the file URL. The image file URL is part of the input arguments.
   *
   * @param {DetectBarcodesOnImageArguments} args
   * @returns {Promise<ResultWrapper<BarcodeScannerResult>>}
   */
  detectBarcodesOnImage: (
    args: DetectBarcodesOnImageArguments
  ): Promise<ResultWrapper<BarcodeScannerResult>> => {
    return ScanbotBarcodeSDKImpl.detectBarcodesOnImage(args);
  },
  /**
   * Extract images from a PDF represented by the file URL. The PDF file URL is part of the input arguments.
   *
   * @param {ExtractImagesFromPdfArguments} args
   * @returns {Promise<ResultWrapper<string[]>>}
   */
  extractImagesFromPDF: (args: ExtractImagesFromPdfArguments): Promise<ResultWrapper<string[]>> => {
    return ScanbotBarcodeSDKImpl.extractImagesFromPDF(args);
  },
  /**
   * Returns the Base 64 encoded representation of the image data.
   */
  getImageData(imageFileUri: string): Promise<ResultWrapper<string>> {
    return ScanbotBarcodeSDKImpl.getImageData(imageFileUri);
  },
};

export default ScanbotBarcodeSDK;

export * from './types';
export * from './customTypes';
export * from './results';
export * from './configurations';
export * from './customConfigurations';
export { Point } from './utils';

export * from './documents/BarcodeDocumentModel';
export * from './documents/CommonFieldType';
export * from './documents/GenericDocument';

export * from './component/barcode-camera-view/ScanbotBarcodeCameraViewProperties';
export { ScanbotBarcodeCameraView };
