import React, { memo } from 'react';
import { Animated, Pressable } from 'react-native';
import { SText } from '../../common/s-components/typography/s-text';
import { fp as _ } from '../../common/utils/fp';
import { SRow } from '../../common/s-components/layout/s-row';
import { SBox } from '../../common/s-components/layout/s-box';
import { SBlueDot } from '../../common/s-components/s-blue-dot';
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 { SH6 } from '../../common/s-components/typography/s-h6';
import { SPersonalizedLabel } from '../../common/s-components/s-personalized-label';
import { BackButton } from '../../common/components/back-button';
import {
  addSafeArea,
  formatStreamDigit,
  getDaysAgoLabel,
  getStatusBarHeight,
  getAnimations,
} from '../../common/transducers';
import { TState as TPlaylistPlacementState } from '../types';
import { Router } from '../../common/utils/navigation-service';
import { ORDER_BY } from '../../playlist-tracklist-core/constants';
import { TTracklistExtended } from '../../playlist-tracklist-core/types';
import { TEntityVisibility } from '../../common/types';
import { SkeletonsSmall } from '../../common/components/skeleton-small';
import { Icon } from '../../common/components/icon';
import { SHeaderPlaylistName } from '../s-components/s-header-playlist-name';
import { ROUTES } from '../../app/constants';
import { navHistoryCache } from '../services';
import { ENAVIGATION_VARIANT } from '../constants';
import { PositionTrends } from '../../common/components/position-trends';

const maxHeight = addSafeArea(62);
const minHeight = addSafeArea(52);
const safeArea = getStatusBarHeight();
const heightDiff = maxHeight - minHeight;

type TProps = {
  data: TPlaylistPlacementState['data'];
  trackData: TPlaylistPlacementState['trackData'];
  playlistData: TPlaylistPlacementState['playlistData'];
  visibility: TEntityVisibility;
  tracklist: TTracklistExtended;
  animationY: Animated.Value;
  scrollToTop: Function;
  placementVariant?: string;
  refreshing: boolean;
};

