import React, {Fragment, useEffect, useState} from 'react';
import {StyleSheet} from 'react-native';
import Animated from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {useDispatch, useSelector, useStore} from 'react-redux';
import {
  INTEGRATED_SOCIAL_LIST,
  PROFILE_CUTOUT_BOTTOM_Y,
  SOCIAL_LIST,
} from '../../constants';
import {getLinkedSocials} from '../../services';
import {loadIndividualSocial, updateSocial} from '../../store/actions';
import {RootState} from '../../store/rootReducer';
import {ScreenType} from '../../types';
import {canViewProfile} from '../../utils';
import Tagg from './Tagg';

const {View, ScrollView, interpolate, Extrapolate} = Animated;
interface TaggsBarProps {
  y: Animated.Value<number>;
  profileBodyHeight: number;
  userXId: string | undefined;
  screenType: ScreenType;
  whiteRing: boolean | undefined;
  linkedSocials?: string[];
}
const TaggsBar: React.FC<TaggsBarProps> = ({
  y,
  profileBodyHeight,
  userXId,
  screenType,
  whiteRing,
  linkedSocials,
}) => {
  let [taggs, setTaggs] = useState<Object[]>([]);
  let [taggsNeedUpdate, setTaggsNeedUpdate] = useState(true);
  const {user} = useSelector((state: RootState) =>
    userXId ? state.userX[screenType][userXId] : state.user,
  );
  const state: RootState = useStore().getState();
  const allowTaggsNavigation = canViewProfile(state, userXId, screenType);

  const dispatch = useDispatch();

  /**
   * Updates the individual social that needs update
   * If username is empty, update nonintegrated socials like Snapchat and TikTok
   * @param socialType Type of the social that needs update
   */
  const handleSocialUpdate = (socialType: string, username: string) => {
    if (username !== '') {
      dispatch(updateSocial(socialType, username));
    } else {
      dispatch(loadIndividualSocial(user.userId, socialType));
    }
  };

  /**
   * This useEffect should be called evey time the user being viewed is changed OR
   * And update is triggered manually
   */
  useEffect(() => {
    const loadData = async () => {
      const socials: string[] = linkedSocials
        ? linkedSocials
        : await getLinkedSocials(user.userId);
      const unlinkedSocials = SOCIAL_LIST.filter(
        (s) => socials.indexOf(s) === -1,
      );
      let new_taggs = [];
      let i = 0;
      for (let social of socials) {
        new_taggs.push(
          <Tagg
            key={i}
            social={social}
            userXId={userXId}
            user={user}
            isLinked={true}
            isIntegrated={INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1}
            setTaggsNeedUpdate={setTaggsNeedUpdate}
            setSocialDataNeedUpdate={handleSocialUpdate}
            whiteRing={whiteRing ? whiteRing : undefined}
            allowNavigation={allowTaggsNavigation}
          />,
        );
        i++;
      }
      if (!userXId && !whiteRing) {
        for (let social of unlinkedSocials) {
          new_taggs.push(
            <Tagg
              key={i}
              social={social}
              isLinked={false}
              isIntegrated={INTEGRATED_SOCIAL_LIST.indexOf(social) !== -1}
              setTaggsNeedUpdate={setTaggsNeedUpdate}
              setSocialDataNeedUpdate={handleSocialUpdate}
              userXId={userXId}
              user={user}
              whiteRing={whiteRing ? whiteRing : undefined}
              allowNavigation={allowTaggsNavigation}
            />,
          );
          i++;
        }
      }
      setTaggs(new_taggs);
      setTaggsNeedUpdate(false);
    };
    if (user.userId) {
      loadData();
    }
  }, [taggsNeedUpdate, user]);

  const shadowOpacity: Animated.Node<number> = interpolate(y, {
    inputRange: [
      PROFILE_CUTOUT_BOTTOM_Y + profileBodyHeight,
      PROFILE_CUTOUT_BOTTOM_Y + profileBodyHeight + 20,
    ],
    outputRange: [0, 0.2],
    extrapolate: Extrapolate.CLAMP,
  });
  const paddingTop: Animated.Node<number> = interpolate(y, {
    inputRange: [
      PROFILE_CUTOUT_BOTTOM_Y +
        profileBodyHeight -
        (useSafeAreaInsets().top + 10),
      PROFILE_CUTOUT_BOTTOM_Y + profileBodyHeight,
    ],
    outputRange: [10, useSafeAreaInsets().top],
    extrapolate: Extrapolate.CLAMP,
  });

  return taggs.length > 0 ? (
    <View
      style={
        whiteRing
          ? [styles.spContainer]
          : [styles.container, {shadowOpacity, paddingTop}]
      }>
      <ScrollView
        horizontal
        showsHorizontalScrollIndicator={false}
        contentContainerStyle={styles.contentContainer}>
        {taggs}
      </ScrollView>
    </View>
  ) : (
    <Fragment />
  );
};

const styles = StyleSheet.create({
  spContainer: {
    shadowColor: '#000',
    shadowRadius: 10,
    shadowOffset: {width: 0, height: 2},
    zIndex: 1,
    marginBottom: 25,
  },
  container: {
    backgroundColor: 'white',
    shadowColor: '#000',
    shadowRadius: 10,
    shadowOffset: {width: 0, height: 2},
    zIndex: 1,
    paddingBottom: 5,
  },
  contentContainer: {
    alignItems: 'center',
    paddingBottom: 5,
  },
});

export default TaggsBar;
