import { useEffect, useRef, useState } from "react";
import { useAuth } from "../hooks/useAuth";
import { usePublicProfile, useUpdateProfile } from "../hooks/useProfile";
import { apiUpload } from "../lib/api";

export function ProfileSection() {
	const { data: auth } = useAuth();
	const userId = auth?.user?.id ?? null;
	const { data: profile } = usePublicProfile(userId);
	const updateProfile = useUpdateProfile();

	const [displayName, setDisplayName] = useState("");
	const [bio, setBio] = useState("");
	const [avatarFilename, setAvatarFilename] = useState<string | null>(null);
	const [avatarDisplayUrl, setAvatarDisplayUrl] = useState<string | null>(null);
	const [dirty, setDirty] = useState(false);
	const [message, setMessage] = useState<{
		type: "success" | "error";
		text: string;
	} | null>(null);
	const [uploading, setUploading] = useState(false);
	const fileInputRef = useRef<HTMLInputElement>(null);

	useEffect(() => {
		if (profile && !dirty) {
			setDisplayName(profile.displayName ?? "");
			setBio(profile.bio ?? "");
			setAvatarFilename(profile.avatarUrl ?? null);
			setAvatarDisplayUrl(profile.avatarImageUrl ?? null);
		}
	}, [profile, dirty]);

	async function handleSave(e: React.FormEvent) {
		e.preventDefault();
		setMessage(null);
		try {
			await updateProfile.mutateAsync({
				displayName: displayName.trim() || undefined,
				avatarUrl: avatarFilename,
				bio: bio.trim() || undefined,
			});
			setDirty(false);
			setMessage({ type: "success", text: "Profile updated" });
		} catch (err) {
			setMessage({ type: "error", text: (err as Error).message });
		}
	}

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

		const maxSize = 5 * 1024 * 1024;
		const accepted = ["image/jpeg", "image/png", "image/webp"];

		if (!accepted.includes(file.type)) {
			setMessage({
				type: "error",
				text: "Please select a JPG, PNG, or WebP image.",
			});
			return;
		}
		if (file.size > maxSize) {
			setMessage({ type: "error", text: "Image must be under 5MB." });
			return;
		}

		const localPreview = URL.createObjectURL(file);
		setAvatarDisplayUrl(localPreview);
		setUploading(true);
		setMessage(null);
		try {
			const result = await apiUpload<{ filename: string }>("/api/images", file);
			setAvatarFilename(result.filename);
			setDirty(true);
		} catch {
			setAvatarDisplayUrl(null);
			setMessage({ type: "error", text: "Avatar upload failed." });
		} finally {
			setUploading(false);
			if (fileInputRef.current) fileInputRef.current.value = "";
		}
	}

	return (
		<form onSubmit={handleSave} className="space-y-4">
			<div>
				<h3 className="text-sm font-medium text-gray-900">Profile</h3>
				<p className="text-xs text-gray-500 mt-0.5">
					Your public profile information
				</p>
			</div>

			{/* Avatar */}
			<div className="flex items-center gap-4">
				<div
					onClick={() => fileInputRef.current?.click()}
					className="relative w-16 h-16 rounded-full overflow-hidden cursor-pointer group shrink-0"
				>
					{avatarDisplayUrl ? (
						<img
							src={avatarDisplayUrl}
							alt="Avatar"
							className="w-full h-full object-cover"
						/>
					) : (
						<div className="w-full h-full bg-gray-100 flex items-center justify-center">
							<svg
								className="w-8 h-8 text-gray-300 group-hover:text-gray-400 transition-colors"
								fill="none"
								stroke="currentColor"
								viewBox="0 0 24 24"
								strokeWidth={1.5}
							>
								<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
								<circle cx="12" cy="7" r="4" />
							</svg>
						</div>
					)}
					{uploading && (
						<div className="absolute inset-0 bg-white/60 flex items-center justify-center">
							<svg
								className="w-5 h-5 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>
				<div>
					<button
						type="button"
						onClick={() => fileInputRef.current?.click()}
						disabled={uploading}
						className="text-sm text-gray-600 hover:text-gray-800 transition-colors"
					>
						{uploading ? "Uploading..." : "Change avatar"}
					</button>
					{avatarFilename && (
						<button
							type="button"
							onClick={() => {
								setAvatarFilename(null);
								setAvatarDisplayUrl(null);
								setDirty(true);
							}}
							className="block text-xs text-red-500 hover:text-red-700 mt-0.5"
						>
							Remove
						</button>
					)}
				</div>
				<input
					ref={fileInputRef}
					type="file"
					accept="image/jpeg,image/png,image/webp"
					onChange={handleAvatarUpload}
					className="hidden"
				/>
			</div>

			{/* Display Name */}
			<div>
				<label
					htmlFor="displayName"
					className="block text-sm font-medium text-gray-700 mb-1"
				>
					Display Name
				</label>
				<input
					id="displayName"
					type="text"
					value={displayName}
					onChange={(e) => {
						setDisplayName(e.target.value);
						setDirty(true);
					}}
					maxLength={100}
					placeholder="Your display name"
					className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-200"
				/>
			</div>

			{/* Bio */}
			<div>
				<label
					htmlFor="bio"
					className="block text-sm font-medium text-gray-700 mb-1"
				>
					Bio
				</label>
				<textarea
					id="bio"
					value={bio}
					onChange={(e) => {
						setBio(e.target.value);
						setDirty(true);
					}}
					maxLength={500}
					rows={3}
					placeholder="Tell others about yourself and your gear interests"
					className="w-full px-3 py-2 border border-gray-200 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-gray-200 resize-none"
				/>
				<p className="text-xs text-gray-400 mt-1 text-right">
					{bio.length}/500
				</p>
			</div>

			{message && (
				<p
					className={`text-sm ${message.type === "success" ? "text-green-600" : "text-red-600"}`}
				>
					{message.text}
				</p>
			)}

			<button
				type="submit"
				disabled={updateProfile.isPending}
				className="px-4 py-2 text-sm font-medium text-white bg-gray-700 hover:bg-gray-800 disabled:opacity-50 rounded-lg transition-colors"
			>
				{updateProfile.isPending ? "Saving..." : "Save Profile"}
			</button>
		</form>
	);
}
