import React, { memo, useCallback, useEffect } from 'react';
import { Platform, Pressable } from 'react-native';
import { Undefinable } from 'tsdef';
import { LinearGradient } from 'expo-linear-gradient';
import { RefreshableView } from '../../common/components/refreshable-view';
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 {
  getStatusBarHeight,
  addSafeArea,
  getAnimations,
} from '../../common/transducers';
import { TRefreshableRenderer } from '../../common/types';
import { BackButton } from '../../common/components/back-button';
import MarketDemographics from '../../market-demographics';
import MarketKpi from '../../market-kpi';
import MarketStreams from '../../market-streams';
import MarketMonitoring from '../../market-monitoring';
import WithMarketIndicator from '../../common/containers/with-market-indicator';
import { DatepickerButton } from '../../common/components/datepicker-button';
import { SHeaderBg } from '../../track/s-components/s-header-bg';
import { SBgArc } from '../s-components/s-bg-arc';
import { RotationOverlay } from '../../common/components/rotation-overlay';
import { setPortraitOrientation } from '../../common/utils/device-utils';
import { getMarketCode } from '../transducers';
import { SHeaderGradient } from '../../track/s-components/s-header-gradient';
import { togglePopup } from '../../common/utils/swipeable-popup-service';
import { Portal } from '../../common/utils/portal/portal';
import { SwipeablePopup } from '../../common/components/bottom-sheet/swipeable-popup';
import { DateRange } from '../../common/components/date-range';
import { fp as _ } from '../../common/utils/fp';
import { ViewNetworkFailed } from '../../common/components/view-network-failed';
import { Icon } from '../../common/components/icon';
import { datepickerOpened, DATEPICKER_SOURCE } from '../../analytics';
import { TMarketProps, TNavProps, TPresetDateRange } from '../types';
import { ROUTES } from '../../app/constants';
import { Router } from '../../common/utils/navigation-service';
import { DATE_RANGE_POPUP_VARIANT } from '../constants';
import { SRow } from '../../common/s-components/layout/s-row';
import { Flag } from '../../common/components/flag';
import { SH3 } from '../../common/s-components/typography/s-h3';
import { MARKET_VARIANT_PARAMS } from '../../market-selector/constants';
import { SPageTitle } from '../s-components/s-page-title';
import { Arc } from '../../common/components/arc';

const maxHeight = addSafeArea(80);
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 / 3, heightDiff / 2, heightDiff],
      outputRange: [1, 1, 0, 0],
    },
    translateY: {
      inputRange: [0, heightDiff / 1.5, heightDiff],
      outputRange: [safeArea + 21, safeArea + 12, 0],
    },
  },

  titleSmall: {
    opacity: {
      inputRange: [0, heightDiff / 2, heightDiff / 1.5, heightDiff],
      outputRange: [0, 0, 1, 1],
    },
    translateY: {
      inputRange: [0, heightDiff / 3, heightDiff / 2, heightDiff],
      outputRange: [safeArea + 45, safeArea + 45, safeArea + 18, safeArea + 12],
    },
    scaleY: {
      inputRange: [0, heightDiff / 3, heightDiff / 2],
      outputRange: [0, 1, 1],
    },
  },

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

type TProps = TMarketProps & {
  streamLatestDate: Undefinable<string>;
  preSetDateRange: TPresetDateRange;
  refresh: () => void;
  offline?: boolean;
} & TNavProps;

