import React, { useContext, useState, memo } from 'react';
import { Swipeable as GSwipeable } from 'react-native-gesture-handler';
import {
  Animated,
  Keyboard,
  StyleSheet,
  TouchableWithoutFeedback,
} from 'react-native';
import { Nullable } from 'tsdef';
import { SBoxAnimated } from '../s-components/layout/s-box-animated';
import { SBox } from '../s-components/layout/s-box';
import { SRow } from '../s-components/layout/s-row';
import { SCol } from '../s-components/layout/s-col';
import { SText } from '../s-components/typography/s-text';
import { SH3 } from '../s-components/typography/s-h3';
import { theme } from '../../app/theme';
import { fp as _ } from '../utils/fp';
import { SSwipeableIcon } from '../s-components/s-swipeable-icon';
import { SRectButton } from '../s-components/s-rect-button';
import { blurSubject$ } from '../utils/input-service';
import { ContextStarredPlaylists } from '../context';
import { toasterSubject$ } from '../submodules/toaster/services/toaster-service';
import { TPlaylist } from '../submodules/starring-playlists/types';
import { Flag } from './flag';
import {
  formatStreamDigit,
  formatStreamNa,
  getDaysAgoLabel,
  setMarketCode,
} from '../transducers';
import { PositionTrendsLabel } from './position-trends-label';
import { SDot } from '../s-components/s-dot';
import { TouchableCard } from './touchable-card';
import { StarredLabel } from './starred-label';
import { TPlaylistApi } from '../../track-playlists/types';
import { SPlaylistName } from '../s-components/s-playlist-name';
import { SPersonalizedBadge } from '../s-components/s-personalized-badge';
import { TVendor } from '../types';

import { EToastTemplate } from '../submodules/toaster/types';
import { PositionTrends } from './position-trends';

type TProps = TPlaylistApi & {
  cardHeight: number;
  variant: string;
  keyComposed: string;
  onPress?: (params: TPlaylist) => void;
  onPressRight?: (params: TPlaylist) => void;
  onSwipeableRightWillOpen?: (value: string) => void;
  forwardedRef: any;
  starred?: boolean;
  showStarred?: boolean;
  onRightOpen?: (value: string) => void;
  onRightClose?: (value: string) => void;
  optimistic?: boolean;
  starSource: string;
  current_streams: number;
  moved: Nullable<number>;
  updated: Nullable<number>;
  streamsTrend: any;
  cardVariant: string;
  streamsType: string;
  vendor: TVendor;
};

