import styled from '@emotion/styled';
import { useCallback, useContext, useState } from 'react';

import { DropOverlay } from '@/app/(root)/dragAndDrop/Droppable';
import { useContextSelector } from '@/hooks/useContextSelector';
import audioContext from '@/lib/audioContext';
import removeFileExtension from '@/utils/removeFileExtension';

import UploadStateContext from '../../uploaderV2/UploadStateContext';
import CreateFormContext from '../../v2/CreateFormContext';
import { CreateFormModals } from '../../v2/types';

const ShadedDropOverlay = styled(DropOverlay)`
  background-color: var(--color-opacity-black-60);
  backdrop-filter: blur(10px);
  z-index: 1000;
`;

export default function CreateFileDropReceiver({
  children,
}: {
  children: React.ReactNode;
}) {
  const [showDropOverlay, setShowDropOverlay] = useState(false);
  const uploadState = useContext(UploadStateContext);
  const { setIsUploadInProgress } = useContext(UploadStateContext);
  const setActiveModal = useContextSelector(
    CreateFormContext,
    (context) => context.setActiveModal
  );

  const handleDrop = useCallback(
    async (e: React.DragEvent<HTMLDivElement>) => {
      setShowDropOverlay(false);
      if (e.dataTransfer.types.includes('Files')) {
        e.stopPropagation();
        e.preventDefault();

        const files = Array.from(e.dataTransfer.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);
        setIsUploadInProgress(true);
        setActiveModal(CreateFormModals.AudioUpload);
      }
    },
    [setIsUploadInProgress, setActiveModal, uploadState]
  );

  const handleDragOver = useCallback((e: React.DragEvent<HTMLDivElement>) => {
    if (e.dataTransfer.types.includes('Files')) {
      setShowDropOverlay(true);
      e.preventDefault();
    }
  }, []);

  const handleDragLeave = useCallback(() => {
    setShowDropOverlay(false);
  }, []);

  return (
    <div
      onDragOver={handleDragOver}
      onDrop={handleDrop}
      onDragLeave={handleDragLeave}
    >
      {children}
      {showDropOverlay && <ShadedDropOverlay>Drop Here</ShadedDropOverlay>}
    </div>
  );
}
