import { randomString } from '@/lib/random'
import { cn } from '@/lib/utils'
import logger from '@/lib/logger'
import { useContentPolicyOptional } from '@/providers/ContentPolicyProvider'
import modalManager from '@/services/modal-manager.service'
import { TImetaInfo } from '@/types'
import { ReactNode, useEffect, useLayoutEffect, useMemo, useState } from 'react'
import { createPortal } from 'react-dom'
import { lightboxSlideFromImeta } from '@/lib/lightbox-slides'
import Lightbox from 'yet-another-react-lightbox'
import Captions from 'yet-another-react-lightbox/plugins/captions'
import Video from 'yet-another-react-lightbox/plugins/video'
import Zoom from 'yet-another-react-lightbox/plugins/zoom'
import 'yet-another-react-lightbox/plugins/captions.css'
import Image from '../Image'
import ImageWithLightbox from '../ImageWithLightbox'
const galleryImageWrapper = (className?: string) =>
cn('w-full max-w-full min-w-0', className)
export default function ImageGallery({
className,
images,
start = 0,
end = images.length,
mustLoad = false
}: {
className?: string
images: TImetaInfo[]
start?: number
end?: number
mustLoad?: boolean
}) {
const id = useMemo(() => `image-gallery-${randomString()}`, [])
const contentPolicy = useContentPolicyOptional()
const autoLoadMedia = contentPolicy?.autoLoadMedia ?? true
const [index, setIndex] = useState(-1)
const [lightboxPortalActive, setLightboxPortalActive] = useState(false)
useEffect(() => {
if (index >= 0) {
modalManager.register(id, () => {
setIndex(-1)
})
} else {
modalManager.unregister(id)
}
}, [id, index])
const handlePhotoClick = (event: React.MouseEvent, current: number) => {
event.stopPropagation()
event.preventDefault()
const newIndex = start + current
logger.debug('[ImageGallery] Click:', {
start,
current,
newIndex,
totalImages: images.length,
displayImages: displayImages.length
})
setLightboxPortalActive(true)
setIndex(newIndex)
}
const displayImages = images.slice(start, end)
/** Tap-to-load: no shared grid lightbox — each image uses {@link ImageWithLightbox}. */
const tapToLoadGallery = !mustLoad && !autoLoadMedia
useLayoutEffect(() => {
if (tapToLoadGallery) {
setIndex(-1)
setLightboxPortalActive(false)
}
}, [tapToLoadGallery])
if (displayImages.length === 1) {
return (