import React, { useEffect, useRef, useState } from 'react'
import { EmptyCard } from './AppCard'

interface GridWithFillProps<T> {
  items: T[]
  renderItem: (item: T, index: number) => React.ReactNode
  minCellWidth?: number
  keyPrefix: string
}

const GridWithFill = <T,>({ items, renderItem, minCellWidth = 110, keyPrefix }: GridWithFillProps<T>) => {
  const gridRef = useRef<HTMLDivElement | null>(null)
  const [columns, setColumns] = useState<number>(1)

  const rafId = useRef<number | null>(null)
  const lastWidth = useRef<number>(0)

  useEffect(() => {
    const calcColumns = (width: number) => {
      if (width === 0) return
      // 避免频繁setState引发布局抖动
      if (Math.abs(width - lastWidth.current) < 1) return
      lastWidth.current = width
      const cols = Math.max(1, Math.floor(width / minCellWidth))
      setColumns((prev) => (prev === cols ? prev : cols))
    }

    const scheduleCalc = (width: number) => {
      if (rafId.current) cancelAnimationFrame(rafId.current)
      rafId.current = requestAnimationFrame(() => calcColumns(width))
    }

    const observer = new ResizeObserver((entries) => {
      const entry = entries[0]
      const width = entry?.contentRect?.width || 0
      scheduleCalc(width)
    })

    if (gridRef.current) {
      // 初始化
      scheduleCalc(gridRef.current.clientWidth)
      observer.observe(gridRef.current)
    }

    return () => {
      if (rafId.current) cancelAnimationFrame(rafId.current)
      observer.disconnect()
    }
  }, [minCellWidth])

  const remainder = columns > 0 ? (columns - (items.length % columns)) % columns : 0

  return (
    <div
      ref={gridRef}
      className="apps-grid"
      style={{ gridTemplateColumns: `repeat(${columns}, minmax(100px, 1fr))` }}
    >
      {items.map((item, idx) => renderItem(item, idx))}
      {Array.from({ length: remainder }).map((_, i) => (
        <EmptyCard key={`${keyPrefix}-empty-${i}`} />
      ))}
    </div>
  )
}

export default GridWithFill
