import React, { useEffect, useRef, useState } from 'react';
import { Animated, View } from 'react-native';
import { PanGestureHandler, PanGestureHandlerStateChangeEvent, State } from 'react-native-gesture-handler';
import { TextNative } from '../TextNative';

export function TimeDayPicker(): any {
   return (
      <>
         <View style={{ flexDirection: 'row' }}>
            <View style={{ flex: 1 }}>
               <TimeClock sizeNumber={24} />
            </View>
            <View style={{ width: 1, backgroundColor: '#eee' }} />
            <View style={{ flex: 1 }}>
               <TimeClock sizeNumber={60} />
            </View>
         </View>
      </>
   );
}

function TimeClock({ sizeNumber }) {
   const panGestureHandlertranslateY = useRef(new Animated.Value(0)).current;
   const posRelativeNumber = useRef(Array.from({ length: sizeNumber }, (v, k) => new Animated.Value(0))).current;
   const size = 30;
   const offsetOpacity = useRef(new Animated.Value(0)).current;
   const [items, setItems] = useState(Array.from({ length: sizeNumber }, (v, k) => k));

   const scrollOffsetY = useRef(new Animated.Value(0)).current;
   const animationDecay = useRef(new Animated.Value(0)).current;
   const animationScrollY = useRef(
      Animated.multiply(Animated.add(panGestureHandlertranslateY, scrollOffsetY), animationDecay),
   ).current;
   const animation = useRef<any>();

   const scrollY = useRef(0);
   const scrollYDecay = useRef(0);

   function updateOffsetNumbers(): void {
      const scrollPos = scrollYDecay.current + scrollY.current + size * 20;
      posRelativeNumber.forEach((n, i) => {
         const x = Math.floor((scrollPos + i * size) / (sizeNumber * size));
         posRelativeNumber[i].setValue(x * (sizeNumber * size));
      });
   }

   function setPosCorrect() {
      const x = Math.abs(((scrollYDecay.current + scrollY.current) % (size * sizeNumber)) % size);

      // console.log(scrollY.current + scrollYDecay.current, x);

      if (scrollYDecay.current + scrollY.current > 0) {
         if (scrollY.current > size / 3) {
            scrollY.current -= x;
         } else {
            scrollY.current += size - x;
         }
      } else if (scrollY.current > size / 3) {
         scrollY.current -= size - x;
      } else {
         scrollY.current += x;
      }

      Animated.timing(scrollOffsetY, {
         toValue: scrollY.current,
         duration: 100,
         useNativeDriver: true,
      }).start();
   }

   function updateRelativePos(addValue = 0) {
      if (scrollYDecay.current + scrollY.current >= 0) {
         offsetOpacity.setValue(
            200 +
               size * sizeNumber -
               Math.abs((scrollYDecay.current + addValue + scrollY.current) % (size * sizeNumber)),
         );
      } else {
         offsetOpacity.setValue(
            200 + Math.abs((scrollYDecay.current + addValue + scrollY.current) % (size * sizeNumber)),
         );
      }
   }

   useEffect(() => {
      animationDecay.addListener(({ value }) => {
         // console.log(Math.abs(value - scrollYDecay.current));
         if (Math.abs(value - scrollYDecay.current) < 1) {
            animation.current?.stop();
            if (value > 0) {
               setPosCorrect();
            } else {
               setPosCorrect();
            }
         }

         scrollYDecay.current = value;
         updateRelativePos();
         updateOffsetNumbers();
      });

      panGestureHandlertranslateY.addListener(({ value }) => {
         updateRelativePos(value);
         updateOffsetNumbers();
      });
   }, []);

   const animatedEvent = useRef(
      Animated.event(
         [
            {
               nativeEvent: {
                  translationY: panGestureHandlertranslateY,
               },
            },
         ],
         {
            useNativeDriver: true,
         },
      ),
   ).current;

   const onHandlerStateChange = (event: PanGestureHandlerStateChangeEvent): void => {
      const { translationY, velocityY, y } = event.nativeEvent;

      if (event.nativeEvent.oldState === State.UNDETERMINED) {
         animation.current?.stop();
      }

      scrollY.current += translationY;

      if (event.nativeEvent.oldState === State.ACTIVE) {
         panGestureHandlertranslateY.setValue(0);
         scrollOffsetY.setValue(scrollY.current);

         if (Math.abs(velocityY / 1500) > 0.15) {
            animation.current = Animated.decay(animationDecay, {
               velocity: velocityY / 1500,
               deceleration: 0.99,
               useNativeDriver: true,
            });

            animation.current.start();
         } else {
            updateRelativePos();
            setPosCorrect();
         }
      }

      updateRelativePos();
   };

   return (
      <>
         <PanGestureHandler maxPointers={1} onGestureEvent={animatedEvent} onHandlerStateChange={onHandlerStateChange}>
            <Animated.View
               style={{
                  overflow: 'hidden',
                  height: size * 3,
               }}
            >
               {items.map((m, i) => {
                  const A1 = 200 + (i - 1) * size - size * 0.6;
                  const B1 = 200 + (i - 1) * size - size * 0.3;
                  const A2 = 200 + (i - 1) * size;
                  const B2 = 200 + (i - 1) * size + size * 0.3;
                  const A3 = 200 + (i - 1) * size + size * 0.6;

                  return (
                     <Animated.View
                        key={i}
                        style={{
                           flexDirection: 'row',
                           alignItems: 'center',
                           justifyContent: 'center',
                           height: size,
                           opacity: offsetOpacity.interpolate({
                              inputRange: [A1, B1, A2, B2, A3],
                              outputRange: [0.2, 0.9, 1, 0.9, 0.2],
                              extrapolate: 'clamp',
                           }),
                           transform: [
                              {
                                 translateY: Animated.subtract(animationScrollY, posRelativeNumber[i]),
                              },
                           ],
                        }}
                     >
                        <TextNative size={20} style={{ justifyContent: 'center' }}>
                           {m}
                        </TextNative>
                     </Animated.View>
                  );
               })}
            </Animated.View>
         </PanGestureHandler>
      </>
   );
}
