import React, { useState, useEffect, useRef, useMemo, memo } from 'react';
import { StyleSheet, AccessibilityInfo } from 'react-native';
import Animated, {
  useSharedValue,
  useAnimatedStyle,
  withTiming,
  Easing,
} from 'react-native-reanimated';
import { scheduleOnRN } from 'react-native-worklets';
import { CENTER, COLORS, FONT, SIZES } from '../../constants';
import FullLoadingScreen from './loadingScreen';
import { useGlobalThemeContext } from '../../../context-store/theme';
import GetThemeColors from '../../hooks/themeColors';
import {
  DEFAULT_ANIMATION_DURATION,
  RESET_AFTER_SUCCESS_DEFAULT_DELAY,
  SHOULD_ANIMATE_VIEW_ON_SUCCESS,
  SWIPE_SUCCESS_THRESHOLD,
} from './swipeButton/constants';
import { SwipeThumb } from './swipeButton/swipeThumb';
import { useTranslation } from 'react-i18next';
import { useAppStatus } from '../../../context-store/appStatus';

const containerStyles = StyleSheet.create({
  container: {
    borderWidth: 1,
    justifyContent: 'center',
    overflow: 'hidden',
    ...CENTER,
  },
  title: {
    alignSelf: 'center',
    position: 'absolute',
    fontFamily: FONT.Title_Regular,
    includeFontPadding: false,
    fontSize: 17,
  },
});

