import React from 'react';
import { Platform, StyleSheet } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import { RefreshableView } from '../../common/components/refreshable-view';
import { theme } from '../../app/theme';
import { ViewLoadFailed } from '../../common/components/view-load-failed';
import { ViewNetworkFailed } from '../../common/components/view-network-failed';
import { SBox } from '../../common/s-components/layout/s-box';
import { addSafeArea } from '../../common/transducers';
import { TAllVideosVisibility, TState as TYoutubeState } from '../types';
import { TEntityVisibility, TRefreshableRenderer } from '../../common/types';
import { TrackCard } from './track-card/track-card';
import { Header } from './header';
import { fp as _ } from '../../common/utils/fp';
import { SBgImageContainer } from '../../youtube-list/s-components/s-bg-image-container';
import { SImage } from '../../common/s-components/s-image';
import { Slider } from './slider/slider';
import YoutubePerformance from '../../youtube-performance';
import YoutubeMarkets from '../../youtube-markets';
import YoutubeDemographics from '../../youtube-demographics';
import { RotationOverlay } from '../../common/components/rotation-overlay';
import { Wave } from './wave';
import { TState as TDemographicsState } from '../../youtube-demographics/types';
import { AllVideos } from './all-videos/all-videos';
import { MULTIPLE_VARIANT, SINGLE_VARIANT } from '../constants';
import { TData as TTrackData } from '../../track/types';
import { makePerformanceVisibilitySelector } from '../../youtube-performance/selectors';
import { ReduxState } from '../../common/utils/redux';
import { SWaveMask } from '../s-components/s-wave-mask';
import { ROUTES } from '../../app/constants';

const maxHeight = addSafeArea(20);

type TProps = {
  data: TYoutubeState['data'];
  refreshing: boolean;
  refresh: () => void;
  visibility: TEntityVisibility;
  demographics: TDemographicsState['demographics'];
  youtubeVariant: string;
  trackData: TTrackData | {};
  visibilityAllVideos: TAllVideosVisibility;
  wavePosition: number;
};

export const Youtube: React.FC<TProps> = props => {
  const {
    data,
    refreshing,
    refresh,
    visibility,
    youtubeVariant,
    trackData,
    visibilityAllVideos,
    demographics,
    wavePosition,
  } = props;
  const isSingle = youtubeVariant === SINGLE_VARIANT;

  const renderHeader: TRefreshableRenderer = ({
    animationY,
    scrollToTop /*, isScrolled*/,
  }) => {
    return (
      <Header
        animationY={animationY}
        scrollToTop={scrollToTop}
        youtubeVariant={youtubeVariant}
      />
    );
  };

  const renderBgLayer: TRefreshableRenderer = () => {
    if (visibility.offline || visibility.error || visibilityAllVideos.offline) {
      return null;
    }

    const imageUrl =
      youtubeVariant === SINGLE_VARIANT
        ? _.path('data.imageUrl', data)
        : _.path('image_url', trackData);
    const containerHeight = 375;
    const imageWidth = youtubeVariant === SINGLE_VARIANT ? 680 : 1;

    return (
      <SBox position="relative" height={containerHeight}>
        {imageUrl ? (
          <SBgImageContainer opacity={0.4}>
            <SImage
              height={containerHeight}
              width={imageWidth}
              alignSelf="center"
              source={{
                uri: imageUrl,
              }}
            />
          </SBgImageContainer>
        ) : null}

        <LinearGradient
          colors={theme.gradients.youtube1}
          locations={[0, 0.42, 1]}
          style={[
            StyleSheet.absoluteFill,
            { flex: 1, height: containerHeight },
          ]}
        />
        <LinearGradient
          colors={theme.gradients.youtube2}
          locations={[0, 1]}
          style={[
            StyleSheet.absoluteFill,
            { flex: 1, height: 243, opacity: 0.8 },
          ]}
        />
      </SBox>
    );
  };

  const renderBody: TRefreshableRenderer = ({ animationY }) => {
    const data = _.path('data', demographics);
    const noData =
      data && _.isNull(_.path('data.age_band_most_popular', demographics));
    const isIos = Platform.OS === 'ios';
    const isSingle = youtubeVariant === SINGLE_VARIANT;
    const gradientTopIos = isSingle ? 315 : 265;
    const gradientTopAndroid = isSingle ? 296 : 219;
    const failedToLoadVariant = isSingle ? 'youtube-video' : 'youtube-videos';
    const waveIsShown = data || noData || _.path('error', demographics);

    if (visibility.offline || visibilityAllVideos.offline) {
      return (
        <SBox flex={1}>
          <ViewNetworkFailed verticalOffset={6} />
        </SBox>
      );
    }

    if (visibility.error && !visibility.offline) {
      return (
        <SBox flex={1}>
          <ViewLoadFailed variant={failedToLoadVariant} verticalOffset={2} />
        </SBox>
      );
    }

    return (
      <>
        <SBox position="relative" flex={1} pt={maxHeight}>
          <TrackCard animationY={animationY} />
          <LinearGradient
            colors={theme.gradients.trackMarkets}
            locations={[0, 0.55, 1]}
            style={[
              StyleSheet.absoluteFill,
              {
                flex: 1,
                height: 123,
                top: isIos ? gradientTopIos : gradientTopAndroid,
              },
            ]}
          />
          {youtubeVariant === SINGLE_VARIANT ? <Slider /> : null}
          {youtubeVariant === MULTIPLE_VARIANT ? <AllVideos /> : null}
          <SBox width={1} height={28} />

          <SBox position="relative">
            <YoutubePerformance />
            <YoutubeDemographics />
            <YoutubeMarkets />
            <SWaveMask />
            {waveIsShown ? <Wave topPosition={wavePosition} /> : null}
          </SBox>
        </SBox>
      </>
    );
  };

  const renderFgLayer2 = () => <RotationOverlay />;

  return (
    <RefreshableView
      loading={refreshing}
      indicatorLight
      indicatorOffsetTop={maxHeight - 20}
      // inifite pagination - get next page when we don't have payload
      // onScrollReachBottom={() => getData('infinite')}
      onPullDown={() => {
        // in multiple variant we don't have visibility for child modules
        const isLoading = isSingle
          ? visibility.skeleton
          : makePerformanceVisibilitySelector()(ReduxState.getState()).skeleton;
        return !isLoading && refresh();
      }}
      renderHeader={renderHeader}
      renderBgLayer={renderBgLayer}
      renderBody={renderBody}
      renderFgLayer2={renderFgLayer2}
      name={ROUTES.youtube}
      withNativeDriver
    />
  );
};
