import React, { memo } from 'react';
import { Dimensions, 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 { Skeleton } from './skeleton';
import { SBox } from '../../common/s-components/layout/s-box';
import { addSafeArea } from '../../common/transducers';
// import { RefillingIndicator } from '../../common/components/refilling-indicator';
import { TState, TState as TYoutubelistState } from '../types';
import { TEntityVisibility, TRefreshableRenderer } from '../../common/types';
import { Arc } from '../../common/components/arc';
import { SImage } from '../../common/s-components/s-image';
import { Header } from './header';
import { Filter } from './filter';
import { SFilterContainer } from '../s-components/s-filter-container';
import { InfinityList } from './infinity-list';
import { CARD_OUTER_HEIGHT, INFO_POPUP } from '../constants';
import { SBgImageContainer } from '../s-components/s-bg-image-container';
import { SBgBody } from '../s-components/s-bg-body';
import { fp as _ } from '../../common/utils/fp';
import { TData as TTrackData } from '../../track/types';
import { Portal } from '../../common/utils/portal/portal';
import { SwipeablePopup } from '../../common/components/bottom-sheet/swipeable-popup';
import { InfoPopup } from './info-popup';
import { AllVideos } from './all-videos';
import { ROUTES } from '../../app/constants';
import { useNanoId } from '../../common/hooks/use-nano';

const maxHeight = addSafeArea(78);
const { height: DEVICE_HEIGHT } = Dimensions.get('window');

type TProps = {
  data: TYoutubelistState['data'];
  refreshing: boolean;
  refresh: () => void;
  visibility: TEntityVisibility;
  trackData: TTrackData | {};
  streamsLatestDate: TState['streamsLatestDate'];
};

export const Youtubelist = memo((props: TProps) => {
  const {
    data,
    visibility,
    trackData,
    streamsLatestDate,
    refreshing,
    refresh,
  } = props;
  const id = useNanoId();

  const renderFgLayer = () => {
    const date = _.path('data.date', streamsLatestDate);

    return (
      <Portal id={`${INFO_POPUP}:${id}`} updateIfAnyChanged={{ date }}>
        <SwipeablePopup
          variant={INFO_POPUP}
          content={<InfoPopup streamsLatestDate={date} />}
        />
      </Portal>
    );
  };

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

    const imageUrl = _.path('image_url', trackData);
    const containerHeight = DEVICE_HEIGHT * 0.7;
    const gradientHeight = DEVICE_HEIGHT * 0.57;

    return (
      <SBox height={containerHeight} position="relative">
        {imageUrl ? (
          <>
            <SBgImageContainer>
              <SImage
                height={375}
                width={1}
                resizeMode="cover"
                source={{
                  uri: imageUrl,
                }}
              />
            </SBgImageContainer>

            <LinearGradient
              colors={theme.gradients.marketsTrackAvatar}
              locations={[0, 0.54, 1]}
              style={[StyleSheet.absoluteFill, { height: 375 }]}
            />
            <LinearGradient
              colors={theme.gradients.trackShadow}
              locations={[0, 0.54, 1]}
              style={{ height: 102, top: 290 }}
            />
          </>
        ) : null}

        <LinearGradient
          colors={theme.gradients.youtube}
          style={[
            StyleSheet.absoluteFill,
            { flex: 1, height: gradientHeight, opacity: 0.8 },
          ]}
        />
      </SBox>
    );
  };

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

  const renderBody: TRefreshableRenderer = () => {
    const items = _.path('data', data);
    const isAndroid = Platform.OS === 'android';
    const viewNetworkFailedOffset = isAndroid ? -60 : 128;
    const buttonIsShown = _.length(items) > 1;
    const itemsCount = _.length(items);
    const youtubeVideoIds = _.map<any, any>(_.path('id'))(items).toString();
    const arcPosition = isAndroid ? 113 : 138;
    const bgPosition = isAndroid ? 143 : 168;

    return (
      <>
        <SBox position="relative" flex={1} pt={maxHeight}>
          <SBgBody
            topPosition={
              buttonIsShown ? bgPosition : visibility.skeleton ? 169 : 196
            }
          />
          <SBox
            position="absolute"
            top={buttonIsShown ? arcPosition : visibility.skeleton ? 139 : 166}
          >
            <Arc />
          </SBox>

          {visibility.skeleton && <Skeleton />}
          {visibility.error && (
            <ViewLoadFailed variant="youtube-list" verticalOffset={126} />
          )}
          {visibility.offline && (
            <ViewNetworkFailed verticalOffset={viewNetworkFailedOffset} />
          )}

          {visibility.data && (
            <SBox mb={66}>
              {buttonIsShown ? (
                <AllVideos total={itemsCount} videoIds={youtubeVideoIds} />
              ) : null}
              <SFilterContainer>
                <Filter
                  color={buttonIsShown ? 'periwinkleGray' : 'white'}
                  title="Global Lifetime Views"
                />
              </SFilterContainer>
              <SBox px={16} mt={-15}>
                <InfinityList
                  cardOuterHeight={CARD_OUTER_HEIGHT}
                  items={items}
                />
                {/*{refilling && <RefillingIndicator />}*/}
              </SBox>
            </SBox>
          )}
        </SBox>
      </>
    );
  };

  const indicatorOffset = maxHeight - 20;

  return (
    <RefreshableView
      loading={refreshing}
      indicatorLight
      indicatorOffsetTop={indicatorOffset}
      // inifite pagination - get next page when we don't have payload
      // onScrollReachBottom={() => getData('infinite')}
      onPullDown={() => !visibility.skeleton && refresh()}
      renderHeader={renderHeader}
      renderBody={renderBody}
      renderBgLayer={renderBgLayer}
      renderFgLayer={renderFgLayer}
      name={ROUTES.youtubelist}
      withNativeDriver
    />
  );
});
