import { useCallback, useRef, useState } from 'react';

const ACCEPTED_TYPES = '.png,.jpg,.jpeg,.bmp,.tiff,.webp,.svg';

interface FileUploadProps {
  onFileSelect: (file: File, isSvg: boolean) => void;
  selectedFile: File | null;
}

function formatFileSize(bytes: number): string {
  if (bytes < 1024) return `${bytes} B`;
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

function isSvgFile(file: File): boolean {
  return (
    file.type === 'image/svg+xml' ||
    file.name.toLowerCase().endsWith('.svg')
  );
}

export default function FileUpload({ onFileSelect, selectedFile }: FileUploadProps) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [isDragOver, setIsDragOver] = useState(false);
  const [thumbnailUrl, setThumbnailUrl] = useState<string | null>(null);

  const handleFile = useCallback(
    (file: File) => {
      // Revoke previous thumbnail URL to avoid memory leaks
      if (thumbnailUrl) {
        URL.revokeObjectURL(thumbnailUrl);
      }
      const url = URL.createObjectURL(file);
      setThumbnailUrl(url);
      onFileSelect(file, isSvgFile(file));
    },
    [onFileSelect, thumbnailUrl],
  );

  const onDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(true);
  }, []);

  const onDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setIsDragOver(false);
  }, []);

  const onDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      e.stopPropagation();
      setIsDragOver(false);
      const file = e.dataTransfer.files[0];
      if (file) handleFile(file);
    },
    [handleFile],
  );

  const onInputChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0];
      if (file) handleFile(file);
    },
    [handleFile],
  );

  return (
    <div
      className={`file-upload-zone ${isDragOver ? 'file-upload-zone--drag-over' : ''}`}
      onDragOver={onDragOver}
      onDragLeave={onDragLeave}
      onDrop={onDrop}
      onClick={() => inputRef.current?.click()}
      role="button"
      tabIndex={0}
      onKeyDown={(e) => {
        if (e.key === 'Enter' || e.key === ' ') inputRef.current?.click();
      }}
      aria-label="Upload image file"
    >
      <input
        ref={inputRef}
        type="file"
        accept={ACCEPTED_TYPES}
        onChange={onInputChange}
        style={{ display: 'none' }}
        data-testid="file-input"
      />
      {selectedFile ? (
        <div className="file-upload-preview">
          {thumbnailUrl && (
            <img
              src={thumbnailUrl}
              alt="Uploaded preview"
              className="file-upload-thumb"
            />
          )}
          <div className="file-upload-info">
            <span className="file-upload-name">{selectedFile.name}</span>
            <span className="file-upload-size">
              {formatFileSize(selectedFile.size)}
            </span>
            {isSvgFile(selectedFile) && (
              <span className="file-upload-badge">SVG — simplify mode</span>
            )}
          </div>
        </div>
      ) : (
        <div className="file-upload-prompt">
          <span className="file-upload-icon">📁</span>
          <p>
            <strong>Drop an image here</strong> or click to browse
          </p>
          <small>PNG, JPG, BMP, TIFF, WebP, or SVG</small>
        </div>
      )}
    </div>
  );
}
