import {StyleSheet, TouchableOpacity} from 'react-native';
import {useNavigation} from '@react-navigation/native';
import {IconBolt, IconBoltOff, IconX} from '@tabler/icons-react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Animated, {
  SharedValue,
  useAnimatedProps,
  useAnimatedStyle,
  withTiming,
} from 'react-native-reanimated';
import {TextInput} from 'react-native-gesture-handler';

import {
  CAMERA_BUTTON_BACKGROUND_COLOR,
  CAMERA_BUTTON_BORDER_COLOR,
  styles,
  TIMER_TEXT_INPUT_ACTIVE_COLOR,
  TIMER_TEXT_INPUT_BORDER_COLOR,
} from './styles';
import {iconRotationSV} from '../../utils';

Animated.addWhitelistedNativeProps({text: true});
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);

type Props = {
  flash: 'on' | 'off';
  // Display flash button, only available if device has flash or torch
  flashAvailable?: boolean;
  onToggleFlash: () => void;
  recordType: SharedValue<'photo' | 'video'>;
  timerSeconds: SharedValue<number>;
  isRecordingSV: SharedValue<number>;
};

export const CameraTopControls: React.FC<Props> = ({
  flash,
  flashAvailable,
  onToggleFlash,
  recordType,
  timerSeconds,
  isRecordingSV,
}) => {
  const navigation = useNavigation();
  const {top} = useSafeAreaInsets();

  const flashButtonStyle = StyleSheet.create({
    button: {
      backgroundColor:
        flash === 'off'
          ? styles.button.backgroundColor
          : styles.flashButtonActive.backgroundColor,
    },
  });

  const iconRotationStyle = useAnimatedStyle(() => ({
    transform: [{rotate: `${iconRotationSV.value}deg`}],
  }));

  const durationVideoStyle = useAnimatedStyle(() => ({
    opacity: withTiming(
      isRecordingSV.value === 1 || recordType.value === 'video' ? 1 : 0,
      {
        duration: 100,
      },
    ),
  }));

  const animatedProps = useAnimatedProps(() => {
    const minutes = Math.floor(timerSeconds.value / 60);
    const seconds = timerSeconds.value % 60;
    const formattedTime = `${minutes.toString().padStart(2, '0')}:${seconds
      .toString()
      .padStart(2, '0')}`;
    return {
      text: formattedTime,
      value: formattedTime,
    };
  });

  const animatedTextInputStyle = useAnimatedStyle(() => ({
    backgroundColor: withTiming(
      isRecordingSV.value === 1
        ? TIMER_TEXT_INPUT_ACTIVE_COLOR
        : CAMERA_BUTTON_BACKGROUND_COLOR,
    ),
    borderColor: withTiming(
      isRecordingSV.value === 1
        ? TIMER_TEXT_INPUT_BORDER_COLOR
        : CAMERA_BUTTON_BORDER_COLOR,
    ),
  }));
  const hideButtonAnimatedStyle = useAnimatedStyle(() => ({
    opacity: withTiming(isRecordingSV.value === 1 ? 0 : 1, {
      duration: 100,
    }),
  }));

  return (
    <Animated.View style={[styles.controlsTop, {top}]}>
      <Animated.View
        style={[styles.controlWrapperTop, hideButtonAnimatedStyle]}>
        <TouchableOpacity
          onPress={() => navigation.goBack()}
          style={styles.button}>
          <IconX size={24} color="white" />
        </TouchableOpacity>
      </Animated.View>
      <Animated.View style={[styles.controlWrapperTop, durationVideoStyle]}>
        <AnimatedTextInput
          editable={false}
          pointerEvents="none"
          animatedProps={animatedProps}
          style={[styles.timerTextInput, animatedTextInputStyle]}
        />
      </Animated.View>
      {flashAvailable && (
        <Animated.View
          style={[styles.controlWrapperTop, hideButtonAnimatedStyle]}>
          <TouchableOpacity
            onPress={onToggleFlash}
            style={[styles.button, flashButtonStyle.button]}>
            <Animated.View style={iconRotationStyle}>
              {flash === 'off' ? (
                <IconBoltOff size={24} color="white" />
              ) : (
                <IconBolt size={24} color="black" />
              )}
            </Animated.View>
          </TouchableOpacity>
        </Animated.View>
      )}
    </Animated.View>
  );
};
