import * as React from "react";
import { path, prop } from "ramda";
import {
  findPluginByType,
  findPluginByIdentifier,
} from "@applicaster/zapp-react-native-utils/pluginUtils";
import { HandlePlayable } from "../HandlePlayable";
import { toPascalCase } from "@applicaster/zapp-react-native-utils/stringUtils";
import { HookRenderer } from "../HookRenderer";
import { LinkHandler } from "../LinkHandler";
import { Favorites } from "../Favorites";
import { ZappPipesScreenContext } from "../../Contexts";
import { componentsLogger } from "../../Helpers/logger";
import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
import { useNavigation } from "@applicaster/zapp-react-native-utils/reactHooks";
import { useScreenAnalytics } from "@applicaster/zapp-react-native-utils/analyticsUtils/helpers/hooks";

const logger = componentsLogger.addSubsystem("ScreenResolver");

type Props = {
  screenType: string;
  screenId: string;
  screenData: any;
  feedId?: string;
  feedTitle?: string;
  focused?: boolean;
  parentFocus?: {
    nextFocusDown?: React.Ref<any>;
    nextFocusRight?: React.Ref<any>;
    nextFocusLeft?: React.Ref<any>;
    nextFocusUp?: React.Ref<any>;
  };
  groupId?: string;
};

export function ScreenResolverComponent(props: Props) {
  useScreenAnalytics(props);

  const { screenType, screenId, screenData, groupId } = props;

  const { hookPlugin } = screenData || {};

  const { components, plugins, rivers } = usePickFromState([
    "components",
    "plugins",
    "rivers",
  ]);

  const {
    videoModalState: { mode },
  } = useNavigation();

  const [, setScreenContext] = ZappPipesScreenContext.useZappPipesContext();

  React.useEffect(() => {
    setScreenContext(rivers[screenId]);
  }, [screenId]);

  const ScreenPlugin =
    findPluginByType(screenType, plugins, { skipWarning: true }) ||
    findPluginByIdentifier(screenType, plugins) ||
    findPluginByIdentifier(hookPlugin && hookPlugin.identifier, plugins) ||
    components[toPascalCase(screenType)];

  if (screenType === "favorites") {
    return <Favorites screenData={screenData} />;
  }

  if (screenType === "link") {
    return <LinkHandler screenData={screenData} />;
  }

  if (screenType === "playable") {
    return (
      // @ts-ignore
      <HandlePlayable
        item={screenData}
        mode={mode === "PIP" ? "PIP" : "FULLSCREEN"}
        isModal={false}
        groupId={groupId}
      />
    );
  }

  if (hookPlugin || screenType === "hooks") {
    return (
      screenData && (
        <HookRenderer
          screenData={screenData}
          focused={props.focused}
          parentFocus={props.parentFocus as ParentFocus}
        />
      )
    );
  }

  const ScreenComponent =
    path(["module", "Component"], ScreenPlugin) ||
    prop("module", ScreenPlugin) ||
    prop("Component", ScreenPlugin) ||
    ScreenPlugin;

  const configuration =
    prop("configuration", ScreenPlugin) ||
    prop("__plugin_configuration", ScreenComponent);

  if (ScreenComponent) {
    return (
      <ScreenComponent
        {...props}
        screenId={screenId}
        screenData={screenData}
        configuration={configuration}
      />
    );
  }

  logger.warning({
    message: "Could not resolve screen plugin",
    data: props,
  });

  return null;
}

export const ScreenResolver = ZappPipesScreenContext.withProvider(
  ScreenResolverComponent
);
