import { useState } from 'react';

import { clsx } from 'clsx';

import ImageIcon from '#/icons/central/Images1_round_outlined_radius1_stroke2.svg';

import * as styles from './EmbedThumb.css';

export type EmbedThumbProps = {
	/** Replaces the default full-bleed card geometry; sizes the frame the image fills. */
	frameClassName?: string;
	/** Thumbnail image URL; the placeholder shows when omitted or on load failure. */
	src?: string;
};

/**
 * media slot for a link or embed card. lazily loads the thumbnail and falls back to a placeholder icon if the
 * source is missing or fails to load.
 *
 * @param props configuration options for the embed thumbnail
 */
export function EmbedThumb({ frameClassName, src }: EmbedThumbProps) {
	// remount on a new `src` so the load status starts fresh — feed rows recycle this slot across posts.
	return <Thumb frameClassName={frameClassName} key={src} src={src} />;
}

function Thumb({ frameClassName, src }: EmbedThumbProps) {
	// kept hidden until it resolves so the browser's broken-image glyph never flashes on the way to the
	// fallback.
	const [status, setStatus] = useState<'error' | 'loaded' | 'loading'>(src ? 'loading' : 'error');

	// a cached image can finish loading before React wires up `onLoad`, leaving the status stuck on
	// 'loading'; settle it from the element's own state when the ref attaches.
	const measure = (node: HTMLImageElement | null) => {
		if (node?.complete) {
			setStatus(node.naturalWidth > 0 ? 'loaded' : 'error');
		}
	};

	return (
		<div className={clsx(styles.frame, frameClassName ?? styles.cardFrame)}>
			{status === 'error' ? (
				<span className={styles.fallback}>
					<ImageIcon className={styles.imageIcon} />
				</span>
			) : (
				<img
					alt=""
					className={clsx(styles.image, status === 'loading' && styles.loading)}
					loading="lazy"
					onError={() => setStatus('error')}
					onLoad={() => setStatus('loaded')}
					ref={measure}
					src={src}
				/>
			)}
		</div>
	);
}
