import React, {memo, useCallback, useEffect} from 'react';
import {View} from 'react-native';
import {
  IconMicrophone,
  IconPlayerPause,
  IconSend,
  IconTrash,
} from '@tabler/icons-react-native';
import Animated, {
  interpolate,
  useAnimatedReaction,
  useAnimatedStyle,
  useDerivedValue,
  useSharedValue,
  withTiming,
} from 'react-native-reanimated';
import {scheduleOnRN} from 'react-native-worklets';
import {IconButton} from '@components/index';
import {formatSecondsToTime} from '@modules/chat/utils';
import {
  useAudioRecording,
  useAudioRecordingAnimated,
} from '@modules/chats/contexts';
import {useWaveformBarHeights} from '@modules/chats/hooks/useWaveformBarHeights';
import {useTheme} from '@shared/theme';

import VoiceRecordingInfo from './components/VoiceRecordingInfo';
import VoiceRecordingPlayer from './components/VoiceRecordingPlayer';
import {styles} from './styles';

export interface VoiceRecordingPanelLockedProps {
  onSendPress: () => void;
}

export const VoiceRecordingPanelLocked = memo(
  ({onSendPress}: VoiceRecordingPanelLockedProps) => {
    const {theme} = useTheme();
    const {
      status,
      audioUri,
      audioDurationSeconds,
      cancelRecording,
      pauseRecording,
      meteringLevel,
      resumeRecording,
    } = useAudioRecording();
    const {isLocked, reset, isActive} = useAudioRecordingAnimated();
    const isPaused = status === 'paused';
    const isStopped = status === 'stopped';
    const isPausedAnimated = useSharedValue(0);
    const isLockedAnimated = useDerivedValue(() => {
      return withTiming(isLocked.value, {
        duration: 100,
      });
    });

    const {
      liveBarHeights,
      compressedBarHeights,
      reset: resetWaveformBars,
    } = useWaveformBarHeights({
      meteringLevel,
      isActive: status === 'recording',
    });

    const onCancelPress = useCallback(() => {
      cancelRecording({withHaptic: true});
      reset();
      resetWaveformBars();
    }, [reset, cancelRecording, resetWaveformBars]);

    const containerAnimatedStyle = useAnimatedStyle(() => {
      if (!_WORKLET) {
        return {
          opacity: 0,
          left: 0,
          zIndex: -1,
          bottom: 0,
          position: 'absolute',
          alignSelf: 'center',
          transform: [{translateY: 100}],
        };
      }

      return {
        opacity: isLocked.value,
        left: 0,
        zIndex: isLocked.value > 0 ? 1 : -1,
        bottom: 0,
        position: 'absolute',
        alignSelf: 'center',
        transform: [
          {
            translateY: interpolate(isLockedAnimated.value, [0, 1], [100, 0]),
          },
        ],
      };
    });

    const formattedTime = formatSecondsToTime(audioDurationSeconds);

    useEffect(() => {
      if (isPaused || isStopped) {
        if (isStopped) {
          resetWaveformBars();
        }
        isPausedAnimated.value = withTiming(1, {duration: 100});
      } else {
        isPausedAnimated.value = withTiming(0, {duration: 100});
      }
      // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [isPaused, isStopped]);

    useAnimatedReaction(
      () => isActive.value,
      (active, prevActive) => {
        if (active === prevActive) {
          return;
        }
        scheduleOnRN(resetWaveformBars);
      },
    );

    return (
      <Animated.View
        style={[
          styles.container,
          {backgroundColor: theme.background.layout.tertiary},
          containerAnimatedStyle,
        ]}>
        <VoiceRecordingInfo
          time={formattedTime}
          normalizedBarsHeights={liveBarHeights}
        />
        {(isPaused || isStopped) && audioUri && (
          <VoiceRecordingPlayer
            url={audioUri}
            durationSec={audioDurationSeconds}
            normalizedBarsHeights={compressedBarHeights.value}
          />
        )}
        <View style={styles.controllers}>
          <IconButton
            Icon={IconTrash}
            variant="tertiary"
            onPress={onCancelPress}
            useGestureHandler
          />
          {!isStopped && (
            <IconButton
              Icon={isPaused ? IconMicrophone : IconPlayerPause}
              iconColor={theme.graphics.error[500]}
              variant="tertiary"
              onPress={() => (isPaused ? resumeRecording() : pauseRecording())}
              useGestureHandler
            />
          )}
          <IconButton
            Icon={IconSend}
            variant="secondary"
            onPress={onSendPress}
            useGestureHandler
          />
        </View>
      </Animated.View>
    );
  },
);
