import React, { memo, useCallback, useEffect } from 'react';
import {
  // Animated,
  // Dimensions,
  // LayoutChangeEvent,
  Platform,
  Keyboard,
} from 'react-native';
import once from 'lodash/once';
import { RefreshableView } from '../../../common/components/refreshable-view';
import { SBoxAnimated } from '../../../common/s-components/layout/s-box-animated';
// import { SwipeableList } from '../../common/components/swipeable-list';
import { ViewLoadFailed } from '../../../common/components/view-load-failed';
import { ViewNetworkFailed } from '../../../common/components/view-network-failed';
import { SBox } from '../../../common/s-components/layout/s-box';
import {
  addSafeArea,
  getStatusBarHeight,
  getAnimations,
} from '../../../common/transducers';
// import { RefillingIndicator } from '../../common/components/refilling-indicator';
import {
  NEntityInfinite,
  TEntityVisibility,
  TRefreshableRenderer,
  TRouteParams,
  TTrackParams,
  TVendor,
} from '../../../common/types';
import { SRow } from '../../../common/s-components/layout/s-row';
import { SearchInput } from '../../../common/components/search-input';
import { Button } from '../../../common/components/button';
import { NoResults } from '../../../common/components/no-results';
import { SKeyboardAvoidingView } from '../../../common/s-components/s-keyboard-avoiding-view';
import { fp as _ } from '../../../common/utils/fp';
import { LoadingOverlay } from '../../../common/components/loading-overlay';
import { Tracklist } from './tracklist';
import { SortBlock } from '../sort-block';
import { DATE_RANGES, FETCH_TYPE } from '../../../common/constants';
import { Skeleton } from './skeleton';
import { focusSubject$ } from '../../../common/utils/input-service';
import { ROUTES } from '../../../app/constants';
import { Router } from '../../../common/utils/navigation-service';
// import { replaceStack } from '../../common/utils/navigation-service';
import { SORTING_OPTIONS, TRACKLIST_SCREEN_VARIANT } from '../../constants';
import { TTracklistExtended } from '../../types';
import { getHeaderAddHeight } from '../../transducers';
import { keyboardState$ } from '../../../common/utils/keyboard-service';

const maxHeight = addSafeArea(73);
const minHeight = addSafeArea(72);
const heightDiff = maxHeight - minHeight;
const safeArea = getStatusBarHeight();

type TProps = {
  tracklist: TTracklistExtended;
  tracklistParent: TTracklistExtended;
  refreshing: boolean;
  refresh: () => void;
  visibility: TEntityVisibility;
  getTracklist: NEntityInfinite.TEntityInfiniteGet;
  getTracklistParent: NEntityInfinite.TEntityInfiniteGet;
  routeParams?: TRouteParams;
  onCardPress: (params: TTrackParams) => void;
  variant?: string;
  playlistVendor: TVendor;
};

const Animation = getAnimations({
  headerBg: {
    opacity: {
      inputRange: [0, heightDiff],
      outputRange: [0, 1],
    },
    translateY: {
      inputRange: [0, heightDiff],
      outputRange: [0, -heightDiff],
    },
  },
  headerContent: {
    translateY: safeArea + 12,
  },
});

