import * as React from "react";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";

import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
import { PlayerContainer } from "../PlayerContainer";
import { useModalSize } from "../VideoModal/hooks";
import { ViewStyle } from "react-native";
import { findCastPlugin, getPlayer } from "./utils";
import { useWaitForValidOrientation } from "../Screen/hooks";

type Props = {
  item: ZappEntry;
  isModal: boolean;
  modalHeight?: number;
  modalWidth?: number;
  mode: VideoModalMode;
  groupId?: string;
};

type PlayableComponent = {
  Component: React.ComponentType<any>;
};

export function HandlePlayable({
  item,
  isModal,
  mode,
  groupId,
}: Props): React.ReactElement | null {
  const { plugins, contentTypes, rivers, appData } = usePickFromState([
    "plugins",
    "contentTypes",
    "rivers",
    "appData",
  ]);

  const { closeVideoModal } = useNavigation();

  const [Player, playerModuleProperties] = getPlayer(item, {
    plugins,
    contentTypes,
    rivers,
    appData,
  });

  const { module: CastPlugin } = findCastPlugin(plugins);

  const [playable, setPlayable] =
    React.useState<Nullable<PlayableComponent>>(null);

  const [casting, setCasting] = React.useState(CastPlugin?.isCasting);

  React.useEffect(() => {
    // close video modal before open non-modal player
    if (!isModal) {
      closeVideoModal();
    }

    const castStateHandler = async () => {
      const castState = await CastPlugin?.getCastState();
      setCasting(castState === "Connected");
    };

    castStateHandler();

    CastPlugin?.EventEmitter?.addListener?.(
      CastPlugin?.CAST_STATE_CHANGED,
      castStateHandler
    );

    return () => {
      CastPlugin?.EventEmitter?.removeListener?.(
        CastPlugin?.CAST_STATE_CHANGED,
        castStateHandler
      );
    };
  }, []);

  React.useEffect(() => {
    setPlayable({
      Component: casting ? CastPlugin?.CastHandler : PlayerContainer,
    });
  }, [casting]);

  const modalSize = useModalSize();

  const isOrientationReady = useWaitForValidOrientation();

  const style = React.useMemo(() => {
    const isFullScreenReady =
      mode === "PIP" || (mode === "FULLSCREEN" && isOrientationReady);

    const getDimensionValue = (value: string | number) => {
      return isModal ? value : isFullScreenReady ? "100%" : 0; // do not show player, until full screen mode is ready
    };

    return {
      width: getDimensionValue(modalSize.width),
      height: getDimensionValue(modalSize.height),
    } as ViewStyle;
  }, [modalSize, isModal, mode, isOrientationReady]);

  const Component = playable?.Component;

  if (Component) {
    return (
      <Component
        item={item}
        Player={Player}
        plugin={CastPlugin}
        style={style}
        isModal={isModal}
        mode={mode}
        disableCastAction={playerModuleProperties?.disableCastAction}
        groupId={groupId}
      />
    );
  }

  return !isModal ? <BufferAnimation videoStyle={style} /> : null;
}
