import React, { useRef } from 'react';
import { Animated, GestureResponderEvent, PanResponder } from 'react-native';
import {
  // PanGestureHandler,
  TouchableWithoutFeedback,
} from 'react-native-gesture-handler';
import { SText } from '../../s-components/typography/s-text';
import { SBox } from '../../s-components/layout/s-box';
import { SBoxAnimated } from '../../s-components/layout/s-box-animated';
import { fp as _ } from '../../utils/fp';
import { ScrollViewLock } from '../../utils/animation-service';

type TProps = {};

// https://codedaily.io/tutorials/21/Pan-Responder-Inside-of-a-ScrollView
// https://www.programmersought.com/article/4969737328/
// https://github.com/facebook/react-native/issues/1046
// https://github.com/mjracca/react-native-scroll-block
// https://docs.swmansion.com/react-native-gesture-handler/docs/handler-pan
// https://github.com/rome2rio/react-native-touch-through-view
// https://blog.bitsrc.io/using-the-gesture-handler-in-react-native-c07f84ddfa49
// https://medium.com/@andi.gu.ca/react-native-3d-animations-2b2a14552feb
// https://github.com/facebook/react-native/releases/tag/v0.53.0
// https://stackoverflow.com/questions/38142552/scrollview-how-to-reproduce-snaptointerval-and-snaptoalignment-for-android#comment85464652_45666362
export const DraggableCards: React.FC<TProps> = () => {
  const animation = useRef(new Animated.Value(0));
  const animationXY = useRef(new Animated.ValueXY({ x: 0, y: 0 }));

  const resetAnimation = () => {
    animationXY.current.setValue({ x: 0, y: 0 });
    animationXY.current.setOffset({ x: 0, y: 0 });
  };

  const startAnimation = () => {
    const onChange = (params: any) => {
      // console.tron.log(params);
      // eslint-disable-next-line
      console.log(params);
    };

    animation.current.addListener(onChange);

    // Animated.timing(animation, {
    //   toValue: 300,
    //   duration: 1500,
    //   useNativeDriver: true,
    // }).start(() => {
    //   // jump to start
    //   animation.setValue(0);
    // });
    Animated.spring(animation.current, {
      toValue: 300,
      friction: 2,
      tension: 160,
      useNativeDriver: true,
    }).start(() => {
      Animated.timing(animation.current, {
        toValue: 0,
        duration: 1000,
        useNativeDriver: true,
      }).start(() => {
        animation.current.removeAllListeners();
      });
    });
  };

  const getTranslation = () => {
    return {
      transform: [
        {
          translateY: animation.current,
        },
      ],
    };
  };

  // componentDidMount() {
  //   setTimeout(() => {
  //     ScrollViewLock.next(true);
  //   }, 1000);
  // }
  //
  // componentWillUnmount() {
  //   ScrollViewLock.next(false);
  // }

  const panResponder = PanResponder.create({
    // onStartShouldSetPanResponder: _.T,
    onStartShouldSetPanResponder: _.T,
    onMoveShouldSetPanResponder: _.T,
    // onMoveShouldSetPanResponderCapture: _.T,
    // eslint-disable-next-line
    onPanResponderGrant: (e: GestureResponderEvent) => {
      // console.log('grant');
      animationXY.current.stopAnimation();
      animationXY.current.extractOffset();

      ScrollViewLock.next(true);
    },
    onPanResponderMove: Animated.event(
      [
        // don't interested in 1-st argument of onPanResponderMove only in 2-nd
        null,
        // eslint-disable-next-line
        { dx: animationXY.current.x, dy: animationXY.current.y },
      ],
      { useNativeDriver: false } as Animated.EventConfig<any>
    ),
    // onPanResponderTerminationRequest: () => false,
    onPanResponderRelease: (e, { vx, vy }) => {
      // merge offset to value and remove offset
      animationXY.current.flattenOffset();
      Animated.decay(animationXY.current, {
        velocity: { x: vx, y: vy },
        deceleration: 0.997,
        useNativeDriver: true,
      } as Animated.DecayAnimationConfig).start();

      ScrollViewLock.next(false);
    },
    // onShouldBlockNativeResponder: _.T,
  });

  return (
    <SBox flex={1}>
      <Animated.View
        // flex={1}
        {...panResponder.panHandlers}
        style={{ flex: 1, backgroundColor: '#9798A7' }}
        // Pan responder doesn't work with views without color on android
        // https://stackoverflow.com/a/51833007/6190198
      >
        <TouchableWithoutFeedback onPress={startAnimation}>
          <SText>Start spring animation</SText>
        </TouchableWithoutFeedback>
        <TouchableWithoutFeedback onPress={resetAnimation}>
          <SBoxAnimated
            width={50}
            height={50}
            bg="orange"
            style={[getTranslation()]}
          >
            <SText>Reset</SText>
          </SBoxAnimated>
        </TouchableWithoutFeedback>

        <SBoxAnimated
          width={200}
          height={50}
          bg="red"
          style={[
            {
              transform: [
                {
                  translateY: animationXY.current.y,
                },
              ],
            },
          ]}
        >
          <SText>Throw me</SText>
        </SBoxAnimated>
      </Animated.View>
    </SBox>
  );
};

// const circleRadius = 30;
// export class SnapCarousel extends PureComponent {
//   _touchY = new Animated.Value(
//     Dimensions.get('window').height / 2 - circleRadius
//   );
//
//   _onPanGestureEvent = Animated.event([{ nativeEvent: { y: this._touchY } }], {
//     useNativeDriver: true,
//   });
//
//   render() {
//     return (
//       <SBox>
//         <SText>This variant works from react-native-gesture-handlers and even block automatically parent ScrollView</SText>
//         <SText>However Animated.View should be a first child not SBoxAnimated</SText>
//         <SText>It doesn't have release event - it only handle move</SText>
//         <PanGestureHandler onGestureEvent={this._onPanGestureEvent}>
//           <Animated.View
//             style={{
//               height: 150,
//               justifyContent: 'center',
//             }}
//           >
//             <Animated.View
//               style={[
//                 {
//                   backgroundColor: '#42a5f5',
//                   borderRadius: circleRadius,
//                   height: circleRadius * 2,
//                   width: circleRadius * 2,
//                 },
//                 {
//                   transform: [
//                     {
//                       translateY: Animated.add(
//                         this._touchY,
//                         new Animated.Value(-circleRadius)
//                       ),
//                     },
//                   ],
//                 },
//               ]}
//             />
//           </Animated.View>
//         </PanGestureHandler>
//       </SBox>
//     );
//   }
// }