export const Market: React.FC<TProps> = memo(props => {
  const {
    refreshing,
    refresh,
    loaded,
    dateRangeOptions,
    preSetDateRange,
    dateRange,
    market,
    offline,
    streamLatestDate,
    trackData,
  } = props;

  useEffect(() => {
    setPortraitOrientation();
  });

  const goToMarketSelector = () => {
    Router.goTo(ROUTES.marketselector, {
      marketVariant: MARKET_VARIANT_PARAMS.market,
    });
  };

  const goBack = () => {
    Router.goBack();
  };

  const infoPressHandler = (variant: string) => {
    togglePopup(variant);
    datepickerOpened({ datepicker_source: DATEPICKER_SOURCE.MARKETS_DETAILED });
  };

  const renderFgLayer = useCallback(() => {
    const days = _.path('days', dateRange)!;

    return (
      <Portal id="market" updateIfAnyChanged={{ days }}>
        <SwipeablePopup
          fullheight
          variant={DATE_RANGE_POPUP_VARIANT}
          content={
            <DateRange
              rangeTitle="Streams Period"
              value={days}
              options={dateRangeOptions}
              onRange={preSetDateRange}
              confirmRange={() => {
                setTimeout(() => {
                  togglePopup(DATE_RANGE_POPUP_VARIANT);
                }, 100);
              }}
              source={DATEPICKER_SOURCE.MARKETS_DETAILED}
            />
          }
        />
      </Portal>
    );
  }, [dateRangeOptions, preSetDateRange, dateRange]);

  const renderFgLayer2 = () => <RotationOverlay />;

  const renderHeader: TRefreshableRenderer = useCallback(
    ({ animationY, scrollToTop, isScrolled }) => {
      const marketCode = getMarketCode(market!);

      const onPress = () => {
        if (isScrolled) {
          scrollToTop();
        } else {
          goToMarketSelector();
        }
      };

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

              <SBoxAnimated
                style={Animation.title(animationY)}
                position="absolute"
                alignItems="center"
                width={1}
              >
                <Pressable onPress={onPress} testID="market-tappable-title">
                  {({ pressed }) => (
                    <WithMarketIndicator
                      variant="market-charts"
                      maxHeight={maxHeight}
                      notClickable
                      marketCode={marketCode}
                      pressed={pressed}
                    >
                      <SRow>
                        <SPageTitle>{marketCode} Streams</SPageTitle>
                        <Icon
                          name="down-ind"
                          size={12}
                          color="white"
                          pl={8}
                          pt={7}
                        />
                      </SRow>
                    </WithMarketIndicator>
                  )}
                </Pressable>
              </SBoxAnimated>

              <SBoxAnimated
                style={Animation.titleSmall(animationY)}
                position="absolute"
                alignItems="center"
                width={1}
              >
                <Pressable onPress={onPress} testID="market-tappable-title">
                  {({ pressed }) => (
                    <SRow alignItems="center" opacity={pressed ? 0.7 : 1}>
                      <Flag
                        market={marketCode}
                        width={16}
                        height={16}
                        marginTop={0}
                        variant="light"
                      />
                      <SH3 ml={8}>{marketCode} Streams</SH3>
                    </SRow>
                  )}
                </Pressable>
              </SBoxAnimated>
            </>
          ) : null}
          <SBoxAnimated
            style={[Animation.arrow(animationY)]}
            position="absolute"
          >
            <BackButton testID="market-back-button" onPress={goBack} fixed />
          </SBoxAnimated>
        </>
      );
    },
    [market, offline]
  );

  const renderBody: TRefreshableRenderer = useCallback(
    ({ scrollToBottom }) => {
      const isIOS = Platform.OS === 'ios';
      const arcTopOffset = isIOS ? 266 : 250;
      const marketCode = getMarketCode(market!);
      const range = _.path('days', dateRange)!;

      if (offline) {
        return (
          <SBox position="relative" flex={1}>
            <ViewNetworkFailed verticalOffset={-2} />
          </SBox>
        );
      }

      return (
        <>
          <SBox position="relative" flex={1} pt={maxHeight + 4}>
            <MarketKpi />
            <SBox mb={54}>
              <DatepickerButton
                maxDate={streamLatestDate}
                range={range}
                onInfoPress={infoPressHandler}
                daterangePopupVariant="date-range"
              />
            </SBox>
            <MarketStreams marketCode={marketCode!} />
            <MarketDemographics />
            <MarketMonitoring scrollToBottom={scrollToBottom} />
            <SBox
              position="absolute"
              top={arcTopOffset}
              height={426}
              zIndex={-1}
            >
              <Arc fill="mirage" />
              <SBgArc />
              <LinearGradient
                colors={theme.gradients.marketStreams1}
                style={{
                  height: 386,
                }}
                locations={[0, 1]}
              />
            </SBox>
          </SBox>
        </>
      );
    },
    [offline, dateRange, market, streamLatestDate]
  );

  const renderBgLayer2 = useCallback(() => {
    const image_url = _.path('image_url', trackData);

    if (offline) return null;

    return (
      <SBox position="relative" height={400}>
        <>
          {image_url ? (
            <SHeaderBg top={0} source={{ uri: image_url }} />
          ) : (
            <SBox
              height={375}
              width="100%"
              position="absolute"
              top={0}
              bg={theme.colors.lavenderGray}
            />
          )}
          <SHeaderGradient
            height={375}
            top={0}
            colors={theme.gradients.marketTrackAvatar}
            location={[0.1, 0.6, 1]}
          />
        </>
      </SBox>
    );
  }, [trackData, offline]);

  return (
    <RefreshableView
      testID="market-refreshable-view"
      loading={refreshing}
      indicatorOffsetTop={maxHeight - 12}
      indicatorLight
      // inifite pagination - get next page when we don't have payload
      // onScrollReachBottom={() => getData('infinite')}
      onPullDown={() => {
        if (loaded) {
          refresh();
        }
      }}
      renderHeader={renderHeader}
      renderBgLayer2={renderBgLayer2}
      renderBody={renderBody}
      renderFgLayer={renderFgLayer}
      renderFgLayer2={renderFgLayer2}
      name={ROUTES.market}
      withNativeDriver
    />
  );
});

Market.defaultProps = {
  // dateRange: undefined,
  // market: undefined,
  // offline: undefined,
};