const SwipeButtonNew = memo(function SwipeButtonNew({
  containerStyles: customContainerStyles = {},
  disabled = false,
  disableResetOnTap = false,
  enableReverseSwipe = false,
  forceReset,
  height = 55,
  onSwipeFail,
  onSwipeStart,
  onSwipeSuccess,
  railStyles = {},
  resetAfterSuccessAnimDelay,
  resetAfterSuccessAnimDuration,
  shouldResetAfterSuccess,
  swipeSuccessThreshold = SWIPE_SUCCESS_THRESHOLD,
  thumbIconComponent,
  thumbIconStyles = {},
  thumbIconWidth,
  title,
  shouldAnimateViewOnSuccess = SHOULD_ANIMATE_VIEW_ON_SUCCESS,
  width = 0.95,
  maxWidth = 375,
  shouldDisplaySuccessState = false,
}) {
  const { screenDimensions } = useAppStatus();
  const { theme, darkModeType } = useGlobalThemeContext();
  const { backgroundColor, backgroundOffset } = GetThemeColors();
  const windowDimensions = screenDimensions.width * width;
  const layoutWidth = windowDimensions > maxWidth ? maxWidth : windowDimensions;
  const [screenReaderEnabled, setScreenReaderEnabled] = useState(false);
  const [isUnmounting, setIsUnmounting] = useState(false);
  const { t } = useTranslation();
  const titleText = title || t('constants.slideToConfirm');

  const containerAnimatedWidth = useSharedValue(layoutWidth);
  const textOpacity = useSharedValue(1);
  const textTranslateX = useSharedValue(0);
  const loadingAnimationOpacity = useSharedValue(0);

  const [showLoadingIcon, setShowLoadingIcon] = useState(false);
  const prevPoint = useRef(0);

  const containerStyle = useAnimatedStyle(() => {
    return {
      width: containerAnimatedWidth.value,
    };
  });

  const textStyle = useAnimatedStyle(() => {
    return {
      opacity: textOpacity.value,
      transform: [{ translateX: textTranslateX.value }],
    };
  });

  const loadingStyle = useAnimatedStyle(() => {
    return {
      opacity: loadingAnimationOpacity.value,
    };
  });

  const handleSwipeProgress = progress => {
    const jumpDistance = Math.abs(prevPoint.current - progress);
    prevPoint.current = progress;

    const shouldAnimate = jumpDistance > 0.1;
    const duration = shouldAnimate ? 200 : 0;

    textOpacity.value = withTiming(1 - progress, {
      duration,
      easing: Easing.linear,
    });
    textTranslateX.value = withTiming(progress * 100, {
      duration,
      easing: Easing.linear,
    });
  };

  const reset = () => {
    scheduleOnRN(setShowLoadingIcon, false);
    containerAnimatedWidth.value = withTiming(layoutWidth, { duration: 200 });
    loadingAnimationOpacity.value = withTiming(0, { duration: 200 });
  };

  const animateViewOnSuccess = () => {
    if (!shouldAnimateViewOnSuccess) return;
    const thumbSize = height + 3 + 2;
    scheduleOnRN(setShowLoadingIcon, true);

    containerAnimatedWidth.value = withTiming(thumbSize, { duration: 200 });
    loadingAnimationOpacity.value = withTiming(1, { duration: 200 });

    if (!shouldDisplaySuccessState && shouldResetAfterSuccess) {
      const resetDelay =
        DEFAULT_ANIMATION_DURATION +
        (resetAfterSuccessAnimDelay !== undefined
          ? resetAfterSuccessAnimDelay
          : RESET_AFTER_SUCCESS_DEFAULT_DELAY);

      setTimeout(() => {
        reset();
      }, resetDelay);
    }
  };

  useEffect(() => {
    if (shouldDisplaySuccessState) {
      animateViewOnSuccess();
    }
  }, [shouldDisplaySuccessState]);

  // Accessibility setup
  useEffect(() => {
    const handleScreenReaderToggled = isEnabled => {
      if (isUnmounting || screenReaderEnabled === isEnabled) return;
      setScreenReaderEnabled(isEnabled);
    };

    setIsUnmounting(false);

    let subscription;
    try {
      subscription = AccessibilityInfo.addEventListener(
        'change',
        handleScreenReaderToggled,
      );
    } catch {
      AccessibilityInfo.addEventListener('change', handleScreenReaderToggled);
    }

    AccessibilityInfo.isScreenReaderEnabled().then(isEnabled => {
      if (!isUnmounting) setScreenReaderEnabled(isEnabled);
    });

    return () => {
      setIsUnmounting(true);
      if (subscription && subscription.remove) {
        subscription.remove();
      } else {
        AccessibilityInfo.removeEventListener(
          'change',
          handleScreenReaderToggled,
        );
      }
    };
  }, [isUnmounting, screenReaderEnabled]);

  const railDynamicStyles = useMemo(() => {
    return {
      backgroundColor: showLoadingIcon
        ? COLORS.darkModeText
        : theme
        ? COLORS.darkModeText
        : COLORS.primary,
      borderColor: showLoadingIcon
        ? COLORS.darkModeText
        : theme
        ? backgroundOffset
        : backgroundColor,
    };
  }, [theme, darkModeType, showLoadingIcon]);

  const titleDynamicStyles = useMemo(() => {
    return {
      color: theme ? backgroundColor : COLORS.darkModeText,
    };
  }, [theme, darkModeType]);

  return (
    <Animated.View
      style={[
        containerStyles.container,
        containerStyle,
        {
          ...railDynamicStyles,
          ...customContainerStyles,
          borderRadius: (height + 3 + 2) / 2,
        },
      ]}
    >
      {showLoadingIcon ? (
        <Animated.View style={[{ height: height + 3 + 2 }, loadingStyle]}>
          <FullLoadingScreen
            loadingColor={COLORS.lightModeText}
            size="small"
            showText={false}
          />
        </Animated.View>
      ) : (
        <>
          <Animated.Text
            maxFontSizeMultiplier={1}
            ellipsizeMode="tail"
            numberOfLines={1}
            importantForAccessibility={
              screenReaderEnabled ? 'no-hide-descendants' : ''
            }
            style={[containerStyles.title, textStyle, titleDynamicStyles]}
          >
            {titleText}
          </Animated.Text>

          {layoutWidth > 0 && (
            <SwipeThumb
              disabled={disabled}
              disableResetOnTap={disableResetOnTap}
              enableReverseSwipe={enableReverseSwipe}
              forceReset={forceReset}
              layoutWidth={layoutWidth}
              onSwipeFail={onSwipeFail}
              onSwipeStart={onSwipeStart}
              onSwipeSuccess={onSwipeSuccess}
              railStyles={railStyles}
              resetAfterSuccessAnimDelay={resetAfterSuccessAnimDelay}
              resetAfterSuccessAnimDuration={resetAfterSuccessAnimDuration}
              screenReaderEnabled={screenReaderEnabled}
              shouldResetAfterSuccess={shouldResetAfterSuccess}
              swipeSuccessThreshold={swipeSuccessThreshold}
              thumbIconComponent={thumbIconComponent}
              thumbIconHeight={height}
              thumbIconStyles={thumbIconStyles}
              thumbIconWidth={thumbIconWidth}
              title={titleText}
              animateViewOnSuccess={animateViewOnSuccess}
              handleSwipeProgress={handleSwipeProgress}
              theme={theme}
            />
          )}
        </>
      )}
    </Animated.View>
  );
});

export default SwipeButtonNew;
