import * as R from "ramda";
import { Platform } from "react-native";
import uuidv4 from "uuid/v4";

import { bridgeLogger } from "../logger";

export type QuickBrickEvent =
  | "quickBrickReady"
  | "moveAppToBackground"
  | "allowedOrientationsForScreen"
  | "idleTimerDisabled"
  | "allowOverdrawInLandscape"
  | "setPrefersHomeIndicatorAutoHidden"
  | "forceAppReload";

export interface AppData {
  bundleIdentifier: string;
  accountId: number;
  accountsAccountId: string;
  broadcasterId: number;
}

export interface QuickBrickCommunicationModuleI extends AppData {
  quickBrickEvent: (
    eventName: QuickBrickEvent,
    payload: { [key: string]: any }
  ) => void;
}

const { NativeModules } = require("react-native");
const { QuickBrickCommunicationModule } = NativeModules;

/**
 * sends an event to the native QuickBrick manager module
 * This is one-way communication, no response is returned
 *
 * @export
 * @param {QuickBrickEvent} eventName
 * @param {{ [string]: any }} [payload={}] optional payload to pass to the native side - defaults to empty dictionary
 */
export function sendQuickBrickEvent(
  eventName: QuickBrickEvent,
  payload: { [key: string]: any } = {}
): void {
  const QBNativeModule =
    QuickBrickCommunicationModule ||
    NativeModules.QuickBrickCommunicationModule;

  if (!QBNativeModule) {
    throw new Error("QuickBrickCommunicationModule not found");
  }

  QBNativeModule.quickBrickEvent(eventName, payload);
}

/**
 * retrieve data from the native side
 *
 * @export
 * @returns {AppData} appData object - see type def for more details
 */
export function getAppData(): AppData {
  const APP_PROPERTY_KEYS = [
    "accountId",
    "accountsAccountId",
    "broadcasterId",
    "bundleIdentifier",
    "apiSecretKey",
    "os_type",
    "uuid",
    "platform",
    "countryLocale",
    "languageLocale",
  ];

  const webPlatforms = ["lg_tv", "samsung_tv", "web", "lg", "samsung"];

  if (Platform && webPlatforms.includes(Platform.OS)) {
    APP_PROPERTY_KEYS.push("bver", "os_type", "platform", "store");

    try {
      const uuid = window.localStorage.uuid || uuidv4();
      window.localStorage.setItem("uuid", uuid);
      QuickBrickCommunicationModule.uuid = uuid;
    } catch (error) {
      bridgeLogger.error({ message: "cannot set device uuid", error });
    }
  }

  if (
    QuickBrickCommunicationModule &&
    R.allPass(R.map(R.has, APP_PROPERTY_KEYS))
  ) {
    // $FlowFixMe - CORRECT DECLARATIONS PLZ ! KTHXBYE
    return R.pick(APP_PROPERTY_KEYS, QuickBrickCommunicationModule);
  } else {
    // TODO: in the end, we probably want to throw if the constants are not defined from the native side
    // for now, stubbing values is good enough
    return {
      accountId: 667,
      accountsAccountId: "5ae06cef8fba0f00084bd3c6",
      broadcasterId: 770,
      bundleIdentifier: "com.quickbrickTest",
    };
  }
}

export function getLegacyInitialProps() {
  if (QuickBrickCommunicationModule) {
    return QuickBrickCommunicationModule.initialProps;
  }

  bridgeLogger.warning("QuickBrickCommunicationModule not found");

  return {};
}

export const QUICK_BRICK_EVENTS = {
  QUICK_BRICK_READY: "quickBrickReady",
  FORCE_APP_RELOAD: "forceAppReload",
  MOVE_APP_TO_BACKGROUND: "moveAppToBackground",
  ALLOWED_ORIENTATIONS_FOR_SCREEN: "allowedOrientationsForScreen",
  IDLE_TIMER_DISABLED: "idleTimerDisabled",
  SET_PREFERS_HOME_INDICATOR_AUTO_HIDDEN: "setPrefersHomeIndicatorAutoHidden",
  ALLOW_OVERDRAW_IN_LANDSCAPE: "allowOverdrawInLandscape",
} as const;
