import { useEffect, useRef, useState } from 'react'
import { imgUrl } from '../api'

// True justified layout: pack photos greedily into rows at their real aspect
// ratios, then scale each row's height so it fills the container width
// exactly. No cropping, no stretch, and the last row simply renders at the
// target height instead of being padded by a spacer.
function layoutRows(photos, containerWidth, targetHeight, gap) {
  const rows = []
  let row = []
  let arSum = 0
  let index = 0
  for (const photo of photos) {
    const ar = photo.width && photo.height ? photo.width / photo.height : 1.5
    row.push({ photo, ar, index: index++ })
    arSum += ar
    const gaps = (row.length - 1) * gap
    if (arSum * targetHeight + gaps >= containerWidth) {
      rows.push({ items: row, height: (containerWidth - gaps) / arSum })
      row = []
      arSum = 0
    }
  }
  if (row.length > 0) {
    const gaps = (row.length - 1) * gap
    rows.push({
      items: row,
      height: Math.min(targetHeight, (containerWidth - gaps) / arSum),
    })
  }
  return rows
}

export default function Gallery({ photos, onOpen, overlay, selected, onToggleSelect }) {
  const containerRef = useRef(null)
  const [width, setWidth] = useState(0)

  useEffect(() => {
    const observer = new ResizeObserver((entries) => setWidth(entries[0].contentRect.width))
    observer.observe(containerRef.current)
    return () => observer.disconnect()
  }, [])

  // The container renders even with zero photos — unmounting it would detach
  // the observer and leave a later non-empty render stuck at width 0.
  const gap = 6
  const targetHeight = width < 700 ? 170 : 240
  const rows = width > 0 ? layoutRows(photos, width, targetHeight, gap) : []
  const selecting = selected && selected.size > 0

  return (
    <div ref={containerRef} className={`gallery${selecting ? ' selecting' : ''}`}>
      {rows.map((row) => (
        <div key={row.items[0].photo.id} className="g-row" style={{ height: row.height }}>
          {row.items.map(({ photo: p, ar, index }) => {
            const isSelected = selected ? selected.has(p.id) : false
            return (
              <div
                key={p.id}
                className={`g-item${isSelected ? ' selected' : ''}`}
                style={{ width: ar * row.height }}
                onClick={() => onOpen && onOpen(index)}
              >
                <img src={imgUrl(p, 'thumb')} loading="lazy" alt={p.filename} />
                {onToggleSelect && (
                  <button
                    className="g-check"
                    title={isSelected ? 'Deselect' : 'Select'}
                    onClick={(e) => {
                      e.stopPropagation()
                      onToggleSelect(p.id, e.shiftKey)
                    }}
                  >
                    ✓
                  </button>
                )}
                {overlay && overlay(p)}
              </div>
            )
          })}
        </div>
      ))}
    </div>
  )
}
