import React, {memo} from 'react';
import {
  IconChevronUp,
  IconLockOpen,
  IconMicrophone,
} from '@tabler/icons-react-native';
import Animated, {
  Extrapolation,
  SharedValue,
  clamp,
  interpolate,
  useAnimatedReaction,
  useAnimatedStyle,
  useSharedValue,
  withDelay,
  withTiming,
} from 'react-native-reanimated';
import {AUDIO_ANIMATED_VALUES} from '@modules/chats/constants';
import {useTheme} from '@shared/theme';

import {styles} from './styles';

interface Props {
  isLocked: SharedValue<number>;
  isPressing: SharedValue<number>;
  isCanceling: SharedValue<number>;
  translationY: SharedValue<number>;
}

const ANIMATION_DURATION = 200;

function VoiceRecordingLocker({
  isLocked,
  isCanceling,
  isPressing,
  translationY,
}: Props) {
  const {theme, iconSizes} = useTheme();

  const isControllerVisible = useSharedValue(0);
  const isLockCircleVisible = useSharedValue(0);

  const controllerBGColor = theme.background.layout.tertiary;
  const controllerBorderColor = theme.border.neutral.default;

  const containerAnimatedStyle = useAnimatedStyle(() => {
    if (!_WORKLET) {
      return {
        transform: [{translateY: 0}],
      };
    }

    return {
      transform: [
        {
          translateY: clamp(
            translationY.value,
            -AUDIO_ANIMATED_VALUES.lockThreshold,
            0,
          ),
        },
      ],
    };
  });

  const controllerAnimatedStyle = useAnimatedStyle(() => {
    if (!_WORKLET) {
      return {
        height: 60,
        borderColor: controllerBorderColor,
        backgroundColor: controllerBGColor,
        display: 'none',
        opacity: 0,
      };
    }

    return {
      height:
        interpolate(
          isControllerVisible.value,
          [0, 1],
          [60, 121],
          Extrapolation.CLAMP,
        ) -
        interpolate(
          translationY.value,
          [0, -AUDIO_ANIMATED_VALUES.lockThreshold],
          [0, AUDIO_ANIMATED_VALUES.lockThreshold / 2],
          Extrapolation.CLAMP,
        ),
      borderColor: controllerBorderColor,
      backgroundColor: controllerBGColor,
      display: isControllerVisible.value !== 0 ? 'flex' : 'none',
      opacity:
        interpolate(isControllerVisible.value, [0, 0.4, 1], [0, 0, 1]) -
        isLocked.value,
    };
  });

  const lockCircleAnimatedStyle = useAnimatedStyle(() => {
    if (!_WORKLET) {
      return {
        opacity: 0,
        display: 'none',
        transform: [{translateY: 25}],
      };
    }

    return {
      opacity: isLockCircleVisible.value - (1 - isLocked.value), // Hide immediately when not locked
      display: isLockCircleVisible.value !== 0 ? 'flex' : 'none',
      transform: [
        {
          translateY: interpolate(isLockCircleVisible.value, [0, 1], [25, -25]),
        },
      ],
    };
  });

  useAnimatedReaction(
    () => isPressing.value,
    val => {
      if (val) {
        isControllerVisible.value = withDelay(
          AUDIO_ANIMATED_VALUES.showLockerDelay,
          withTiming(1, {duration: ANIMATION_DURATION}),
        );
      } else {
        isControllerVisible.value = withTiming(0, {
          duration: ANIMATION_DURATION,
        });
      }
    },
    [],
  );

  useAnimatedReaction(
    () =>
      isControllerVisible.value === 1 &&
      isPressing.value === 1 &&
      (isCanceling.value || isLocked.value),
    (val, prevValue) => {
      if (val && prevValue !== val) {
        isControllerVisible.value = withTiming(0, {
          duration: ANIMATION_DURATION,
        });
      }
    },
    [],
  );

  useAnimatedReaction(
    () =>
      isLocked.value &&
      translationY.value === -AUDIO_ANIMATED_VALUES.lockThreshold,
    (val, prev) => {
      if (val && prev !== val) {
        isLockCircleVisible.value = withTiming(
          1,
          {duration: ANIMATION_DURATION},
          () => {
            isLockCircleVisible.value = withDelay(
              1000,
              withTiming(0, {duration: 100}),
            );
          },
        );
      }
    },
    [],
  );

  return (
    <Animated.View
      pointerEvents={'none'}
      style={[styles.container, containerAnimatedStyle]}>
      <Animated.View style={[styles.controller, controllerAnimatedStyle]}>
        <IconLockOpen />
        <IconChevronUp />
        <IconMicrophone size={iconSizes.x6} style={styles.iconMicrophone} />
      </Animated.View>
      <Animated.View
        style={[
          styles.circleLock,
          {backgroundColor: theme.brand[500]},
          lockCircleAnimatedStyle,
        ]}>
        <IconLockOpen color={theme.text.neutral.inverted} />
      </Animated.View>
    </Animated.View>
  );
}

export default memo(VoiceRecordingLocker);
