import React, { useRef } from 'react';
import {
  StyleSheet,
  PanResponder,
  Animated,
  ScrollView,
  Dimensions,
} from 'react-native';
import { SText } from '../../s-components/typography/s-text';
import { Input } from '../input';
import { SBox } from '../../s-components/layout/s-box';

const styles = StyleSheet.create({
  container: {
    height: Dimensions.get('window').height - 200,
    paddingLeft: 30,
    paddingRight: 30,
  },
  modal: {
    flex: 1,
    borderRadius: 15,
    overflow: 'hidden',
    borderWidth: 1,
    borderColor: '#333',
  },
  comments: {
    flex: 1,
  },
  fakeText: {
    padding: 15,
    textAlign: 'center',
  },
  fakeComments: {
    height: 1000,
    backgroundColor: '#eee',
  },
  inputWrap: {
    flexDirection: 'row',
    paddingHorizontal: 15,
  },
  textInput: {
    flex: 1,
    height: 50,
    borderTopWidth: 1,
    borderTopColor: '#000',
  },
});

export const ModalSwipe: React.FC = () => {
  const animated = useRef(new Animated.Value(0));

  const animatedMargin = useRef(new Animated.Value(0));

  const scrollOffset = useRef(0);

  const contentHeight = useRef(0);

  const scrollViewHeight = useRef(0);

  const panResponder = PanResponder.create({
    onMoveShouldSetPanResponder: (evt, gestureState) => {
      const { dy } = gestureState;
      const totalScrollHeight = scrollOffset.current + scrollViewHeight.current;

      // dy > 0 === FINGER DOWN
      // dy < 0 === FINGER UP
      if (
        // allow drag bottom to swipe away
        // make it draggable when scrollOffset <=0 and we are moving a finger down
        (scrollOffset.current <= 0 && dy > 0) ||
        // allow drag top to swipe away
        // make it draggable when scrollOffset > then total content height and we are moving a finger up
        (totalScrollHeight >= contentHeight.current && dy < 0)
      ) {
        return true;
      }

      return false;
    },
    onPanResponderMove: (e, gestureState) => {
      const { dy } = gestureState;
      // it will work only if dragging is allowed by onMoveShouldSetPanResponder
      // it is possible only in edge cases
      if (dy < 0) {
        animated.current.setValue(dy);
      } else if (dy > 0) {
        animatedMargin.current.setValue(dy);
      }
    },
    onPanResponderRelease: (e, gestureState) => {
      const { dy } = gestureState;

      if (dy < -150) {
        // Animate away over the top
        Animated.parallel([
          Animated.timing(animated.current, {
            toValue: -400,
            duration: 150,
            useNativeDriver: true,
          } as Animated.TimingAnimationConfig),
          Animated.timing(animatedMargin.current, {
            toValue: 0,
            duration: 150,
            useNativeDriver: false,
          } as Animated.TimingAnimationConfig),
        ]).start();
      } else if (dy > -150 && dy < 150) {
        //Animate back to start position
        Animated.parallel([
          Animated.timing(animated.current, {
            toValue: 0,
            duration: 150,
            useNativeDriver: true,
          } as Animated.TimingAnimationConfig),
          Animated.timing(animatedMargin.current, {
            toValue: 0,
            duration: 150,
            useNativeDriver: false,
          } as Animated.TimingAnimationConfig),
        ]).start();
      } else if (dy > 150) {
        // Animate away to bottom
        Animated.parallel([
          Animated.timing(animated.current, {
            toValue: 400,
            duration: 300,
            useNativeDriver: true,
          } as Animated.TimingAnimationConfig),
        ]).start();
      }
    },
  });

  const spacerStyle = {
    marginTop: animatedMargin.current,
  };

  const opacityInterpolate = animated.current.interpolate({
    inputRange: [-400, 0, 400],
    outputRange: [0, 1, 0],
  });
  const modalStyle = {
    transform: [{ translateY: animated.current }],
    opacity: opacityInterpolate,
  };

  return (
    <SBox style={styles.container}>
      <Animated.View style={spacerStyle} />
      <Animated.View
        style={[styles.modal, modalStyle]}
        {...panResponder.panHandlers}
      >
        <SBox style={styles.comments}>
          <ScrollView
            scrollEventThrottle={16}
            onScroll={event => {
              scrollOffset.current = event.nativeEvent.contentOffset.y;
              scrollViewHeight.current =
                event.nativeEvent.layoutMeasurement.height;
            }}
            onContentSizeChange={(width, height) => {
              contentHeight.current = height;
            }}
          >
            <SText style={styles.fakeText}>Top</SText>
            <SBox style={styles.fakeComments} />
            <SText style={styles.fakeText}>Bottom</SText>
          </ScrollView>
        </SBox>
        <SBox style={styles.inputWrap}>
          <Input style={styles.textInput} placeholder="Comment" />
        </SBox>
      </Animated.View>
    </SBox>
  );
};
