import {RouteProp} from '@react-navigation/native';
import {StackNavigationProp} from '@react-navigation/stack';
import React, {useEffect, useRef, useState} from 'react';
import {FlatList, Keyboard, ViewToken} from 'react-native';
import {useSelector} from 'react-redux';
import {MomentPost, TabsGradient} from '../../components';
import {AVATAR_DIM} from '../../constants';
import {MainStackParams} from '../../routes';
import {RootState} from '../../store/rootreducer';
import {MomentPostType} from '../../types';
import {isIPhoneX} from '../../utils';

/**
 * Individual moment view opened when user clicks on a moment tile
 */

type MomentContextType = {
  keyboardVisible: boolean;
  scrollTo: (index: number) => void;
  currentVisibleMomentId: string | undefined;
};

export const MomentContext = React.createContext({} as MomentContextType);

type IndividualMomentRouteProp = RouteProp<MainStackParams, 'IndividualMoment'>;

type IndividualMomentNavigationProp = StackNavigationProp<
  MainStackParams,
  'IndividualMoment'
>;

interface IndividualMomentProps {
  route: IndividualMomentRouteProp;
  navigation: IndividualMomentNavigationProp;
}

const IndividualMoment: React.FC<IndividualMomentProps> = ({route}) => {
  const {
    userXId,
    screenType,
    moment: {moment_category, moment_id},
  } = route.params;
  const {moments} = useSelector((state: RootState) =>
    userXId ? state.userX[screenType][userXId] : state.moments,
  );
  const scrollRef = useRef<FlatList<MomentPostType>>(null);
  const momentData = moments.filter(
    (m) => m.moment_category === moment_category,
  );
  const initialIndex = momentData.findIndex((m) => m.moment_id === moment_id);
  const [keyboardVisible, setKeyboardVisible] = useState(false);
  const [currentVisibleMomentId, setCurrentVisibleMomentId] = useState<
    string | undefined
  >();
  // https://stackoverflow.com/a/57502343
  const viewabilityConfigCallback = useRef(
    (info: {viewableItems: ViewToken[]; changed: ViewToken[]}) => {
      const index = info.viewableItems[0].index;
      if (index !== null) {
        setCurrentVisibleMomentId(momentData[index].moment_id);
      }
    },
  );

  useEffect(() => {
    const showKeyboard = () => setKeyboardVisible(true);
    const hideKeyboard = () => setKeyboardVisible(false);
    Keyboard.addListener('keyboardWillShow', showKeyboard);
    Keyboard.addListener('keyboardWillHide', hideKeyboard);
    return () => {
      Keyboard.removeListener('keyboardWillShow', showKeyboard);
      Keyboard.removeListener('keyboardWillHide', hideKeyboard);
    };
  }, []);

  const scrollTo = (index: number) => {
    // TODO: make this dynamic
    const offset = isIPhoneX() ? -(AVATAR_DIM + 100) : -(AVATAR_DIM + 160);
    scrollRef.current?.scrollToIndex({
      index: index,
      viewOffset: offset,
    });
  };

  return (
    <MomentContext.Provider
      value={{
        keyboardVisible,
        scrollTo,
        currentVisibleMomentId,
      }}>
      <FlatList
        ref={scrollRef}
        data={momentData}
        renderItem={({item}) => (
          <MomentPost
            key={item.moment_id}
            moment={item}
            userXId={userXId}
            screenType={screenType}
          />
        )}
        keyExtractor={(item, _) => item.moment_id}
        showsVerticalScrollIndicator={false}
        initialScrollIndex={initialIndex}
        onViewableItemsChanged={viewabilityConfigCallback.current}
        onScrollToIndexFailed={(info) => {
          setTimeout(() => {
            scrollRef.current?.scrollToIndex({
              index: info.index,
            });
          }, 500);
        }}
        pagingEnabled
      />
      <TabsGradient />
    </MomentContext.Provider>
  );
};

export default IndividualMoment;
