import React, { memo, useCallback } from 'react';
import { StyleSheet } from 'react-native';
import throttle from 'lodash/throttle';
import { RefreshableView } from '../../common/components/refreshable-view';
import { theme } from '../../app/theme';
import { SBoxAnimated } from '../../common/s-components/layout/s-box-animated';
import { ViewNetworkFailed } from '../../common/components/view-network-failed';
import { SBox } from '../../common/s-components/layout/s-box';
import { addSafeArea } from '../../common/transducers';
import { TRoute, TState as TPlaylistPlacementState, TState } from '../types';
import {
  NEntityInfinite,
  TEntityVisibility,
  TRefreshableRenderer,
  TVendor,
} from '../../common/types';
import { fp as _ } from '../../common/utils/fp';
import { SHeaderBg } from '../../track/s-components/s-header-bg';
import { SHeaderGradient } from '../../track/s-components/s-header-gradient';
import { PlaylistCard } from './card-playlist';
import { TrackCard } from './card-track';
import { FETCH_TYPE } from '../../common/constants';
import { ROUTES } from '../../app/constants';
import { Header } from './header';
import { Tracklist } from '../../playlist-tracklist-core';
import { TTracklistExtended } from '../../playlist-tracklist-core/types';
import { TRACKLIST_VARIANT } from '../../playlist-tracklist-core/constants';
import { Navigator } from '../services';
import { ENAVIGATION_VARIANT } from '../constants';
// import { TToggleStarred } from '../../common/submodules/starring-tracks/types';

const maxHeight = addSafeArea(62);

type TProps = {
  data: TPlaylistPlacementState['data'];
  trackData: TPlaylistPlacementState['trackData'];
  playlistData: TPlaylistPlacementState['playlistData'];
  getTracklist: NEntityInfinite.TEntityInfiniteGet;
  refreshing: boolean;
  refresh: () => void;
  visibility: TEntityVisibility;
  tracklist: TTracklistExtended;
  trackStreams: TPlaylistPlacementState['trackStreams'];
  // toggleStarred: TToggleStarred;
  isTrackStarred: boolean;
  config: TState['config'];
  route: TRoute;
};

export const PlaylistPlacement: React.FC<TProps> = memo(props => {
  const {
    trackData,
    visibility,
    tracklist,
    playlistData,
    data,
    config,
    refreshing,
    trackStreams,
    isTrackStarred,
    getTracklist,
    route,
    refresh,
  } = props;

  // NESTED_NAVIGATION::1
  // TODO: move it to single place
  const onCardPress = throttle(params => {
    Navigator.next({
      variant: ENAVIGATION_VARIANT.track,
      params,
    });
  }, 1000);

  const renderHeader: TRefreshableRenderer = ({
    animationY,
    scrollToTop /*, isScrolled*/,
  }) => {
    const { placementVariant } = config;
    return (
      <Header
        trackData={trackData}
        playlistData={playlistData}
        visibility={visibility}
        tracklist={tracklist}
        data={data}
        animationY={animationY}
        scrollToTop={scrollToTop}
        placementVariant={placementVariant}
        refreshing={refreshing}
      />
    );
  };

  const renderOffline = () => {
    return (
      <SBoxAnimated position="relative" flex={1} pt={34}>
        <ViewNetworkFailed verticalOffset={34} />
      </SBoxAnimated>
    );
  };

  const renderBody: TRefreshableRenderer = useCallback(() => {
    const { placementVariant } = config;
    const personalized = _.path('data.personalized', data);

    if (visibility.offline) return renderOffline();

    return (
      <>
        <SBoxAnimated position="relative" flex={1} pt={maxHeight}>
          <SBox mt={50} position="relative">
            <SBox
              style={[StyleSheet.absoluteFill, { top: 10 }]}
              bg="ebonyClay"
            />
            <PlaylistCard
              playlistData={playlistData}
              data={data}
              route={route}
            />
            <TrackCard
              data={data}
              trackData={trackData}
              trackStreams={trackStreams}
              isTrackStarred={isTrackStarred}
              placementVariant={placementVariant}
            />
          </SBox>
          <Tracklist
            testID="playlist-placement-tracklist"
            visibility={visibility}
            tracklist={tracklist}
            getTracklist={getTracklist}
            personalized={personalized}
            vendor={_.path('vendor', trackData) as TVendor}
            playlistVendor={_.path('playlistVendor', playlistData) as TVendor}
            isrc={_.path('isrc', trackData) as string}
            variant={TRACKLIST_VARIANT.playlistPlacement}
            onCardPress={onCardPress}
          />
        </SBoxAnimated>
      </>
    );
  }, [
    visibility,
    trackData,
    playlistData,
    tracklist,
    trackStreams,
    isTrackStarred,
    getTracklist,
    data,
    config,
    route,
  ]);

  const renderBgLayer2: TRefreshableRenderer = () => {
    const imageUrl = _.path('imageUrl', trackData);

    if (visibility.offline) return false;

    return (
      <SBox position="relative" height={400}>
        {imageUrl ? (
          <SHeaderBg top={-49} source={{ uri: imageUrl }} />
        ) : (
          <SBox
            height={375}
            width="100%"
            position="absolute"
            top={0}
            bg={theme.colors.lavenderGray}
          />
        )}

        <SHeaderGradient
          height={375}
          colors={theme.gradients.playlistPlacement}
          locations={[0, 0.44, 0.86, 1]}
          top={-40}
        />
      </SBox>
    );
  };

  return (
    <RefreshableView
      testID="playlist-placemnets-refreshable-view"
      indicatorLight
      loading={refreshing}
      indicatorOffsetTop={maxHeight}
      // inifite pagination - get next page when we don't have payload
      onScrollReachBottom={() => {
        if (!tracklist.loading) {
          getTracklist(null, FETCH_TYPE.refill);
        }
      }}
      onPullDown={() => !visibility.skeleton && refresh()}
      renderHeader={renderHeader}
      renderBgLayer2={renderBgLayer2}
      renderBody={renderBody}
      name={ROUTES.playlistplacement}
      withNativeDriver
      withoutBottomTabNavigator
    />
  );
});
