import React, { memo } from 'react';
import { Animated, Dimensions, Pressable } from 'react-native';
import { SBox } from '../../common/s-components/layout/s-box';
import { SBoxAnimated } from '../../common/s-components/layout/s-box-animated';
import { theme } from '../../app/theme';
import { SH3 } from '../../common/s-components/typography/s-h3';
import { BackButton } from '../../common/components/back-button';
import {
  addSafeArea,
  getStatusBarHeight,
  getAnimations,
} from '../../common/transducers';
import { Router } from '../../common/utils/navigation-service';
import { fp as _ } from '../../common/utils/fp';
import { StarredBtn } from './starred/starred-btn';
import { /*TRoute,*/ TState as TTrackState, TVisibilityConfig } from '../types';
import { TVisibility as TVisibilityTrackCharts } from '../../track-charts/types';
import { TRouteParams, TState as TCommonState } from '../../common/types';
import { TVisibility as TVisibilityTrackMarkets } from '../../track-markets/types';
import { TVisibility as TVisibilityTrackPlaylists } from '../../track-playlists/types';
import { TopSliderShade } from '../../common/components/animation/top-slider-shade';
import TopSlider from '../containers/top-slider';
import {
  goToPlacement,
  navHistoryCache,
} from '../../playlist-placement/services';
import { ROUTES } from '../../app/constants';
import { ENAVIGATION_VARIANT } from '../../playlist-placement/constants';
import { getOptimistic } from '../transducers';
import { PAGES, updatePageMeta } from '../../analytics';
import { EPlaylistSourcePage } from '../../analytics/types';

const { width: DEVICE_WIDTH } = Dimensions.get('window');
const maxHeight = addSafeArea(88);
const minHeight = addSafeArea(54);
const safeArea = getStatusBarHeight();
const heightDiff = maxHeight - minHeight;

type TProps = {
  animationY: Animated.Value;
  scrollToTop: Function;
  track: TTrackState['track'];
  starred: boolean;
  toggleStarred: () => void;
  routeParams?: TRouteParams;
  visibility: TVisibilityConfig;
  visibilityCharts: TVisibilityTrackCharts;
  visibilityMarkets: TVisibilityTrackMarkets;
  visibilityPlaylists: TVisibilityTrackPlaylists;
  // route: TRoute;
  isScrolled: boolean;
  starredTracks: TCommonState['starred'];
};

const Animation = getAnimations({
  headerBg: {
    opacity: {
      inputRange: [0, heightDiff],
      outputRange: [0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [0, -heightDiff],
    },
  },

  titleSmall: {
    opacity: {
      inputRange: [0, heightDiff + 20],
      outputRange: [0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 48, safeArea + 13],
    },
  },

  arrow: {
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 12, safeArea + 2],
    },
    translateX: 16,
  },

  star: {
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 11, safeArea + 1],
    },
    translateX: -16,
  },
});

export const Header: React.FC<TProps> = memo(props => {
  const {
    animationY,
    scrollToTop,
    track,
    starred,
    toggleStarred,
    routeParams,
    visibility,
    visibilityCharts,
    visibilityMarkets,
    visibilityPlaylists,
    isScrolled,
    starredTracks,
  } = props;
  const goBack = () => {
    const lastHistory = navHistoryCache.last();

    if (lastHistory && lastHistory.variant === ENAVIGATION_VARIANT.playlist) {
      // it means that track doesn't have close icon and close icon is on playlist page
      Router.setParamsFor(ROUTES.playlist, {
        gesturesDisabled: true,
        // noAnimation: true,
      });

      updatePageMeta({
        page: PAGES.Playlist.page,
        source_page: EPlaylistSourcePage.trackPage,
      });

      return Router.goBack();
    }

    if (lastHistory && lastHistory.variant === ENAVIGATION_VARIANT.track) {
      setTimeout(() => {
        scrollToTop(true);
      }, 0);

      return goToPlacement();
    }

    Router.setParamsFor(ROUTES.track, {
      gesturesDisabled: false,
      noAnimation: false,
    });
    Router.setParamsFor(ROUTES.playlist, {
      gesturesDisabled: false,
      noAnimation: false,
    });

    updatePageMeta({
      page: PAGES.Playlist.page,
      source_page: EPlaylistSourcePage.trackPage,
    });

    return Router.goBack();
  };

  const anyOffline =
    _.path('offline', visibility) ||
    _.path('offline', visibilityCharts) ||
    _.path('offline', visibilityMarkets) ||
    _.path('offline', visibilityPlaylists);

  const trackError = _.path('track.error', visibility);

  return (
    <>
      {!anyOffline && !trackError ? (
        <>
          <SBoxAnimated
            style={Animation.headerBg(animationY)}
            height={maxHeight}
            bg={theme.colors.vulcan}
            position="absolute"
            width={1}
          />

          <SBoxAnimated
            style={Animation.titleSmall(animationY)}
            position="absolute"
            alignItems="center"
            width={1}
          >
            <Pressable onPress={() => scrollToTop()}>
              {({ pressed }) => (
                <SBox
                  width={DEVICE_WIDTH - 120}
                  alignItems="center"
                  opacity={pressed ? 0.7 : 1}
                >
                  <SH3
                    testID="track-touchable-text"
                    numberOfLines={1}
                    ellipsizeMode="tail"
                    bold
                  >
                    {_.path('data.name', track)}
                  </SH3>
                </SBox>
              )}
            </Pressable>
          </SBoxAnimated>

          <SBoxAnimated
            style={[Animation.star(animationY)]}
            position="absolute"
            right={0}
          >
            <StarredBtn
              onPress={() => {
                const optimistic = getOptimistic(starredTracks, track);
                if (_.isNotNil(optimistic)) return;
                toggleStarred();
              }}
              starred={starred}
              entityVisibility={_.path('track', visibility)}
            />
          </SBoxAnimated>
        </>
      ) : null}

      <SBoxAnimated style={[Animation.arrow(animationY)]} position="absolute">
        <BackButton
          testID="track-back-button"
          onPress={() => goBack()}
          iconName={
            _.path('gesturesDisabled', routeParams) ? 'close' : undefined
          }
          fixed
        />
      </SBoxAnimated>
      {!isScrolled && !anyOffline && !trackError && visibility.statics.data ? (
        <TopSliderShade>
          <TopSlider />
        </TopSliderShade>
      ) : null}
    </>
  );
});
