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} 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 Tagg from './Tagg';

const {View, ScrollView, interpolate, Extrapolate} = Animated;
interface TaggsBarProps {
  y: Animated.Value<number>;
  profileBodyHeight: number;
  userXId: string | undefined;
  screenType: ScreenType;
}
const TaggsBar: React.FC<TaggsBarProps> = ({
  y,
  profileBodyHeight,
  userXId,
  screenType,
}) => {
  let [taggs, setTaggs] = useState<Object[]>([]);
  let [taggsNeedUpdate, setTaggsNeedUpdate] = useState(true);

  const {user} = userXId
    ? useSelector((state: RootState) => state.userX[screenType][userXId])
    : useSelector((state: RootState) => state.user);

  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 () => {
      getLinkedSocials(user.userId).then((linkedSocials) => {
        const unlinkedSocials = SOCIAL_LIST.filter(
          (s) => linkedSocials.indexOf(s) === -1,
        );
        let new_taggs = [];
        let i = 0;
        for (let social of linkedSocials) {
          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}
              screenType={screenType}
            />,
          );
          i++;
        }
        if (!userXId && screenType !== ScreenType.SuggestedPeople) {
          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}
                screenType={screenType}
              />,
            );
            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={
        screenType === ScreenType.SuggestedPeople
          ? [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,
    paddingBottom: 5,
  },
  container: {
    backgroundColor: 'white',
    shadowColor: '#000',
    shadowRadius: 10,
    shadowOffset: {width: 0, height: 2},
    zIndex: 1,
    paddingBottom: 5,
  },
  contentContainer: {
    alignItems: 'center',
    paddingBottom: 5,
  },
});

export default TaggsBar;
