import React from "react";
import { equals } from "ramda";
import { StyleSheet, StatusBar } from "react-native";

import { HandlePlayable } from "@applicaster/zapp-react-native-ui-components/Components/HandlePlayable";
import {
  useNavigation,
  useZappHooksForEntry,
} from "@applicaster/zapp-react-native-utils/reactHooks";
import { useIsInitialRender } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
import { useVideoModalAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";
import { useProfilerLogging } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
import {
  allowedOrientationsForScreen,
  ORIENTATIONS,
} from "@applicaster/zapp-react-native-utils/appUtils/orientationHelper";
import { useIsTablet } from "@applicaster/zapp-react-native-utils/reactHooks/device/useIsTablet";

import { withModalNavigationContextProvider } from "../../Contexts/ModalNavigationContext";
import {
  useModalSize,
  useBackgroundColor,
  useInitialPlayerState,
} from "./hooks";

import { APP_EVENTS } from "@applicaster/zapp-react-native-utils/appUtils/events";
import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
import { ROUTE_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/routeTypes";
import { useSubscriberFor } from "@applicaster/zapp-react-native-utils/reactHooks/useSubscriberFor";
import { requiresAuthentication } from "@applicaster/zapp-react-native-utils/configurationUtils";
import { playerManager } from "@applicaster/zapp-react-native-utils/appUtils";
import { ScreenContextProvider } from "../../Contexts/ScreenContext";
import { OpaqueLayer } from "./OpaqueLayer";

import { AnimatedPlayerModalWrapper } from "@applicaster/zapp-react-native-ui-components/Components/VideoModal/ModalAnimation";

const styles = StyleSheet.create({
  container: {
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    position: "absolute",
  },
});

const VideoModalComponent = () => {
  const [itemIdHooksFinished, setItemIdHooksFinished] =
    React.useState<Nullable<string>>(null);

  const onVideoModalHookSuccessAnalyticsEvent = useVideoModalAnalytics();

  const modalSize = useModalSize();
  const isFirstRender = useIsInitialRender();
  const backgroundColor = useBackgroundColor();

  const {
    closeVideoModal,
    setVideoModalItem,
    videoModalState: { item, mode },
    fullscreenVideoModal,
    maximiseVideoModal,
  } = useNavigation();

  const logTimestamp = useProfilerLogging();

  useInitialPlayerState(fullscreenVideoModal, maximiseVideoModal, item);

  useSubscriberFor(APP_EVENTS.onLogout, () => {
    const isItemFree = item.extensions.free && !requiresAuthentication(item);

    if (!isItemFree) {
      closeVideoModal();
      playerManager.closeNativePlayer();
    }
  });

  React.useLayoutEffect(() => {
    if (!isFirstRender) {
      setItemIdHooksFinished(null);
    }
  }, [item?.id]);

  const isLandscape = modalSize.width > modalSize.height;
  const isTablet = useIsTablet();

  React.useEffect(() => {
    if (!isTablet && isLandscape && mode !== "FULLSCREEN" && mode !== "PIP") {
      fullscreenVideoModal();
    }
  }, [isLandscape]);

  const onHooksSuccess = ({ payload }) => {
    // set new modified entry
    if (!equals(payload, item)) {
      onVideoModalHookSuccessAnalyticsEvent();
      setVideoModalItem(payload);
    }

    if (mode === "FULLSCREEN") {
      allowedOrientationsForScreen(ORIENTATIONS.landscapeSensor);
    }

    setItemIdHooksFinished(item?.id);
  };

  const onHooksFailure = () => {
    closeVideoModal();
  };

  useZappHooksForEntry(item, {
    handleHookComplete: onHooksSuccess,
    handleHookError: onHooksFailure,
    handleHookCancel: onHooksFailure,
  });

  React.useEffect(() => {
    logTimestamp(item?.id?.toString());
  }, []);

  const pathname = `${ROUTE_TYPES.VIDEO_MODAL}/${item?.id}`;

  return (
    <>
      {/* TODO: Workaround to avoid unnecessary UI effect when switching from portrait to fullscreen */}
      <StatusBar hidden={false} />
      {/* TODO: Workaround to avoid unnecessary UI effect when switching from portrait to fullscreen */}

      <PathnameContext.Provider value={pathname}>
        <ScreenContextProvider pathname={pathname}>
          {/* Hide content underneath when we switch to next video in fullscreen mode */}
          {mode === "FULLSCREEN" && <OpaqueLayer />}

          {itemIdHooksFinished === item?.id && (
            <AnimatedPlayerModalWrapper
              style={[
                styles.container,
                {
                  backgroundColor,
                },
              ]}
            >
              <HandlePlayable
                item={item}
                isModal={mode !== "PIP"}
                modalHeight={modalSize.height}
                modalWidth={modalSize.width}
                mode={mode}
              />
            </AnimatedPlayerModalWrapper>
          )}
        </ScreenContextProvider>
      </PathnameContext.Provider>
    </>
  );
};

export const VideoModal =
  withModalNavigationContextProvider(VideoModalComponent);
