import React, { useEffect } from 'react';
import {
  Animated,
  Pressable,
  StyleSheet,
  I18nManager,
  View,
} from 'react-native';
import { withTheme, useTheme } from '../../core/theming';
import type { Theme } from '../../utils/types';

interface SwitchProps {
  onValueChange?: () => void;
  switchSize: number;
  isActive: boolean;
  activeColor?: string;
  inActiveColor?: string;
  knobColor?: string;
  isDisabled?: boolean;
  theme: Theme;
}

const TSwitch: React.FC<SwitchProps> = ({
  onValueChange,
  switchSize,
  isActive,
  activeColor,
  inActiveColor,
  isDisabled = false,
}): any => {
  const switchHeight = 24;
  const switchWidth = 42;
  const { colors } = useTheme();
  const trackWidth = switchWidth;
  const trackHeight = switchHeight;
  const knobSize = isActive ? switchHeight - 2 : switchHeight - 4;

  const knobAnim = React.useRef(new Animated.Value(0)).current;
  const knobPos = I18nManager.isRTL
    ? isActive
      ? -36 / 4
      : 34 / 4
    : isActive
    ? 36 / 4
    : -34 / 4;

  const trackAnim = React.useRef(new Animated.Value(0)).current;
  const trackColor = isActive ? 75 : -75;

  const interpolatedColorAnimation = trackAnim.interpolate({
    inputRange: [-75, 75],
    outputRange: [
      (inActiveColor = inActiveColor || colors.white),
      (activeColor = activeColor || colors.black),
    ],
  });

  const knobColorAnimation = trackAnim.interpolate({
    inputRange: [-75, 75],
    outputRange: [colors.black, colors.white],
  });

  useEffect(() => {
    Animated.parallel([
      Animated.spring(knobAnim, {
        toValue: knobPos,
        useNativeDriver: false,
      }),
      Animated.timing(trackAnim, {
        toValue: trackColor,
        duration: 200,
        useNativeDriver: false,
      }),
    ]).start();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isActive]);

  const handleSwitch = () => {
    if (isDisabled) {
      return;
    }
    if (onValueChange) {
      onValueChange();
    }
  };

  const stylesWithProp = styles();

  return (
    <Pressable onPress={handleSwitch} style={{ width: switchSize }}>
      <View style={stylesWithProp.container}>
        <Animated.View
          style={[
            stylesWithProp.trackView,
            {
              width: trackWidth,
              height: trackHeight,
              borderRadius: trackHeight / 2,
              borderColor: isDisabled ? colors.greyOpac50 : colors.black,
              backgroundColor: isDisabled
                ? colors.greyOpac10
                : interpolatedColorAnimation,
            },
          ]}
        />
        <Animated.View
          style={[
            {
              width: switchSize,
              height: switchSize,
              borderRadius: switchSize / 2,
              transform: [{ translateX: knobAnim }],
            },
            stylesWithProp.knobContainer,
          ]}
        >
          <Animated.View
            style={{
              width: knobSize,
              height: knobSize,
              borderRadius: knobSize / 2,
              backgroundColor: isDisabled
                ? colors.greyOpac50
                : knobColorAnimation || colors.black,
            }}
          />
        </Animated.View>
      </View>
    </Pressable>
  );
};

export default withTheme(TSwitch);

const styles = () =>
  StyleSheet.create({
    container: {
      alignItems: 'center',
      justifyContent: 'center',
    },
    trackView: {
      position: 'absolute',
      borderWidth: 1,
    },
    knobContainer: {
      alignItems: 'center',
      justifyContent: 'center',
    },
  });
