import {
  useCallback,
  useState,
  type DragEvent,
} from 'react';
import {
  Loader2,
  UploadIcon,
} from 'lucide-react';

import { Lang } from '@/lang/Lang';

type FileDataImageEmptyUploadProps = {
  uploading: boolean;
  buttonTitle: string;
  isMobile: boolean;
  col: number;
  onUpload: () => void;
  onDropFile: (file: File) => void;
};

export const FileDataImageEmptyUpload = ({
  uploading,
  onUpload,
  onDropFile,
}: FileDataImageEmptyUploadProps) => {
  const [isDragging, setIsDragging] = useState(false);

  const onDragEnter = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      if (uploading) return;
      setIsDragging(true);
    },
    [uploading],
  );

  const onDragOver = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      if (uploading) return;
      setIsDragging(true);
    },
    [uploading],
  );

  const onDragLeave = useCallback((e: DragEvent<HTMLDivElement>) => {
    e.preventDefault();
    e.stopPropagation();
    const relatedTarget = e.relatedTarget;
    if (
      relatedTarget &&
      relatedTarget instanceof Node &&
      e.currentTarget.contains(relatedTarget)
    ) {
      return;
    }
    setIsDragging(false);
  }, []);

  const onDrop = useCallback(
    (e: DragEvent<HTMLDivElement>) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragging(false);
      if (uploading) return;

      const file = e.dataTransfer.files[0];
      if (file?.type.startsWith('image/')) {
        onDropFile(file);
      }
    },
    [uploading, onDropFile],
  );

  return (
    <div
      onClick={uploading ? undefined : onUpload}
      onDragEnter={onDragEnter}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      className={[
        'flex items-center justify-center border border-dotted transition-all duration-300',
        uploading ? 'cursor-default' : 'cursor-pointer',
        isDragging
          ? 'bg-gray-100 border-gray-400'
          : 'bg-gray-200 border-gray-300 hover:bg-gray-100',
      ].join(' ')}
      style={{
        width: '100%',
        height: 100,
        borderRadius: 8,
        overflow: 'hidden',
      }}
    >
      <div className='text-xs flex items-center gap-2 justify-center'>
        {uploading ? (
          <>
            <Loader2 className='size-4 animate-spin' />
            {Lang.key('uploading_file_wait')}
          </>
        ) : (
          <UploadIcon className='size-4' />
        )}
      </div>
    </div>
  );
};
