import { common } from "../styledSystem/common.js";
import { descriptors } from "../customizables/elementDescriptors.js";
import { Box, Flex, Image, Spinner, Text } from "../customizables/index.js";
import React from "react";
import { jsx, jsxs } from "@emotion/react/jsx-runtime";

//#region src/elements/Avatar.tsx
const SPINNER_DELAY_MS = 150;
const SPINNER_MIN_DURATION_MS = 400;
const Avatar = (props) => {
	const { size = () => 26, title, initials, imageUrl, rounded = true, imageFetchSize = 80, sx, boxElementDescriptor, imageElementDescriptor, showLoadingSpinner = false } = props;
	const [error, setError] = React.useState(false);
	const [loaded, setLoaded] = React.useState(false);
	const [spinnerVisible, setSpinnerVisible] = React.useState(false);
	const spinnerShownAtRef = React.useRef(null);
	const loadTimerRef = React.useRef(null);
	React.useEffect(() => {
		setLoaded(false);
		setError(false);
		setSpinnerVisible(false);
		spinnerShownAtRef.current = null;
		return () => {
			if (loadTimerRef.current) {
				clearTimeout(loadTimerRef.current);
				loadTimerRef.current = null;
			}
		};
	}, [imageUrl]);
	React.useEffect(() => {
		if (!showLoadingSpinner || !imageUrl || loaded || error) return;
		const timer = setTimeout(() => {
			setSpinnerVisible(true);
			spinnerShownAtRef.current = Date.now();
		}, SPINNER_DELAY_MS);
		return () => clearTimeout(timer);
	}, [
		showLoadingSpinner,
		imageUrl,
		loaded,
		error
	]);
	/**
	* Prevents the loading spinner from appearing and disappearing too quickly
	*/
	const handleImageLoad = React.useCallback(() => {
		if (spinnerShownAtRef.current) {
			const remaining = SPINNER_MIN_DURATION_MS - (Date.now() - spinnerShownAtRef.current);
			if (remaining > 0) {
				loadTimerRef.current = setTimeout(() => {
					loadTimerRef.current = null;
					setLoaded(true);
				}, remaining);
				return;
			}
		}
		setLoaded(true);
	}, []);
	const isLoading = showLoadingSpinner && spinnerVisible && imageUrl && !loaded && !error;
	const ImgOrFallback = initials && (!imageUrl || error) ? /* @__PURE__ */ jsx(InitialsAvatarFallback, { initials }) : /* @__PURE__ */ jsx(Image, {
		elementDescriptor: [imageElementDescriptor, descriptors.avatarImage],
		title,
		alt: `${title}'s logo`,
		src: imageUrl || "",
		sx: {
			objectFit: "cover",
			width: "100%",
			height: "100%",
			opacity: showLoadingSpinner ? loaded ? 1 : 0 : 1,
			transition: "opacity 0.2s ease-in-out"
		},
		onError: () => setError(true),
		onLoad: handleImageLoad,
		size: imageFetchSize
	});
	return /* @__PURE__ */ jsxs(Flex, {
		as: "span",
		elementDescriptor: [boxElementDescriptor, descriptors.avatarBox],
		sx: [(t) => ({
			flexShrink: 0,
			borderRadius: rounded ? t.radii.$circle : t.radii.$avatar,
			overflow: "hidden",
			width: size(t),
			height: size(t),
			backgroundColor: t.colors.$avatarBackground,
			backgroundClip: "padding-box",
			position: "relative"
		}), sx],
		children: [
			ImgOrFallback,
			isLoading && /* @__PURE__ */ jsx(Flex, {
				as: "span",
				sx: (t) => ({
					position: "absolute",
					inset: 0,
					alignItems: "center",
					justifyContent: "center",
					backgroundColor: t.colors.$avatarBackground
				}),
				children: /* @__PURE__ */ jsx(Spinner, {
					size: "sm",
					colorScheme: "neutral"
				})
			}),
			/* @__PURE__ */ jsx(Box, {
				as: "span",
				sx: (t) => ({
					overflow: "hidden",
					background: t.colors.$colorShimmer,
					position: "absolute",
					width: "25%",
					height: "100%",
					transition: `all ${t.transitionDuration.$slow} ${t.transitionTiming.$easeOut}`,
					transform: "var(--cl-shimmer-hover-transform, skewX(-45deg) translateX(-300%))",
					":after": {
						display: "block",
						boxSizing: "border-box",
						content: "''",
						position: "absolute",
						width: "400%",
						height: "100%",
						transform: "var(--cl-shimmer-hover-after-transform, skewX(45deg) translateX(75%))",
						transition: `all ${t.transitionDuration.$slow} ${t.transitionTiming.$easeOut}`,
						borderWidth: t.borderWidths.$heavy,
						borderStyle: t.borderStyles.$solid,
						borderColor: t.colors.$colorShimmer,
						borderRadius: rounded ? t.radii.$circle : t.radii.$avatar
					}
				})
			})
		]
	});
};
const InitialsAvatarFallback = (props) => {
	const initials = props.initials;
	return /* @__PURE__ */ jsx(Text, {
		as: "span",
		sx: (t) => ({
			...common.centeredFlex("inline-flex"),
			width: "100%",
			color: t.colors.$colorForeground
		}),
		children: initials
	});
};

//#endregion
export { Avatar };
//# sourceMappingURL=Avatar.js.map