<template>
  <ChatBubble :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
  <HealthBar :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
  <CharacterHair :mapCharacter="props.mapCharacter" :currentX="currentPositionX" :currentY="currentPositionY" />
  <Sprite ref="charSprite" :depth="isometricDepth" :x="currentPositionX" :y="currentPositionY" :origin-y="1" :flipX="isFlippedX" />
</template>

<script lang="ts" setup>
import { type MapCharacter } from '@/application/types'
import CharacterHair from '@/components/game/character/partials/CharacterHair.vue'
import ChatBubble from '@/components/game/character/partials/ChatBubble.vue'
import HealthBar from '@/components/game/character/partials/HealthBar.vue'
import { useCharacterSprite } from '@/composables/useCharacterSpriteComposable'
import { useGameStore } from '@/stores/gameStore'
import { useMapStore } from '@/stores/mapStore'
import { Sprite, useScene } from 'phavuer'
import { onMounted, onUnmounted, watch } from 'vue'
import { Direction } from '@/application/enums'

const props = defineProps<{
  tilemap: Phaser.Tilemaps.Tilemap
  mapCharacter: MapCharacter
}>()

const gameStore = useGameStore()
const mapStore = useMapStore()
const scene = useScene()

const {
  charSprite,
  currentPositionX,
  currentPositionY,
  isometricDepth,
  isFlippedX,
  updatePosition,
  calcDirection,
  updateSprite,
  initializeSprite,
  cleanup
} = useCharacterSprite(scene, props.tilemap, props.mapCharacter)

const handlePositionUpdate = (newValues: any, oldValues: any) => {
  if (!newValues) return

  if (!oldValues || newValues.positionX !== oldValues.positionX || newValues.positionY !== oldValues.positionY) {
    const direction = !oldValues ? Direction.POSITIVE : calcDirection(oldValues.positionX, oldValues.positionY, newValues.positionX, newValues.positionY)
    updatePosition(newValues.positionX, newValues.positionY, direction)
  }

  if (newValues.isMoving !== oldValues?.isMoving || newValues.rotation !== oldValues?.rotation) {
    updateSprite()
  }
}

watch(
  () => ({
    positionX: props.mapCharacter.character.positionX,
    positionY: props.mapCharacter.character.positionY,
    isMoving: props.mapCharacter.isMoving,
    rotation: props.mapCharacter.character.rotation,
    isAttacking: props.mapCharacter.isAttacking
  }),
  handlePositionUpdate
)

onMounted(async () => {
  await initializeSprite()

  if (props.mapCharacter.character.id === gameStore.character!.id) {
    mapStore.setCharacterLoaded(true)
    scene.cameras.main.startFollow(charSprite.value as Phaser.GameObjects.Sprite)
  }
})

onUnmounted(() => {
  cleanup()
})
</script>
