import {useEffect, useRef, useMemo} from 'react';
import {NativeEventEmitter, NativeModules} from 'react-native';
import {VolumeManager} from 'react-native-volume-manager';
import debounce from 'lodash.debounce';
import {isAndroid, isIos} from '@shared/utils';

const RELEASE_DEBOUNCE_MS = 500;

const {VolumeButtonListener} = NativeModules;

type VolumeButtonCallbacks = {
  onTakePhoto: () => void;
  currentRecordType: 'photo' | 'video';
  isPreviewVisible: boolean;
};

export const useVolumeButtonAsShutter = ({
  onTakePhoto,
  currentRecordType,
  isPreviewVisible,
}: VolumeButtonCallbacks) => {
  const onTakePhotoRef = useRef(onTakePhoto);
  const currentRecordTypeRef = useRef(currentRecordType);
  const savedVolumeRef = useRef<number | null>(null);

  useEffect(() => {
    onTakePhotoRef.current = onTakePhoto;
  }, [onTakePhoto]);
  useEffect(() => {
    currentRecordTypeRef.current = currentRecordType;
  }, [currentRecordType]);

  const iosListenerRef = useRef<{remove: () => void} | null>(null);
  const androidListenerRef = useRef<{remove: () => void} | null>(null);

  const debouncedAction = useMemo(
    () =>
      debounce(
        () => {
          if (currentRecordTypeRef.current === 'photo') {
            onTakePhotoRef.current();
          }
        },
        RELEASE_DEBOUNCE_MS,
        {leading: true, trailing: false},
      ),
    [],
  );

  const clear = () => {
    if (isIos) {
      iosListenerRef.current?.remove();
      VolumeManager.showNativeVolumeUI({enabled: true});
    } else if (isAndroid) {
      androidListenerRef.current?.remove();
      VolumeButtonListener.setEnabled(false);
    }
    debouncedAction.cancel();
  };

  useEffect(() => {
    if (isPreviewVisible) {
      clear();
      return;
    }

    if (isIos) {
      VolumeManager.setActive(true);
      VolumeManager.showNativeVolumeUI({enabled: false});
      VolumeManager.getVolume().then(result => {
        savedVolumeRef.current = result.volume;
      });
      iosListenerRef.current = VolumeManager.addVolumeListener(() => {
        debouncedAction();
      });
    } else if (isAndroid) {
      VolumeButtonListener.setEnabled(true);
      const emitter = new NativeEventEmitter(VolumeButtonListener);
      androidListenerRef.current = emitter.addListener(
        'onVolumeButtonPress',
        () => {
          debouncedAction();
        },
      );
    }

    return () => {
      clear();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isPreviewVisible]);
};