const Animation = getAnimations({
  title: {
    opacity: {
      inputRange: [0, heightDiff / 2, heightDiff],
      outputRange: [1, 0, 0],
    },
    translateY: safeArea + 12,
  },

  titleSmall: {
    opacity: {
      inputRange: [0, heightDiff / 2, heightDiff],
      outputRange: [0, 0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 20, safeArea + 12],
    },
  },

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

  headerBg: {
    opacity: {
      inputRange: [0, heightDiff],
      outputRange: [0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [0, -heightDiff],
    },
  },
});

export const Header: React.FC<TProps> = memo(props => {
  const {
    data,
    playlistData,
    tracklist,
    trackData,
    visibility,
    animationY,
    scrollToTop,
    placementVariant,
    refreshing,
  } = props;
  const renderHeaderPlaylistAdded = () => {
    const playlistAdded = _.path('data.addedDate', data);
    const loading = _.path('loading', data);

    if (loading) return null;

    return _.isNil(playlistAdded) ? (
      <SText mt={2}>N/A</SText>
    ) : (
      <SText sm pt={4}>
        {getDaysAgoLabel(playlistAdded)}
      </SText>
    );
  };

  const renderHeaderPlaylistRemoved = () => {
    const playlistName = _.path('playlistName', playlistData);
    const playlistVendor = _.path('playlistVendor', playlistData);
    const isSpotify = playlistVendor === 'spotify';

    return (
      <SBox alignItems="center" mt={-1}>
        <SRow ml={-1}>
          <SBox mr={8} mt={isSpotify ? 1 : 0}>
            <Icon name={playlistVendor} size={22} color={theme.colors.white} />
          </SBox>
          <SBox maxWidth={162}>
            <SHeaderPlaylistName numberOfLines={1}>
              {_.isNil(playlistName) ? 'N/A' : playlistName}
            </SHeaderPlaylistName>
          </SBox>
        </SRow>
      </SBox>
    );
  };

  const renderHeaderPlaylistPosition = () => {
    const trend = _.path('data.trend', data);
    const playlistPosition = _.path('data.position', data);
    const positionTrend = {
      value: trend,
      valueFormatted: formatStreamDigit(trend),
    };
    const isNew = _.path('data.isNew', data);
    const loading = _.path('loading', data);

    if (loading) return null;

    return (
      <SRow mt={2}>
        {playlistPosition ? (
          <SBox mr={6}>
            <SText>
              #
              {formatStreamDigit(playlistPosition as number, {
                addComma: true,
              })}
            </SText>
          </SBox>
        ) : (
          <SBox>
            <SText>N/A</SText>
          </SBox>
        )}

        {!!trend && playlistPosition ? (
          <PositionTrends trend={positionTrend} mt={2} ml={3} />
        ) : null}
        {isNew ? <SBlueDot ml={11} mt={5} /> : null}
      </SRow>
    );
  };

  const renderHeaderPlaylist = () => {
    const personalized = _.path('data.personalized', data);
    const orderBy = _.path('config.orderBy', tracklist);

    if (orderBy === ORDER_BY.position && personalized) {
      return null;
    }

    return orderBy !== ORDER_BY.position
      ? renderHeaderPlaylistAdded()
      : renderHeaderPlaylistPosition();
  };

  const personalized = _.path('data.personalized', data);
  const dataLoading = _.path('loading', data);
  const orderBy = _.path('config.orderBy', tracklist);
  const isCenteredPersonalized = orderBy === ORDER_BY.position && personalized;

  return (
    <>
      {!visibility.offline ? (
        <>
          <SBoxAnimated
            style={Animation.headerBg(animationY)}
            height={maxHeight}
            bg={theme.colors.vulcan}
            position="absolute"
            width={1}
          />
          <SBoxAnimated
            style={Animation.title(animationY)}
            alignItems="center"
            width={1}
            position="absolute"
          >
            <SBox width={224} mb={9}>
              <SH3 numberOfLines={1} textAlign="center">
                {_.path('name', trackData)}
              </SH3>
            </SBox>
            <SRow height={16} alignItems="center" testID="track-in-playlist">
              {!dataLoading || refreshing ? (
                <>
                  <SH6 color={theme.colors.periwinkleGray}>
                    {_.toUpper('Track in Playlist')}
                  </SH6>
                  {personalized ? (
                    <SPersonalizedLabel ml={8}>
                      <SH6>P</SH6>
                    </SPersonalizedLabel>
                  ) : null}
                </>
              ) : (
                <SkeletonsSmall width={192} mb={9} />
              )}
            </SRow>
          </SBoxAnimated>
          <SBoxAnimated
            style={Animation.titleSmall(animationY)}
            width={1}
            position="absolute"
          >
            <Pressable onPress={() => scrollToTop()}>
              {placementVariant === 'past' ? (
                renderHeaderPlaylistRemoved()
              ) : (
                <SRow justifyContent="space-between" pr={16} pl={77}>
                  <SBox
                    width={isCenteredPersonalized ? 230 : 192}
                    alignItems="flex-start"
                  >
                    <SH3 numberOfLines={1}>{_.path('name', trackData)}</SH3>
                  </SBox>
                  {renderHeaderPlaylist()}
                </SRow>
              )}
            </Pressable>
          </SBoxAnimated>
        </>
      ) : null}
      <SBoxAnimated style={[Animation.arrow(animationY)]} position="absolute">
        <BackButton
          testID="playlist-placement-back-button"
          onPress={() => {
            const lastHistory = navHistoryCache.last();
            if (
              lastHistory &&
              lastHistory.variant === ENAVIGATION_VARIANT.track
            ) {
              Router.setParamsFor(ROUTES.track, {
                gesturesDisabled: true,
                noAnimation: true,
              });
            } else {
              Router.setParamsFor(ROUTES.track, {
                gesturesDisabled: false,
                noAnimation: false,
              });
            }

            Router.goBack();
          }}
          fixed
        />
      </SBoxAnimated>
    </>
  );
});
