import 'dart:async';

import 'package:cmbsdk_flutter/cmbsdk_flutter_constants.dart';
import 'package:flutter/services.dart';

class cmb {
  static const MethodChannel _channel = const MethodChannel('cmbsdk_flutter');
  static const EventChannel _availabilityChannel =
      const EventChannel('availabilityChannel');
  static const EventChannel _connectionStateChannel =
      const EventChannel('connectionStateChannel');
  static const EventChannel _resultsChannel =
      const EventChannel('resultsChannel');
  static const EventChannel _scanningStateChannel =
      const EventChannel('scanningStateChannel');

  static Future loadScanner(int deviceType) {
    return _channel.invokeMethod('loadScanner', deviceType);
  }

  static Future connect() {
    return _channel.invokeMethod('connect');
  }

  static Future disconnect() {
    return _channel.invokeMethod('disconnect');
  }

  static Future startScanning() {
    return _channel.invokeMethod('startScanning');
  }

  static Future stopScanning() {
    return _channel.invokeMethod('stopScanning');
  }

  static Future setSymbologyEnabled(cmbSymbology symbology, bool enable) {
    return _channel.invokeMethod('setSymbologyEnabled',
        {'symbology': symbology.index, 'enable': enable});
  }

  static Future isSymbologyEnabled(cmbSymbology symbology) {
    return _channel.invokeMethod('isSymbologyEnabled', symbology.index);
  }

  static setCameraMode(int cameraMode) {
    _channel.invokeMethod('setCameraMode', cameraMode);
  }

  static setPreviewOptions(int previewOptions) {
    _channel.invokeMethod('setPreviewOptions', previewOptions);
  }

  static setPreviewOverlayMode(cmbOverlayMode previewOverlayMode) {
    _channel.invokeMethod('setPreviewOverlayMode', previewOverlayMode.index);
  }

  static setPreviewContainerPositionAndSize(
      double x, double y, double width, double height) {
    _channel.invokeMethod('setPreviewContainerPositionAndSize',
        {'x': x, 'y': y, 'width': width, 'height': height});
  }

  static Future setLightsOn(bool on) {
    return _channel.invokeMethod('setLightsOn', on);
  }

  static Future isLightsOn() {
    return _channel.invokeMethod('isLightsOn');
  }

  static Future enableImage(bool enable) {
    return _channel.invokeMethod('enableImage', enable);
  }

  static Future enableImageGraphics(bool enable) {
    return _channel.invokeMethod('enableImageGraphics', enable);
  }

  static Future sendCommand(String commandString) {
    return _channel.invokeMethod('sendCommand', commandString);
  }

  static Future resetConfig() {
    return _channel.invokeMethod('resetConfig');
  }

  static registerSDK(String key) {
    _channel.invokeMethod('registerSDK', key);
  }

  static Future<int> getAvailability() async {
    return await _channel.invokeMethod('getAvailability');
  }

  static Future<int> getConnectionState() async {
    return await _channel.invokeMethod('getConnectionState');
  }

  static Future beep() {
    return _channel.invokeMethod('beep');
  }

  static Future getDeviceBatteryLevel() {
    return _channel.invokeMethod('getDeviceBatteryLevel');
  }

  static Future<String> get sdkVersion async {
    return await _channel.invokeMethod('getSdkVersion');
  }

  static Future setPreviewContainerFullScreen() {
    return _channel.invokeMethod('setPreviewContainerFullScreen');
  }

  static Future setPreviewContainerBelowStatusBar(bool arg) {
    return _channel.invokeMethod('setPreviewContainerBelowStatusBar', arg);
  }

  static setStopScannerOnRotate(bool stopScanner) {
    _channel.invokeMethod('setStopScannerOnRotate', stopScanner);
  }

  static Future enableCameraFlag(int codeMask, int flag) {
    return _channel
        .invokeMethod('enableCameraFlag', {'codeMask': codeMask, 'flag': flag});
  }

  static Future disableCameraFlag(int codeMask, int flag) {
    return _channel.invokeMethod(
        'disableCameraFlag', {'codeMask': codeMask, 'flag': flag});
  }

  static Future setCameraParam(int codeMask, int param, int value) {
    return _channel.invokeMethod('setCameraParam',
        {'codeMask': codeMask, 'param': param, 'value': value});
  }

  static Future setParser(cmbResultParser parser) {
    return _channel.invokeMethod('setParser', parser.index);
  }

  static Future setReadStringEncoding(
      cmbReadStringEncoding readStringEncoding) {
    return _channel.invokeMethod(
        'setReadStringEncoding', readStringEncoding.index);
  }

  static createMDMAuthCredentials(
      String username, String password, String clientID, String clientSecret) {
    _channel.invokeMethod('createMDMAuthCredentials', {
      'username': username,
      'password': password,
      'clientID': clientID,
      'clientSecret': clientSecret
    });
  }

  static setMDMReportingEnabled(bool enabled) {
    _channel.invokeMethod('setMDMReportingEnabled', enabled);
  }

  static Future getCameraExposureCompensationRange() {
    return _channel.invokeMethod('getCameraExposureCompensationRange');
  }

  static Future setCameraExposureCompensation(double exposureCompensation) {
    return _channel.invokeMethod(
        'setCameraExposureCompensation', exposureCompensation);
  }

  static Future loadCameraConfig() {
    return _channel.invokeMethod('loadCameraConfig');
  }

  static showToast(String message) {
    _channel.invokeMethod('showToast', message);
  }

  static hideToast() {
    _channel.invokeMethod('hideToast');
  }

  static Future scanImageFromUri(String uri) {
    return _channel.invokeMethod('scanImageFromUri', uri);
  }

  static Future scanImageFromBase64(String base64) {
    return _channel.invokeMethod('scanImageFromBase64', base64);
  }

  static setPairedBluetoothDevice(String btDevice) {
    _channel.invokeMethod('setPairedBluetoothDevice', btDevice);
  }

  static Future getPairedBluetoothDevice() {
    return _channel.invokeMethod('getPairedBluetoothDevice');
  }

  static setAvailabilityChangedListener(
      void Function(dynamic)? callbackFunction) {
    _availabilityChannel.receiveBroadcastStream().listen(callbackFunction);
  }

  static setConnectionStateChangedListener(
      void Function(dynamic)? callbackFunction) {
    _connectionStateChannel.receiveBroadcastStream().listen(callbackFunction);
  }

  static setReadResultReceivedListener(
      void Function(dynamic)? callbackFunction) {
    _resultsChannel.receiveBroadcastStream().listen(callbackFunction);
  }

  static setScanningStateChangedListener(
      void Function(dynamic)? callbackFunction) {
    _scanningStateChannel.receiveBroadcastStream().listen(callbackFunction);
  }
}
