import { useState, useCallback } from 'react';
import Stack from '@mui/material/Stack';
import { UploadBox, MultiFilePreview } from '../../components/upload';
import { UseFormSetValue } from 'react-hook-form';
import { Typography } from '@mui/material';
import { useSnackbar } from '@/components/snackbar';
import { transferApi } from '@/shared/api/transfer-file';

interface FileWithPreview extends File {
  preview?: string;
  serverFileName?: string;
}

type Props = {
  files?: string[];
  setValue: UseFormSetValue<any>;
  error?: string | undefined;
};

export default function FileUpload({ files, setValue, error }: Props) {
  const [uploadedFiles, setUploadedFiles] = useState<FileWithPreview[]>([]);
  const [isUploading, setIsUploading] = useState(false);
  const { enqueueSnackbar } = useSnackbar();

  const handleDrop = useCallback(
    async (acceptedFiles: File[]) => {
      setIsUploading(true);
      try {
        const uploadedFilesData = await Promise.all(
          acceptedFiles.map(async (file) => {
            const data = await transferApi.uploadFile(file);
          

            const fileWithPreview = file as FileWithPreview;
            fileWithPreview.preview = URL.createObjectURL(file);
            fileWithPreview.serverFileName = data;
            
            return fileWithPreview;
          })
        );

        setUploadedFiles((prevFiles) => [...prevFiles, ...uploadedFilesData]);
        setValue("files", [...uploadedFiles, ...uploadedFilesData].map(file => ({
          name: file.serverFileName || file.name, 
          path: file.serverFileName || file.name, 
          originalName: file.name,
          size: file.size,
          type: file.type || 'application/octet-stream',
          serverFileName: file.serverFileName
        })));

        enqueueSnackbar('Files uploaded successfully!', { variant: 'success' });
      } catch (error) {
        console.error('Upload error:', error);
        enqueueSnackbar('Failed to upload some files', { variant: 'error' });
      } finally {
        setIsUploading(false);
      }
    },
    [uploadedFiles, setValue, enqueueSnackbar]
  );

  const handleRemoveFile = useCallback(
    async (fileToRemove: FileWithPreview | string) => {
      try {
        const fileName = typeof fileToRemove === 'string' 
          ? fileToRemove 
          : fileToRemove.serverFileName;

        if (fileName) {
          await transferApi.deleteFile(fileName);
        }

        const filtered = uploadedFiles.filter((file) => {
          if (typeof fileToRemove === 'string') {
            return file.serverFileName !== fileToRemove;
          }
          return file.serverFileName !== fileToRemove.serverFileName;
        });
        
        setUploadedFiles(filtered);
        setValue("files", filtered.map(file => ({
          name: file.serverFileName|| file.name,
          path: file.serverFileName || file.name,
          originalName: file.name,
          size: file.size,
          type: file.type || 'application/octet-stream',
          preview: file.preview
        })));

        enqueueSnackbar('File removed successfully', { variant: 'success' });
      } catch (error) {
        console.error('Delete error:', error);
        enqueueSnackbar('Failed to remove file', { variant: 'error' });
      }
    },
    [uploadedFiles, setValue, enqueueSnackbar]
  );

  const filesToPreview = uploadedFiles.map(file => ({
    ...file,
    preview: file.preview || URL.createObjectURL(file)
  }));

  return (
    <Stack direction="column">
      <Stack direction="row" flexWrap="wrap">
        <MultiFilePreview
          thumbnail
          files={filesToPreview}
          onRemove={handleRemoveFile}
          sx={{ width: 64, height: 64 }}
        />

        <UploadBox 
          onDrop={handleDrop}
          sx={{
            ...(isUploading && {
              opacity: 0.48,
              pointerEvents: 'none',
            }),
          }}
        />
      </Stack>

      {(uploadedFiles.length === 0 && error) && (
      <Typography 
        variant="body2" 
        color="error" 
        sx={{ pl: "-12px" }}
      >
        {error || 'Please upload at least one file'}
      </Typography>
    )}
    </Stack>
  );
}