export const SwipeablePlaylistCardComponent: React.FC<TProps> = memo(
  (props: TProps) => {
    const [pressed, setPressed] = useState(false);
    const { error, offline } = useContext(ContextStarredPlaylists);
    const renderRightActions = (
      progress: Animated.AnimatedInterpolation<any>
    ) => {
      const { starred, onPressRight, cardHeight, ...rest } = props;
      const trans = progress.interpolate({
        inputRange: [0, 1],
        outputRange: [72, 0],
      });

      const iconColor = starred
        ? theme.colors.wildStrawberry
        : theme.colors.white;

      return (
        <SRow width={55}>
          <SBoxAnimated style={{ transform: [{ translateX: trans }] }}>
            <TouchableWithoutFeedback
              testID="swipeable-star"
              onPress={() => {
                if (_.isNotNil(rest.optimistic)) return;
                const data = _.omit([
                  'onPress',
                  'onSwipeableRightWillOpen',
                  'forwardedRef',
                  'onRightOpen',
                  'onRightClose',
                ])(rest) as TPlaylist;
                // TODO add new toast variant for playlist
                // TODO add new toast variant for playlist
                // TODO add new toast variant for playlist
                if (error || offline) {
                  toasterSubject$.next({
                    template: EToastTemplate.starLoadError,
                  });
                  return;
                }
                onPressRight!({ ...data });
              }}
              onPressIn={() => {
                setPressed(true);
              }}
              onPressOut={() => {
                setPressed(false);
              }}
            >
              <SRectButton height={cardHeight - 16}>
                <SSwipeableIcon
                  name={starred ? 'star' : 'star-outlined'}
                  size={29}
                  color={iconColor}
                  opacity={pressed ? 0.7 : 1}
                />
              </SRectButton>
            </TouchableWithoutFeedback>
          </SBoxAnimated>
        </SRow>
      );
    };

    const {
      cardHeight,
      name,
      image_url,
      personalized,
      keyComposed,
      onSwipeableRightWillOpen,
      forwardedRef,
      onRightOpen,
      onRightClose,
      onPress,
      showStarred,
      starred,
      country_code,
      current_position,
      trend,
      is_new,
      updated,
      moved,
      streamsTrend,
      current_streams,
      cardVariant,
      streamsType,
      // vendor,
    } = props;
    const streamsTitle =
      streamsType === 'playlist' ? 'Playlist Streams' : 'Track Streams';

    const updatedDate = updated || (_.isNull(updated) ? 'N/A' : '');
    const cardSize = cardHeight - 16;

    const marketCode = setMarketCode(country_code);
    const validPosition = !!current_position || current_position === 0;
    const marketTransform =
      marketCode === 'global' ? 'capitalize' : 'uppercase';
    const isCurrent = cardVariant === 'current';
    const positionTrend = {
      value: trend,
      valueFormatted: formatStreamDigit(trend),
    };

    const daysAgoLabel = getDaysAgoLabel(moved);
    // const isAmazon = vendor === 'amazon';

    return (
      <SBox height={cardHeight} pt={16} position="relative">
        <GSwipeable
          onSwipeableRightWillOpen={() =>
            onSwipeableRightWillOpen!(keyComposed)
          }
          onSwipeableRightOpen={() => {
            if (onRightOpen) {
              onRightOpen(keyComposed);
            }
            Keyboard.dismiss();
            blurSubject$.next();
          }}
          onSwipeableClose={() => {
            if (onRightClose) {
              onRightClose(keyComposed);
            }
          }}
          containerStyle={{
            paddingBottom: 16,
          }}
          ref={forwardedRef}
          friction={2}
          rightThreshold={5}
          renderRightActions={renderRightActions}
          overshootRight={false}
        >
          <TouchableCard
            testID="shared-touchable-card"
            onPress={() => {
              const data = _.omit([
                'onPress',
                'onSwipeableRightWillOpen',
                'forwardedRef',
                'onRightOpen',
                'onRightClose',
              ])(props) as TPlaylist;
              onPress!(data);
            }}
            borderRadius={8}
            containerStyle={{ mx: 16 }}
            height={cardSize}
            // variant={isAmazon ? 'no-shadow' : 'shadow'}
            variant="shadow"
            bgImage={image_url}
            bgStyle={{ bg: theme.colors.fiord }}
            gradient={{
              // tapped: {
              //   colors: isAmazon
              //     ? theme.gradients.cardPlaylist
              //     : theme.gradients.cardPlaylistTapped,
              // },
              tapped: {
                colors: theme.gradients.cardPlaylistTapped,
              },
              default: { colors: theme.gradients.cardPlaylist },
            }}
          >
            <SBox position="relative">
              <SRow height={cardSize}>
                <SBox flex={1}>
                  {/*HEADER*/}
                  <SBox flex={1} pt={14}>
                    <SRow
                      pl={16}
                      pr={16}
                      justifyContent="space-between"
                      alignItems="center"
                    >
                      <SBox flexShrink={1} pr={22}>
                        <SPlaylistName
                          numberOfLines={1}
                          testID="swipeable-name"
                        >
                          {_.isNil(name) ? 'N/A' : name}
                        </SPlaylistName>
                      </SBox>
                      {isCurrent && !personalized ? (
                        <SRow>
                          <SCol>
                            <SH3
                              medium
                              letterSpacing={1}
                              numberOfLines={1}
                              testID="swipeable-position"
                            >
                              {validPosition
                                ? `#${formatStreamDigit(
                                    current_position as number,
                                    {
                                      addComma: true,
                                    }
                                  )}`
                                : 'N/A'}
                            </SH3>
                          </SCol>
                          <SCol>
                            {trend ? (
                              <PositionTrends
                                trend={positionTrend}
                                ml={8}
                                mt={4}
                              />
                            ) : null}
                            {is_new ? (
                              <SDot
                                mt={7}
                                ml={11}
                                mr={2}
                                bg={theme.colors.dodgerBlue}
                              />
                            ) : null}
                          </SCol>
                        </SRow>
                      ) : null}
                    </SRow>
                  </SBox>

                  {/*BODY*/}
                  <SRow pl={16} pr={11} pb={16} justifyContent="space-between">
                    {personalized ? (
                      <SBox alignItems="flex-start" justifyContent="flex-end">
                        <SBox
                          px={8}
                          borderRadius={2}
                          backgroundColor="purpleHeart2"
                          height={24}
                          justifyContent="center"
                        >
                          <SPersonalizedBadge testID="swipeable-personalized">
                            Personalized
                          </SPersonalizedBadge>
                        </SBox>
                      </SBox>
                    ) : null}

                    {!personalized ? (
                      <SBox>
                        <SBox mb={8}>
                          <SText fontSize={12} color="periwinkleGray" medium>
                            {isCurrent ? 'Added' : 'Removed'}
                          </SText>
                        </SBox>
                        <SText>{daysAgoLabel}</SText>
                      </SBox>
                    ) : null}
                    {isCurrent ? (
                      <SBox alignItems="flex-end">
                        <SBox mb={8} mr={5}>
                          <SText fontSize={12} color="periwinkleGray" medium>
                            {streamsTitle}
                          </SText>
                        </SBox>
                        <SRow alignItems="flex-end">
                          <SText
                            letterSpacing={1}
                            testID="swipeable-current-streams"
                          >
                            {formatStreamNa(current_streams)}
                          </SText>
                          <PositionTrendsLabel
                            showZerroTrend
                            showPercent
                            isTransparent
                            isReversed
                            trend={streamsTrend}
                          />
                        </SRow>
                      </SBox>
                    ) : null}
                  </SRow>

                  {/*FOOTER*/}
                  <SRow
                    height={40}
                    px={16}
                    borderBottomLeftRadius={8}
                    borderBottomRightRadius={8}
                    justifyContent="space-between"
                    alignItems="center"
                  >
                    <SBox
                      style={StyleSheet.absoluteFill}
                      bg={theme.colors.ebonyClay}
                      opacity={0.5}
                    />
                    <SBox>
                      <SText sm color={theme.colors.periwinkleGray}>
                        {updatedDate === 'N/A'
                          ? `Updated: ${updatedDate}`
                          : `Updated ${updatedDate}`}
                      </SText>
                    </SBox>

                    <SRow mr={1}>
                      <SText
                        pr={7}
                        pb={1}
                        style={{ textTransform: marketTransform }}
                      >
                        {_.isNil(marketCode) ? 'N/A' : marketCode}
                      </SText>
                      <Flag
                        market={country_code}
                        width={16}
                        height={16}
                        marginTop={0}
                        variant="white"
                      />
                    </SRow>
                  </SRow>
                </SBox>
              </SRow>
              {showStarred && starred ? <StarredLabel /> : null}
            </SBox>
          </TouchableCard>
        </GSwipeable>
      </SBox>
    );
  }
);

SwipeablePlaylistCardComponent.defaultProps = {
  onPress: _.noop,
  onPressRight: _.noop,
  onSwipeableRightWillOpen: _.noop,
  onRightOpen: _.noop,
  onRightClose: _.noop,
};

function forwardRef(props: any, ref: any) {
  return <SwipeablePlaylistCardComponent {...props} forwardedRef={ref} />;
}

export const SwipeablePlaylistCard = React.forwardRef(forwardRef);