export const TracklistScreen: React.FC<TProps> = memo(props => {
  const {
    getTracklist,
    getTracklistParent,
    tracklist,
    tracklistParent,
    visibility,
    refreshing,
    refresh,
    routeParams,
    onCardPress,
    variant,
    playlistVendor,
  } = props;

  useEffect(() => {
    focusSubject$.next();
  }, []);

  const goBack = once(() => {
    if (keyboardState$.value) {
      Keyboard.dismiss();
    }

    if (Platform.select({ android: keyboardState$.value })) {
      setTimeout(Router.goBack, 100);
    } else {
      Router.goBack();
    }
  });

  const refilling = () => {
    const isSearch = visibility.extra.search;

    if (isSearch) {
      if (!tracklist.loading) {
        return getTracklist(null, FETCH_TYPE.refill);
      }
    }

    if (tracklistParent.data) {
      if (!tracklistParent.loading) {
        return getTracklistParent(null, FETCH_TYPE.refill);
      }
    }
  };

  const renderHeader: TRefreshableRenderer = ({
    animationY,
    scrollToTop /*, isScrolled*/,
  }) => {
    const search = _.path('config.search', tracklist);
    return (
      <>
        <SBoxAnimated
          style={Animation.headerBg(animationY)}
          height={maxHeight + getHeaderAddHeight()}
          width={1}
          bg={visibility.extra.search ? 'ebonyClay' : 'vulcan'}
          position="absolute"
        />
        <SRow
          style={Animation.headerContent(animationY)}
          justifyContent="space-between"
          px={16}
          position="absolute"
          zIndex={1}
        >
          <SBox
            flex={1}
            mr={16}
            overflow="hidden"
            // onStartShouldSetResponderCapture={() => true} // disable clear button
            // onResponderGrant={() => {
            //   console.tron.log('click start');
            // }}
            // onResponderRelease={this.goToSearch}
            // onResponderTerminate={() => {
            //   // click failed probably because someone decided starting moving
            //   console.tron.log('terminate');
            // }}
            // onResponderTerminationRequest={() => {
            //   // Don't allow any other object take this event
            //   return false;
            // }}
          >
            <SearchInput
              inFocus
              value={search}
              placeholder="Find a track"
              onChange={(value: string) => {
                getTracklist({ search: value }, FETCH_TYPE.search);
                setTimeout(() => {
                  scrollToTop(true);
                }, 100);
              }}
              // disabled
              // onFocus={e => {
              //   e.preventDefault();
              // }}
              searchLoading={visibility.skeleton}
              // isScrolled={isScrolled}
              // onFocusBeforeScroll={isScrolled && scrollToTop}
              // onFocus={() => {}}
              // onChange={text => {
              //   change(text);
              //   setTimeout(() => {
              //     scrollToTop(true);
              //   }, 100);
              // }}
            />
          </SBox>

          <Button
            testID="playlist-placement-search-cancel-button"
            mr={-2}
            width={50}
            onPress={goBack}
            variant="transparent"
            color="#019CFE"
            normal
          >
            Cancel
          </Button>
        </SRow>
      </>
    );
  };

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

  const renderBody: TRefreshableRenderer = useCallback(() => {
    const { data, offline, error, skeleton, empty } = visibility;
    const isIos = Platform.OS === 'ios';
    const noResultKeyboardMargin = isIos ? -118 : -50;
    const noResultMargin = isIos ? -160 : -50;
    const isSearch = (_.path('config.search', tracklist) || '').length > 1;
    const showActiveIsrc = variant !== TRACKLIST_SCREEN_VARIANT.playlist;

    if (offline) return renderOffline();

    return (
      <>
        <SBoxAnimated position="relative" flex={1} pt={maxHeight}>
          {error ? (
            <ViewLoadFailed variant="tracklist" verticalOffset={40} />
          ) : null}

          {empty ? (
            <NoResults
              withAnimation
              keyboardDisplayedMargin={noResultKeyboardMargin}
              keyboardHiddenMargin={noResultMargin}
            />
          ) : null}

          {skeleton ? <LoadingOverlay variant="transparent" /> : null}

          {data ? (
            <SBox pb={64}>
              <SortBlock
                value={_.path('config.orderBy', tracklistParent)}
                options={SORTING_OPTIONS}
                dateRange={DATE_RANGES.WEEK}
                activeOption={_.path('config.orderBy', tracklistParent)}
                playlistVendor={playlistVendor}
              />
              {_.path('data', tracklist) && isSearch ? (
                <Tracklist
                  onCardPress={onCardPress}
                  tracklist={tracklist}
                  activeIsrc={
                    showActiveIsrc
                      ? (_.path('isrc', routeParams) as string)
                      : undefined
                  }
                  starSource={
                    variant === TRACKLIST_SCREEN_VARIANT.playlist
                      ? 'Playlistpage'
                      : 'Playlistplacement'
                  }
                />
              ) : null}
              {isSearch ? null : _.includes(
                  _.path('loadingVariant', tracklistParent),
                  [FETCH_TYPE.force, FETCH_TYPE.sort]
                ) ? (
                <Skeleton />
              ) : (
                <Tracklist
                  onCardPress={onCardPress}
                  tracklist={tracklistParent}
                  activeIsrc={
                    showActiveIsrc
                      ? (_.path('isrc', routeParams) as string)
                      : undefined
                  }
                  starSource={
                    variant === TRACKLIST_SCREEN_VARIANT.playlist
                      ? 'Playlistpage'
                      : 'Playlistplacement'
                  }
                />
              )}
            </SBox>
          ) : null}
        </SBoxAnimated>
      </>
    );
  }, [
    visibility,
    tracklist,
    tracklistParent,
    routeParams,
    onCardPress,
    variant,
  ]);

  return (
    <SKeyboardAvoidingView behavior="padding" enabled>
      <RefreshableView
        testID="playlist-placemnets-search-refreshable-view"
        indicatorLight
        loading={refreshing}
        // inifite pagination - get next page when we don't have payload
        // onScrollReachBottom={() => getData('infinite')}
        // inifite pagination - get next page when we don't have payload
        onScrollReachBottom={refilling}
        onPullDown={() => !visibility.skeleton && refresh()}
        renderHeader={renderHeader}
        renderBody={renderBody}
        name={ROUTES.playlistplacementsearch}
        withNativeDriver
        indicatorOffsetTop={maxHeight + 10}
        withoutBottomTabNavigator
      />
    </SKeyboardAvoidingView>
  );
});
