import type { JointKey, JointPoint, Skeleton } from './types'

export function drawSkeleton(
  ctx: CanvasRenderingContext2D,
  skeleton: Skeleton,
  width: number,
  height: number,
) {
  const p = (key: JointKey): JointPoint => [skeleton[key][0] * width, skeleton[key][1] * height]
  const [lShX, lShY] = p('lSh')
  const [rShX, rShY] = p('rSh')
  const [lHpX, lHpY] = p('lHp')
  const [rHpX, rHpY] = p('rHp')
  const midSh: JointPoint = [(lShX + rShX) / 2, (lShY + rShY) / 2]
  const midHp: JointPoint = [(lHpX + rHpX) / 2, (lHpY + rHpY) / 2]
  const [noseX, noseY] = p('nose')

  const line = (a: JointPoint, b: JointPoint, color: string, widthPx: number, alpha = 1) => {
    ctx.save()
    ctx.strokeStyle = color
    ctx.globalAlpha = alpha
    ctx.lineWidth = widthPx
    ctx.lineCap = 'round'
    ctx.beginPath()
    ctx.moveTo(a[0], a[1])
    ctx.lineTo(b[0], b[1])
    ctx.stroke()
    ctx.restore()
  }

  const dot = (point: JointPoint, radius: number, fill: string, alpha = 1) => {
    ctx.save()
    ctx.globalAlpha = alpha
    ctx.fillStyle = fill
    ctx.beginPath()
    ctx.arc(point[0], point[1], radius, 0, Math.PI * 2)
    ctx.fill()
    ctx.restore()
  }

  ctx.clearRect(0, 0, width, height)

  line(p('lSh'), p('lEl'), 'rgba(255,78,203,0.12)', 24)
  line(p('lEl'), p('lWr'), 'rgba(255,78,203,0.12)', 24)
  line(p('rSh'), p('rEl'), 'rgba(0,200,255,0.12)', 24)
  line(p('rEl'), p('rWr'), 'rgba(0,200,255,0.12)', 24)
  line(p('lSh'), p('lEl'), 'rgba(255,78,203,0.08)', 36)
  line(p('lEl'), p('lWr'), 'rgba(255,78,203,0.08)', 36)
  line(p('rSh'), p('rEl'), 'rgba(0,200,255,0.08)', 36)
  line(p('rEl'), p('rWr'), 'rgba(0,200,255,0.08)', 36)

  line(p('lSh'), p('lEl'), '#ff4ecb', 4.5)
  line(p('lEl'), p('lWr'), '#ff4ecb', 3.6)
  line(p('rSh'), p('rEl'), '#00c8ff', 4.5)
  line(p('rEl'), p('rWr'), '#00c8ff', 3.6)

  line(midSh, midHp, '#ffffff', 3.6, 0.65)
  line(p('lSh'), p('rSh'), '#ffffff', 4.5, 0.88)
  line(p('lHp'), p('rHp'), '#ffffff', 3.6, 0.74)
  line(p('lSh'), p('lHp'), '#ffffff', 2.7, 0.18)
  line(p('rSh'), p('rHp'), '#ffffff', 2.7, 0.18)

  line(p('lHp'), p('lKn'), 'rgba(255,255,255,0.22)', 4)
  line(p('lKn'), p('lAn'), 'rgba(255,255,255,0.22)', 3.6)
  line(p('rHp'), p('rKn'), 'rgba(255,255,255,0.22)', 4)
  line(p('rKn'), p('rAn'), 'rgba(255,255,255,0.22)', 3.6)

  ctx.save()
  ctx.strokeStyle = '#ffffff'
  ctx.lineWidth = 3.6
  ctx.fillStyle = 'rgba(255,255,255,0.07)'
  ctx.beginPath()
  ctx.arc(noseX, noseY + 18, 23, 0, Math.PI * 2)
  ctx.fill()
  ctx.stroke()
  ctx.beginPath()
  ctx.arc(noseX, noseY + 18, 20, 0, Math.PI * 2)
  ctx.stroke()
  ctx.restore()

  dot(p('lSh'), 7.2, '#ffffff')
  dot(p('rSh'), 7.2, '#ffffff')
  dot(p('lHp'), 7.2, '#ffffff')
  dot(p('rHp'), 7.2, '#ffffff')
  dot(p('lKn'), 5.4, '#ffffff', 0.3)
  dot(p('rKn'), 5.4, '#ffffff', 0.3)
  dot(p('lAn'), 5.4, '#ffffff', 0.3)
  dot(p('rAn'), 5.4, '#ffffff', 0.3)
  dot(p('lEl'), 9, '#ff4ecb')
  dot(p('rEl'), 9, '#00c8ff')
  dot(p('lWr'), 10.8, '#ff4ecb')
  dot(p('rWr'), 10.8, '#00c8ff')
  dot(p('lWr'), 18, 'rgba(255,78,203,0.2)')
  dot(p('rWr'), 18, 'rgba(0,200,255,0.2)')
}
