import { NativeModules, Platform } from 'react-native';
import { fetchUnitScript } from './UnitSdk.api';
import { UnitUiManager } from './unitUiManager/unitUiManager';
import type { UNFonts } from '../types/shared/fonts.types';
import { warnClientIfNeeded } from '../utils/webVersioningStrategy.utils';
import { UNSDKConstants } from './UnitSdk.constants';
import type { UNWebVersioningStrategy } from '../types/shared';
import { setTheme, setLanguage } from '../slices/ConfigurationSlice';
import { store } from '../store/store';
import { UNEnvironment } from '../types/shared/env.types';
import { UserDataKeys } from '../types/internal/unitStore.types';
import UNStoreManagerHelper from '../nativeModulesHelpers/UNStoreManagerHelper/UNStoreManagerHelper';
import { UnitHelpersManager } from './unitHelpersManager/UnitHelpersManager';
import UNSecurityManagerHelper from '../nativeModulesHelpers/UNSecurityHelper';
import { UNSecuritySettings, UNSnapshotProtectionStrategy } from '../types/shared/securitySettings';
import UNSnapshotProtectionHelper from '../nativeModulesHelpers/UNSanpshotProtectionHelper/UNSnapshotProtectionHelper';

export class UnitSDK {
  public static ui: UnitUiManager;
  public static helpers: UnitHelpersManager;

  protected static env?: UNEnvironment;
  protected static webVersioningStrategy: UNWebVersioningStrategy;
  protected static securitySettings: UNSecuritySettings = UNSDKConstants.securitySettings;
  protected static customerToken?: string;
  protected static fonts?: UNFonts;
  protected static signedNonce?: string;
  protected static pushProvisionModule?: typeof NativeModules;
  protected static sdkVersion = '1.15.0';

  public static init = async (
    env: UNEnvironment,
    theme?: string,
    language?: string,
    fonts?: UNFonts,
    webVersioningStrategy: UNWebVersioningStrategy = UNSDKConstants.webSDKRecommendedStrategy,
    securitySettings: UNSecuritySettings = UNSDKConstants.securitySettings
  ) => {
    try {
      this.webVersioningStrategy = webVersioningStrategy;
      this.ui = new UnitUiManager();
      this.helpers = new UnitHelpersManager();

      const isJailbroke = await UNSecurityManagerHelper.isDeviceJailbroke();
      if (isJailbroke) {
        throw Error('Device is jailbroke');
      }
      this.env = env;
      this.securitySettings = securitySettings;
      this.fonts = fonts;
      store.dispatch(setTheme(theme));
      store.dispatch(setLanguage(language));
      warnClientIfNeeded(this.webVersioningStrategy);
      const shouldProtectFromSnapshot = securitySettings.snapshotProtectionStrategy != UNSnapshotProtectionStrategy.None;
      if (Platform.OS === 'ios') {
        UNSnapshotProtectionHelper.setIosSecurity(shouldProtectFromSnapshot, 'light');
      }
      await fetchUnitScript();
    } catch (e) {
      console.log(e);
    }
  };

  public static isInitialized = () => {
    return this.env != undefined;
  };

  public static setPushProvisioningModule = (pushProvisionModule?: typeof NativeModules) => {
    this.pushProvisionModule = pushProvisionModule;
  };

  public static getPushProvisionModule = () => {
    return this.pushProvisionModule;
  };

  public static getSecuritySettings = () => {
    return this.securitySettings;
  };

  /**
   * @deprecated - Unit SDK is managing the signedNonce, no need to provide it
   */
  public static setSignedNonce = (signedNonce: string) => {
    this.signedNonce = signedNonce;
  };

  public static getEnv = () => {
    return this.env;
  };

  public static getWebVersioningStrategy = () => {
    return this.webVersioningStrategy;
  };

  public static getFonts = () => {
    return this.fonts;
  };

  /**
   * @deprecated - Unit SDK is managing the signedNonce, no need to provide it
   */
  public static getSignedNonce = () => {
    return this.signedNonce;
  };

  public static setCustomerToken = (customerToken: string) => {
    this.customerToken = customerToken;
  };

  public static getCustomerToken = () => {
    return this.customerToken;
  };

  public static getSdkVersion = () => {
    return this.sdkVersion;
  };

  public static cleanUserData = () => {
    UNStoreManagerHelper.cleanValue(UserDataKeys.unitCustomerToken);
    UNStoreManagerHelper.cleanValue(UserDataKeys.unitVerifiedToken);
  };

}
