import React, { useContext, memo } from 'react';
import { Animated, Dimensions } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
import {
  addSafeArea,
  getStatusBarHeight,
  getAnimations,
} from '../../common/transducers';
import { SBoxAnimated } from '../../common/s-components/layout/s-box-animated';
import { theme } from '../../app/theme';
import { Tabs } from '../../common/components/tabs';
import { SBox } from '../../common/s-components/layout/s-box';
import { SearchInput } from '../../common/components/search-input';
import { ContextHeader } from '../contexts';
import { FETCH_TYPE } from '../../common/constants';
import { fp as _ } from '../../common/utils/fp';
import {
  ACTIVE_TAB,
  SEARCH_FILTERING_POPUP_ID,
  SEARCH_VARIANT,
} from '../constants';
import { Router } from '../../common/utils/navigation-service';
import { ROUTE_PARAMS, ROUTES } from '../../app/constants';
import { TActiveTab } from '../types';
import { pageChange, PAGES } from '../../analytics';
import { SRow } from '../../common/s-components/layout/s-row';
import { openPopupByVariant } from '../../common/utils/keyboard-service';
import { Icon } from '../../common/components/icon';
import { ToggleStyled } from '../../common/components/toggle-styled';
import { opacityToHex } from '../../common/transducers/transducers.theme';

const maxHeight = addSafeArea(140);
const minHeight = addSafeArea(80);
const { height: DEVICE_HEIGHT, width: DEVICE_WIDTH } = Dimensions.get('window');
const heightDiff = maxHeight - minHeight;
const safeArea = getStatusBarHeight();

type TProps = {
  animationY: Animated.Value;
  isScrolled: boolean;
  scrollToTop: (withoutAnimation?: boolean) => void;
};

const Animation = getAnimations({
  headerBg: {
    opacity: {
      inputRange: [0, heightDiff],
      outputRange: [0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [0, -heightDiff],
    },
  },
  tabs: {
    opacity: {
      inputRange: [0, heightDiff],
      outputRange: [1, 0],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 25, safeArea],
    },
  },
  input: {
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [safeArea + 80, safeArea + 20],
    },
  },
});

export const Header = memo((params: TProps) => {
  const { animationY, isScrolled, scrollToTop } = params;
  const props = useContext(ContextHeader);

  const {
    entityTracks,
    entityPlaylists,
    getTracks,
    getPlaylists,
    activeVisibility,
    activeTab,
  } = props;

  const inputPlaceholder = !activeTab
    ? 'Search for'
    : activeTab !== ACTIVE_TAB.playlists
    ? 'Search for tracks'
    : 'Search for playlists';
  const inputValue =
    _.path('config.search', entityTracks) ||
    _.path('config.search', entityPlaylists);
  const filtersValue = _.path('config.vendor', entityPlaylists);
  const isPartialVendorSelection =
    _.length(filtersValue) > 0 && _.length(filtersValue) < 3;
  const searchLoading =
    activeTab === 'tracks' ? entityTracks.loading : entityPlaylists.loading;

  const cssSortingRules = {
    width: 44,
    height: 44,
    borderRadius: 22,
    pt: 7,
    pl: 6,
    ml: 8,
  };
  const iconBg = theme.colors[isScrolled ? 'fiord' : 'disco'];
  const tappedIconBg = theme.colors[isScrolled ? 'pickledBluewood' : 'disco'];

  return (
    <>
      {activeVisibility.variant === SEARCH_VARIANT.recentTracks ||
      activeVisibility.variant === SEARCH_VARIANT.recentPlaylists ? (
        <SBoxAnimated
          style={Animation.headerBg(animationY)}
          height={maxHeight}
          bg={theme.colors.vulcan}
          position="absolute"
          width={1}
        />
      ) : (
        <SBoxAnimated
          height={minHeight}
          position="absolute"
          width={1}
          overflow="hidden"
        >
          <LinearGradient
            colors={theme.gradients.search}
            style={{
              flex: 1,
              position: 'absolute',
              width: DEVICE_WIDTH,
              height: DEVICE_HEIGHT,
            }}
          />
        </SBoxAnimated>
      )}

      <SBoxAnimated
        style={Animation.tabs(animationY)}
        width={1}
        position="absolute"
      >
        <Tabs
          // testID="search-tabs"
          active={activeTab}
          light
          tabs={[
            { id: 'tracks', name: 'tracks' },
            { id: 'playlists', name: 'playlists' },
          ]}
          onSelect={tab => {
            Router.setParamsFor(ROUTES.search, {
              [ROUTE_PARAMS.searchVariant]: tab as TActiveTab,
            });
            pageChange(PAGES.Searchtab.page, {
              search_tab_opened: _.capitalize(tab),
              requiredFields: ['search_tab_opened'],
            });
          }}
        />
      </SBoxAnimated>
      <SBoxAnimated
        style={Animation.input(animationY)}
        width={1}
        position="absolute"
      >
        <SRow px={16}>
          <SBox flex={1}>
            <SearchInput
              value={inputValue}
              placeholder={inputPlaceholder}
              searchLoading={searchLoading}
              isScrolled={isScrolled}
              onFocusBeforeScroll={isScrolled && scrollToTop}
              onFocus={() => {}}
              onChange={(search: string) => {
                getTracks({ search }, FETCH_TYPE.silent);
                getPlaylists({ search }, FETCH_TYPE.silent);

                setTimeout(() => {
                  scrollToTop(true);
                }, 100);
              }}
            />
          </SBox>
          {activeTab === ACTIVE_TAB.playlists ? (
            <ToggleStyled
              {...cssSortingRules}
              testID="playlists-toggle"
              tappedCss={{
                backgroundColor:
                  activeVisibility.variant === SEARCH_VARIANT.recentPlaylists
                    ? `${tappedIconBg}${opacityToHex(isScrolled ? 1 : 0.7)}`
                    : `${theme.colors.disco}${opacityToHex(0.5)}`,
              }}
              defaultCss={
                isPartialVendorSelection
                  ? {
                      backgroundColor:
                        activeVisibility.variant ===
                        SEARCH_VARIANT.recentPlaylists
                          ? `${iconBg}${opacityToHex(isScrolled ? 1 : 0.5)}`
                          : `${theme.colors.disco}${opacityToHex(0.5)}`,
                    }
                  : undefined
              }
              onPress={() => {
                openPopupByVariant(SEARCH_FILTERING_POPUP_ID);
              }}
              renderBody={({ pressed }) => (
                <Icon
                  name="filter"
                  color={`${theme.colors.white}${opacityToHex(
                    pressed ? 0.7 : 1
                  )}`}
                  size={32}
                />
              )}
            />
          ) : null}
        </SRow>
      </SBoxAnimated>
    </>
  );
});
