<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch } from 'vue'
import { generateSpriteSheet, getBotColors, FRAME_SIZE, ANIMATIONS, type SpriteCustomization } from '../game/sprites'

const props = defineProps<{
  seed: string
  archetype?: string
  tier?: number
  size?: number
  customization?: SpriteCustomization
  pose?: keyof typeof ANIMATIONS
}>()

const canvasRef = ref<HTMLCanvasElement>()
let img: HTMLImageElement | null = null
let frame = 0
let animHandle: ReturnType<typeof setTimeout> | null = null

function render() {
  if (!canvasRef.value || !img?.complete) return
  const ctx = canvasRef.value.getContext('2d')!
  const displaySize = props.size || 64
  canvasRef.value.width = displaySize
  canvasRef.value.height = displaySize
  ctx.clearRect(0, 0, displaySize, displaySize)
  ctx.imageSmoothingEnabled = false

  const anim = ANIMATIONS[props.pose || 'idle']
  const f = frame % anim.frames
  ctx.drawImage(
    img,
    f * FRAME_SIZE, anim.row * FRAME_SIZE, FRAME_SIZE, FRAME_SIZE,
    0, 0, displaySize, displaySize,
  )

  frame++
  animHandle = setTimeout(() => render(), 180)
}

function loadSprite() {
  const colors = getBotColors(props.seed)
  const dataUrl = generateSpriteSheet(props.seed, props.tier || 0, colors.primary, colors.secondary, props.archetype, props.customization)
  img = new Image()
  img.onload = () => render()
  img.src = dataUrl
}

onMounted(() => loadSprite())

watch(() => [props.seed, props.archetype, props.customization, props.pose], () => {
  if (animHandle) clearTimeout(animHandle)
  frame = 0
  loadSprite()
})

onUnmounted(() => {
  if (animHandle) clearTimeout(animHandle)
  animHandle = null
  if (img) { img.onload = null; img.src = ''; img = null }
})
</script>

<template>
  <canvas
    ref="canvasRef"
    :style="{ width: `${size || 64}px`, height: `${size || 64}px`, imageRendering: 'pixelated' }"
  />
</template>
