import React, { memo } from 'react';
import { Pressable, Animated, Keyboard } from 'react-native';
import { fp as _ } from '../../common/utils/fp';
import { theme } from '../../app/theme';
import { SBoxAnimated } from '../../common/s-components/layout/s-box-animated';
import { SBox } from '../../common/s-components/layout/s-box';
import { SH1 } from '../../common/s-components/typography/s-h1';
import { SRow } from '../../common/s-components/layout/s-row';
import { SearchInput } from '../../common/components/search-input';
import { FETCH_TYPE } from '../../common/constants';
import { SSortingIconContainer } from '../s-components/s-sorting-icon-container';
import { Icon } from '../../common/components/icon';
import { SH3 } from '../../common/s-components/typography/s-h3';
import { BackButton } from '../../common/components/back-button';
import {
  addSafeArea,
  getStatusBarHeight,
  getAnimations,
} from '../../common/transducers';
import { togglePopup } from '../../common/utils/swipeable-popup-service';
import {
  TRoute,
  TState as TTrackChartsScreenState,
  TVisibility,
} from '../types';
import { NEntityInfinite } from '../../common/types';

type TProps = {
  animationY: Animated.Value;
  scrollToTop: Function;
  isScrolled: boolean;
  visibility: TVisibility;
  getData: NEntityInfinite.TEntityInfiniteGet;
  charts: TTrackChartsScreenState['charts'];
  route: TRoute;
  goBack: () => void;
};

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

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

  title: {
    opacity: {
      inputRange: [0, heightDiff / 2, heightDiff / 1.5, heightDiff],
      outputRange: [1, 1, 0, 0],
    },
    translateY: {
      inputRange: [0, heightDiff / 1.5, heightDiff / 1.5, heightDiff],
      outputRange: [safeArea + 20, safeArea + 12, safeArea - 80, safeArea - 80],
    },
  },

  titleSmall: {
    opacity: {
      inputRange: [0, heightDiff / 1.5, heightDiff / 1.4, heightDiff],
      outputRange: [0, 0, 1, 1],
    },
    translateY: {
      inputRange: [0, heightDiff / 1.5, heightDiff],
      outputRange: [safeArea + 68, safeArea + 16, safeArea + 2],
    },
    scaleY: {
      inputRange: [0, heightDiff / 2, heightDiff / 2, heightDiff],
      outputRange: [0, 0, 1, 1],
    },
  },

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

  searchBox: {
    translateY: {
      inputRange: [0, heightDiff / 1.5, heightDiff / 1.5, heightDiff],
      outputRange: [safeArea + 88, safeArea + 76, safeArea + 76, -44],
    },
    opacity: {
      inputRange: [0, heightDiff / 1.5, heightDiff / 1.5, heightDiff],
      outputRange: [1, 1, 0, 0],
    },
  },
  input: {
    translateY: 0,
    scaleY: {
      inputRange: [0, heightDiff / 1.5, heightDiff],
      outputRange: [1, 0, 0],
    },
  },
});

export const Header: React.FC<TProps> = memo(props => {
  const {
    visibility,
    getData,
    charts,
    route,
    animationY,
    scrollToTop,
    isScrolled,
    goBack,
  } = props;
  const params = _.path('params', route);
  const isSpotify = _.pathEq(['provider'], 'spotify', params);
  const title = isSpotify ? 'Spotify Daily Top 200' : 'Apple Music Top 100';

  const sortingIconTappedBg = isSpotify
    ? theme.colorsRgba.surfieGreenPillPressed
    : theme.colorsRgba.discoPillPressed;

  if (visibility.error || visibility.offline) {
    return null;
  }

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

      <SBoxAnimated
        style={Animation.title(animationY)}
        width={1}
        position="absolute"
      >
        <Pressable onPress={() => scrollToTop()}>
          {({ pressed }) => (
            <SBox opacity={pressed && isScrolled ? 0.7 : 1}>
              <SH1
                testID="track-charts-screen-touchable-text"
                textAlign="center"
                numberOfLines={1}
              >
                {title}
              </SH1>
            </SBox>
          )}
        </Pressable>
      </SBoxAnimated>

      <SBoxAnimated
        style={[Animation.searchBox(animationY)]}
        width={1}
        position="absolute"
      >
        <SRow mx={16} overflow="hidden">
          <SBoxAnimated flex={1} style={[Animation.input(animationY)]}>
            <SearchInput
              value={_.path('config.search', charts)}
              placeholder="Find a chart"
              onChange={(search: string) => {
                getData({ search }, FETCH_TYPE.search);
                setTimeout(() => {
                  scrollToTop(true);
                }, 100);
              }}
            />
          </SBoxAnimated>
          <Pressable
            testID="charts-placement-charts-toggle"
            onPress={() => {
              Keyboard.dismiss();
              togglePopup('track-charts-sorting');
            }}
          >
            {({ pressed }) => (
              <SSortingIconContainer
                ml={8}
                opacity={visibility.skeleton ? 0.5 : 1}
                bg={
                  pressed && visibility.data
                    ? sortingIconTappedBg
                    : 'transparent'
                }
              >
                <Icon
                  name="sort-2"
                  color={theme.colors.white}
                  size={32}
                  opacity={pressed && visibility.data ? 0.7 : 1}
                />
              </SSortingIconContainer>
            )}
          </Pressable>
        </SRow>
      </SBoxAnimated>

      <SBoxAnimated
        style={Animation.titleSmall(animationY)}
        alignItems="center"
        width={1}
        position="absolute"
      >
        <Pressable onPress={() => scrollToTop()}>
          {({ pressed }) => (
            <SBox opacity={pressed ? 0.7 : 1} py={10} px={5}>
              <SH3
                testID="track-charts-screen-touchable-text"
                textAlign="center"
                numberOfLines={1}
              >
                {title}
              </SH3>
            </SBox>
          )}
        </Pressable>
      </SBoxAnimated>

      <SBoxAnimated style={[Animation.arrow(animationY)]} position="absolute">
        <BackButton
          testID="track-charts-screen-header-back-button"
          onPress={goBack}
          fixed
        />
      </SBoxAnimated>
    </>
  );
});
