import { useCallback, useContext, useEffect, useRef } from 'react';

import audioContext from '@/lib/audioContext';
import { AUDIO_FILE_TYPES_STRING } from '@/utils/constants';
import removeFileExtension from '@/utils/removeFileExtension';

import UploadStateContext from '../../uploaderV2/UploadStateContext';

export default function useFileInput(props: {
  onFileSelect: (file: File, audioBuffer: AudioBuffer) => void;
}) {
  const { onFileSelect } = props;

  // TODO useContextSelector
  const uploadState = useContext(UploadStateContext);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const openFileInput = useCallback(() => {
    if (fileInputRef.current) {
      fileInputRef.current.click();
    }
  }, []);

  const handleFileSelect = useCallback(
    async (e: Event) => {
      const target = e.target as HTMLInputElement;
      const files = Array.from(target.files || []);
      if (files.length === 0) {
        uploadState.setUploadFileConfig(null);
        return;
      }
      const file = files[0];
      const arrayBuffer = await file.arrayBuffer();
      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
      uploadState.setUploadFileConfig({
        clientSelectedFile: file,
        audioBuffer: audioBuffer,
        title: removeFileExtension(file.name),
      });
      uploadState.setIsRecordingMode(false);
      if (fileInputRef.current) fileInputRef.current.value = '';
      onFileSelect(file, audioBuffer);
    },
    [uploadState, onFileSelect]
  );

  useEffect(() => {
    const fileInput = document.createElement('input');
    fileInput.type = 'file';
    fileInput.accept = AUDIO_FILE_TYPES_STRING;
    fileInput.style.display = 'none';
    fileInput.onchange = handleFileSelect;
    fileInputRef.current = fileInput;
    document.body.appendChild(fileInput);

    return () => {
      if (fileInput.parentNode) {
        fileInput.parentNode.removeChild(fileInput);
      }
      fileInputRef.current = null;
    };
  }, [handleFileSelect]);

  return openFileInput;
}
