import * as React from "react";
import * as R from "ramda";
import { Platform, View, ViewStyle } from "react-native";
import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
import { isTV, isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
import { PlayerLiveImage } from "../../../VideoLive/PlayerLiveImageComponent";
import Image from "../Image";
import { useTrackCurrentAutoScrollingElement } from "@applicaster/zapp-react-native-utils/reactHooks/autoscrolling/useTrackCurrentAutoScrollingElement";
import { useUIComponentContext } from "@applicaster/zapp-react-native-ui-components/Contexts/UIComponentContext";
import { getPropComponentType } from "@applicaster/zapp-react-native-utils/cellUtils";
import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";

type LiveImageProps = {
  item: ZappEntry;
  style: Record<string, any>;
  cellUUID?: string;
  actionIdentifier?: string;
  imageKey?: string;
  state: "focused" | "unfocused" | "selected";
  audio_muted_by_default?: boolean;
  uri: string; // cover image url
};

const DEFAULT_PLAYER_IDENTIFIER = "QuickBrickPlayerPlugin";
const KALTURA_PLAYER_IDENTIFIER = "KalturaPlayerPlugin";

const knownMediaExtensions = {
  m3u8: "application/x-mpegURL",
  m4v: "video/mp4",
  mkv: "video/x-matroska",
  mov: "video/mp4",
  mp3: "audio/mpeg",
  mp4: "video/mp4",
  mpd: "application/dash+xml",
  oga: "audio/ogg",
  ogv: "video/ogg",
  opus: "video/ogg",
};

const isSupportedTVForLiveImage = () => {
  if (isWeb()) {
    const osVersion = Platform.Version as string;
    const platformOS = Platform.OS as QuickBrickPlatforms;

    const parsedOsVersion = parseFloat(osVersion);

    if (platformOS === "lg_tv") {
      if (isNaN(parsedOsVersion)) {
        // it's browser
        return true;
      }

      return parsedOsVersion >= 5.0;
    }

    if (platformOS === "samsung_tv") {
      if (isNaN(parsedOsVersion)) {
        // it's browser
        return true;
      }

      return parsedOsVersion >= 4.0;
    }
  } else {
    return true;
  }
};

const isVideoUrl = (streamUrl: string): boolean => {
  // TODO: Not the best. Will fail if there is query params
  for (const key in knownMediaExtensions) {
    if (streamUrl.endsWith(key)) {
      return true;
    }
  }

  return false;
};

const removeAdsFromEntry = (entry) => {
  if (!entry?.extensions?.video_ads) {
    return entry;
  }

  const newEntry = R.clone(entry);

  delete newEntry.extensions.video_ads;

  return newEntry;
};

const prepareEntry = (entry) => {
  if (!entry) {
    return null;
  }

  if (entry.extensions?.preview_playback) {
    return {
      ...entry,
      content: { ...entry?.content, src: entry?.extensions?.preview_playback },
    };
  }

  if (entry.content?.teaser) {
    return {
      ...entry,
      content: { ...entry?.content, src: entry?.content?.teaser },
    };
  }

  const previewPlayback =
    entry.extensions?.["brightcove"]?.["preview_playback"];

  if (previewPlayback) {
    return {
      ...entry,
      extensions: {
        ...entry.extensions,
        brightcove: {
          ...entry?.extensions?.["brightcove"],
          video_id: previewPlayback,
        },
      },
    };
  }

  if (entry.extensions?.["brightcove"]?.["video_id"]) {
    return entry;
  }

  const src = entry.content?.src;

  if (!src) {
    return null;
  }

  if (entry.content?.type?.startsWith("video")) {
    return entry;
  }

  return isVideoUrl(src) ? entry : null;
};

const getPlayableEntry = (entry) => {
  const preparedEntry = prepareEntry(entry);

  if (!preparedEntry) {
    return null;
  }

  return removeAdsFromEntry(preparedEntry);
};

function getFocusedState(
  state: string,
  componentType: string,
  isCurrentlyFocused: boolean
) {
  if (isTV()) {
    return state === "focused";
  } else {
    // only horizontal_list_qb should work with isCurrentlyFocused
    return componentType === "horizontal_list_qb" ? isCurrentlyFocused : true;
  }
}

const getPlayerConfig = (player_screen_id, actionIdentifier) => {
  if (player_screen_id) {
    const rivers = appStore.get("rivers");
    const playerScreen = rivers?.[player_screen_id] ?? null;

    // TODO: Check is it a player later

    // TODO: Add more dict if needed from the screen component, styles, data etc
    return {
      playerPluginId: playerScreen?.type ?? DEFAULT_PLAYER_IDENTIFIER,
      screenConfig: playerScreen?.["general"],
    };
  }

  if (!actionIdentifier) {
    return null;
  }

  const isPlayer: boolean = [
    DEFAULT_PLAYER_IDENTIFIER,
    KALTURA_PLAYER_IDENTIFIER,
  ].includes(actionIdentifier);

  if (!isPlayer) {
    return null;
  }

  return { playerPluginId: actionIdentifier };
};

const positionAbsolute: ViewStyle = { position: "absolute" };

const LiveImageComponent = (props: LiveImageProps) => {
  const {
    item,
    style: componentStyle,
    cellUUID,
    imageKey,
    actionIdentifier,
    state,
  } = props;

  const component = useUIComponentContext();

  // Fix for blinking on state change
  const style = React.useMemo(
    () => ({ ...componentStyle, backgroundColor: "transparent" }),
    [componentStyle]
  );

  const componentType = React.useMemo(
    () => getPropComponentType(component),
    [component?.id]
  );

  const {
    id: componentId,
    rules: { player_screen_id, audio_muted_by_default = false },
  } = component;

  const isCurrentlyFocused = useTrackCurrentAutoScrollingElement(componentId);

  const { playerPluginId, screenConfig } =
    getPlayerConfig(player_screen_id, actionIdentifier) ?? {};

  const playableEntry = playerPluginId ? getPlayableEntry(item) : null;
  const plugins = appStore.get("plugins");

  const playerPlugin = findPluginByIdentifier(playerPluginId, plugins);

  const isShouldRender =
    playerPlugin &&
    getFocusedState(state, componentType, isCurrentlyFocused) &&
    playableEntry &&
    cellUUID &&
    isSupportedTVForLiveImage();

  return (
    <>
      <Image {...props} applyMaxSize />
      {isShouldRender && (
        <View style={[style, positionAbsolute]}>
          <PlayerLiveImage
            uri={props.uri}
            playerId={cellUUID}
            playerPluginId={playerPluginId}
            screenConfig={screenConfig}
            style={style}
            imageKey={imageKey}
            item={playableEntry}
            audioMutedByDefault={audio_muted_by_default}
          />
        </View>
      )}
    </>
  );
};

export const LiveImage = React.memo<LiveImageProps>(LiveImageComponent);
