import { useEffect, useRef, type RefObject } from 'react'
import { animateIdleSkeleton, cloneSkeleton, BASE_SKELETON } from './skeleton'
import { drawSkeleton } from './drawSkeleton'
import type { PoseResults, Skeleton } from './types'

export function useHomeAvatarCanvas(canvasRef: RefObject<HTMLCanvasElement | null>) {
  const skeletonRef = useRef<Skeleton>(cloneSkeleton(BASE_SKELETON))
  const hasLivePoseRef = useRef(false)
  const rafRef = useRef<number | null>(null)
  const timeRef = useRef(0)

  useEffect(() => {
    const onPoseResults = (results: PoseResults) => {
      const lm = results.poseLandmarks
      if (!lm || lm.length < 29) return
      hasLivePoseRef.current = true
      skeletonRef.current.nose = [lm[0].x, lm[0].y]
      skeletonRef.current.lSh = [lm[11].x, lm[11].y]
      skeletonRef.current.rSh = [lm[12].x, lm[12].y]
      skeletonRef.current.lEl = [lm[13].x, lm[13].y]
      skeletonRef.current.rEl = [lm[14].x, lm[14].y]
      skeletonRef.current.lWr = [lm[15].x, lm[15].y]
      skeletonRef.current.rWr = [lm[16].x, lm[16].y]
      skeletonRef.current.lHp = [lm[23].x, lm[23].y]
      skeletonRef.current.rHp = [lm[24].x, lm[24].y]
      skeletonRef.current.lKn = [lm[25].x, lm[25].y]
      skeletonRef.current.rKn = [lm[26].x, lm[26].y]
      skeletonRef.current.lAn = [lm[27].x, lm[27].y]
      skeletonRef.current.rAn = [lm[28].x, lm[28].y]
    }

    const host = window as Window & { onGrooveQuestPoseResults?: (results: PoseResults) => void }
    host.onGrooveQuestPoseResults = onPoseResults

    return () => {
      if (host.onGrooveQuestPoseResults === onPoseResults) {
        delete host.onGrooveQuestPoseResults
      }
    }
  }, [])

  useEffect(() => {
    const canvas = canvasRef.current
    if (!canvas) return
    const ctx = canvas.getContext('2d')
    if (!ctx) return

    const tick = () => {
      if (!hasLivePoseRef.current) {
        timeRef.current += 0.028
        animateIdleSkeleton(skeletonRef.current, timeRef.current)
      }
      drawSkeleton(ctx, skeletonRef.current, canvas.width, canvas.height)
      rafRef.current = window.requestAnimationFrame(tick)
    }

    rafRef.current = window.requestAnimationFrame(tick)
    return () => {
      if (rafRef.current != null) {
        window.cancelAnimationFrame(rafRef.current)
      }
    }
  }, [canvasRef])
}
