import { NativeModules } from "react-native";
import { localStorage } from "../ZappStorage/LocalStorage";
import { sessionStorage } from "../ZappStorage/SessionStorage";

interface PluginManagerInterface {
  disablePlugin: (identifier: string) => Promise<boolean>;
  disableAllPlugins: (type: string) => Promise<boolean>;
  enablePlugin: (identifier: string) => Promise<boolean>;
  enableAllPlugins: (type: string) => Promise<boolean>;
  isPluginEnabled: (identifier: string) => Promise<boolean> | boolean;
}

// eslint-disable-next-line prefer-promise-reject-errors
const nullPromise = () => Promise.reject("Push Notification bridge is null");

const defaultPluginManager = {
  disablePlugin: nullPromise,
  disableAllPlugins: nullPromise,
  enablePlugin: nullPromise,
  enableAllPlugins: nullPromise,
  isPluginEnabled: nullPromise,
};

const { PluginsManagerBridge = defaultPluginManager } = NativeModules as {
  PluginsManagerBridge: PluginManagerInterface;
};

/**
 * Disable plugin with specific identifier
 * @param  {String} tags Tags array to reginster
 */
async function disablePlugin(identifier) {
  try {
    return PluginsManagerBridge.disablePlugin(identifier);
  } catch (e) {
    return false;
  }
}

/**
 * Disable all plugins for type
 * @param {String} tags Tags array to reginster
 */
async function disableAllPlugins(type) {
  return PluginsManagerBridge.disableAllPlugins(type);
}

/**
 * Enable plugin with specific identifier
 * @param {String} tags Tags array to reginster
 */
async function enablePlugin(identifier) {
  try {
    return PluginsManagerBridge.enablePlugin(identifier);
  } catch (e) {
    return false;
  }
}

/**
 * Enable all plugins for type
 * @param {String} tags Tags array to reginster
 */
async function enableAllPlugins(type) {
  return PluginsManagerBridge.enableAllPlugins(type);
}

/**
 * Check if plugin can support disable/enable logic on iOS
 * @param {String} identifier Plugin identifier
 */
async function isPluginEnabledNative(identifier) {
  try {
    const isEnabled = await PluginsManagerBridge.isPluginEnabled(identifier);

    return isEnabled;
  } catch (e) {
    return false;
  }
}

/**
 * Check if isPluginEnabledNative can be used
 */
function isPluginEnabledNativeAvailable() {
  return !!PluginsManagerBridge.isPluginEnabled;
}

/**
 * Check if plugin can support disable/enable logic
 * @param {String} identifier Plugin identifier
 */
async function isPluginSupportToggleLogic(identifier) {
  const retVal = await sessionStorage.getItem("enabled", identifier);

  return retVal;
}

/**
 * Check if plugin enabled/disabled
 * @param {String} identifier Plugin identifier
 */
async function isPluginEnabled(identifier) {
  if (isPluginEnabledNativeAvailable()) {
    return isPluginEnabledNative(identifier);
  }

  const enabledInConfigurationJSON =
    await isPluginSupportToggleLogic(identifier);

  if (enabledInConfigurationJSON !== undefined) {
    const enabledOverriden = await localStorage.getItem(
      identifier,
      "plugin_status"
    );

    if (typeof enabledOverriden === "undefined" || enabledOverriden === null) {
      return enabledInConfigurationJSON;
    }

    return enabledOverriden;
  } else {
    return null;
  }
}

export const pluginsManagerBridge = {
  disablePlugin,

  disableAllPlugins,

  enablePlugin,

  enableAllPlugins,

  isPluginSupportToggleLogic,

  isPluginEnabled,
};
