type Crop = {
  x: number
  y: number
  width: number
  height: number
}

type SpriteProps = {
  src: string
  frames: number
  frameDuration: number
  sheetWidth: number
  sheetHeight: number
  crop?: Crop
  scale?: number
  class?: string
  style?: string
  playing?: boolean
}

// Include this once in your <head>
export const SpriteStyles = () => (
  <style>
    {`@keyframes sprite{from{background-position:var(--x)var(--y)}to{background-position:var(--ex)var(--y)}}`}
  </style>
)

export const Sprite = (props: SpriteProps) => {
  const {
    src,
    frames,
    frameDuration,
    sheetWidth,
    sheetHeight,
    crop,
    scale = 1,
    class: className,
    style = "",
    playing = true,
  } = props

  const frameWidth = Math.floor(sheetWidth / frames)
  const frameHeight = sheetHeight

  const displayWidth = (crop ? crop.width : frameWidth) * scale
  const displayHeight = (crop ? crop.height : frameHeight) * scale
  const offsetX = crop ? crop.x : 0
  const offsetY = crop ? crop.y : 0

  const scaledSheetWidth = sheetWidth * scale
  const scaledSheetHeight = sheetHeight * scale
  const duration = frames * frameDuration

  const fromX = -offsetX * scale
  const toX = (-sheetWidth - offsetX) * scale
  const y = -offsetY * scale

  const divStyle = [
    `--x:${fromX}px`,
    `--y:${y}px`,
    `--ex:${toX}px`,
    `width:${displayWidth}px`,
    `height:${displayHeight}px`,
    `background-image:url('${src}')`,
    `background-size:${scaledSheetWidth}px ${scaledSheetHeight}px`,
    `animation:sprite ${duration}ms steps(${frames}) infinite`,
    playing ? "" : "animation-play-state:paused",
    style,
  ]
    .filter(Boolean)
    .join(";")

  return <div class={className} style={divStyle} />
}
