import { cn } from '@/lib/utils';
import { UploadCloud } from 'lucide-react';
import { useCallback, useState } from 'react';
import { Spinner } from './spinner';

type FileDropZoneProps = {
	accept?: string;
	isLoading?: boolean;
	label?: string;
	hint?: string;
	onFile: (file: File) => void;
	className?: string;
	id?: string;
};

const FileDropZone = ({
	accept,
	isLoading = false,
	label = 'Drop file here',
	hint = 'or click to browse',
	onFile,
	className,
	id = 'file-drop-zone-input',
}: FileDropZoneProps) => {
	const [isDragging, setIsDragging] = useState(false);

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

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

	return (
		<div
			onDragOver={(e) => {
				e.preventDefault();
				setIsDragging(true);
			}}
			onDragLeave={() => setIsDragging(false)}
			onDrop={onDrop}
			onClick={() => document.getElementById(id)?.click()}
			className={cn(
				'flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed px-6 py-8 transition-colors',
				isDragging ? 'border-teal-400 bg-teal-50' : 'border-gray-200 hover:border-gray-300 hover:bg-gray-50',
				className,
			)}
		>
			{isLoading ? (
				<Spinner className="size-5 text-gray-400" />
			) : (
				<>
					<UploadCloud className="size-7 text-gray-300" />
					<p className="text-[12px] font-medium text-gray-500">{label}</p>
					<p className="text-[11px] text-gray-400">{hint}</p>
				</>
			)}
			<input id={id} type="file" accept={accept} className="hidden" onChange={onFileChange} />
		</div>
	);
};

export { FileDropZone };
