import { useRef, useState } from "react";
import { apiUpload } from "../lib/api";

interface ImageUploadProps {
	value: string | null;
	imageUrl?: string | null;
	onChange: (filename: string | null) => void;
}

const MAX_SIZE_BYTES = 5 * 1024 * 1024; // 5MB
const ACCEPTED_TYPES = ["image/jpeg", "image/png", "image/webp"];

export function ImageUpload({
	value: _value,
	imageUrl,
	onChange,
}: ImageUploadProps) {
	const [uploading, setUploading] = useState(false);
	const [error, setError] = useState<string | null>(null);
	const [localPreview, setLocalPreview] = useState<string | null>(null);
	const inputRef = useRef<HTMLInputElement>(null);

	async function handleFileChange(e: React.ChangeEvent<HTMLInputElement>) {
		const file = e.target.files?.[0];
		if (!file) return;

		setError(null);

		if (!ACCEPTED_TYPES.includes(file.type)) {
			setError("Please select a JPG, PNG, or WebP image.");
			return;
		}

		if (file.size > MAX_SIZE_BYTES) {
			setError("Image must be under 5MB.");
			return;
		}

		// Create local preview for immediate display
		const previewUrl = URL.createObjectURL(file);
		setLocalPreview(previewUrl);

		setUploading(true);
		try {
			const result = await apiUpload<{ filename: string }>("/api/images", file);
			onChange(result.filename);
		} catch {
			setError("Upload failed. Please try again.");
			setLocalPreview(null);
		} finally {
			setUploading(false);
			// Reset input so the same file can be re-selected
			if (inputRef.current) inputRef.current.value = "";
		}
	}

	function handleRemove(e: React.MouseEvent) {
		e.stopPropagation();
		setLocalPreview(null);
		onChange(null);
	}

	// Determine the display URL: local preview takes priority (just-uploaded),
	// then presigned URL from API, then nothing
	const displayUrl = localPreview || imageUrl || null;

	return (
		<div>
			{/* Hero image area */}
			<div
				onClick={() => inputRef.current?.click()}
				className="relative w-full aspect-[4/3] rounded-xl overflow-hidden cursor-pointer group"
			>
				{displayUrl ? (
					<>
						<img
							src={displayUrl}
							alt="Item"
							className="w-full h-full object-cover"
						/>
						{/* Remove button */}
						<button
							type="button"
							onClick={handleRemove}
							className="absolute top-2 right-2 w-7 h-7 flex items-center justify-center bg-white/80 hover:bg-white rounded-full text-gray-600 hover:text-gray-900 transition-colors shadow-sm"
						>
							<svg
								className="w-4 h-4"
								fill="none"
								stroke="currentColor"
								viewBox="0 0 24 24"
							>
								<path
									strokeLinecap="round"
									strokeLinejoin="round"
									strokeWidth={2}
									d="M6 18L18 6M6 6l12 12"
								/>
							</svg>
						</button>
					</>
				) : (
					<div className="w-full h-full bg-gray-100 flex flex-col items-center justify-center">
						{/* ImagePlus icon */}
						<svg
							className="w-10 h-10 text-gray-300 group-hover:text-gray-400 transition-colors"
							fill="none"
							stroke="currentColor"
							viewBox="0 0 24 24"
							strokeWidth={1.5}
						>
							<rect x="3" y="3" width="18" height="18" rx="2" ry="2" />
							<circle cx="9" cy="9" r="2" />
							<path d="m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" />
							<path d="M14 4v3" />
							<path d="M12.5 5.5h3" />
						</svg>
						<span className="mt-2 text-sm text-gray-400 group-hover:text-gray-500 transition-colors">
							Click to add photo
						</span>
					</div>
				)}

				{/* Upload spinner overlay */}
				{uploading && (
					<div className="absolute inset-0 bg-white/60 flex items-center justify-center">
						<svg
							className="w-8 h-8 text-gray-500 animate-spin"
							fill="none"
							viewBox="0 0 24 24"
						>
							<circle
								className="opacity-25"
								cx="12"
								cy="12"
								r="10"
								stroke="currentColor"
								strokeWidth="4"
							/>
							<path
								className="opacity-75"
								fill="currentColor"
								d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
							/>
						</svg>
					</div>
				)}
			</div>

			<input
				ref={inputRef}
				type="file"
				accept="image/jpeg,image/png,image/webp"
				onChange={handleFileChange}
				className="hidden"
			/>
			{error && <p className="mt-1 text-xs text-red-500">{error}</p>}
		</div>
	);
}
