<template>
  <TilemapLayer v-if="zoneStore.isLoaded" :tilemap="tileMap" :tileset="zoneStore.getTiles" ref="tilemapLayer" :layerIndex="0" :cull-padding-x="10" :cull-padding-y="10" />
  <Controls :layer="layer" />
  <Player :layer="layer" />
  <Container v-if="zoneStore.isLoaded && zoneStore.getPlayers.length > 0">
    <Player :layer="layer" v-for="player in zoneStore.getPlayers" :key="player.id" :player="player" />
  </Container>
</template>

<script setup lang="ts">
import { Container, refObj, TilemapLayer, useScene } from 'phavuer'
import Player from '@/components/sprites/player/Player.vue'
import config from '@/config'
import { onBeforeMount, onMounted, reactive, ref, type Ref, toRaw, watch } from 'vue'
import Tileset = Phaser.Tilemaps.Tileset
import Controls from '@/components/Controls.vue'
import { useSocketStore } from '@/stores/socket'
import { useZoneStore } from '@/stores/zone'

// Phavuer logic
let scene = useScene()
let tilemapLayer = ref();
let zoneData = new Phaser.Tilemaps.MapData({
  width: 10, // @TODO : get this from the server
  height: 10, // @TODO : get this from the server
  tileWidth: config.tile_size.x,
  tileHeight: config.tile_size.y,
  orientation: Phaser.Tilemaps.Orientation.ISOMETRIC,
  format: Phaser.Tilemaps.Formats.ARRAY_2D,
});
let tileMap = new Phaser.Tilemaps.Tilemap(scene, zoneData);
let tileset: any = tileMap.addTilesetImage('default', 'tiles');
let layer: (typeof TilemapLayer|null) = tileMap.createBlankLayer('layer', tileset, 0, config.tile_size.y);

// center camera
const centerY = (tileMap.height * tileMap.tileHeight) / 2
const centerX = (tileMap.width * tileMap.tileWidth) / 2
scene.cameras.main.centerOn(centerX, centerY)

// Multiplayer / server logics
const zoneStore = useZoneStore();
const socket = useSocketStore();

// Watch for changes in the zoneStore and update the layer
watch (() => zoneStore.tiles, () => { // @TODO : change to tiles for when loading other maps
  zoneStore.getTiles.forEach((row, y) => row.forEach((tile, x) => layer.putTileAt(tile, x, y)));
}, { deep: true })


// Load the zone from the server
onBeforeMount(() => {
  socket.connection?.emit('character:connect');
  socket.connection?.emit('character:zone:load');
})

// Listen for the zone event from the server and load the zone
socket.connection?.on('character:zone:load', (data) => {
  console.log('character:zone:load', data);
  zoneStore.loadTiles(data.zone.tiles)
  /**
   * @TODO
   * bug , when 2nd player joins, the first player is not added to the zone
   */

  // console.log(data.players);
  // console.log(data.players[1]); // key is user id
  //
  // // remove self from the players list
  // delete data.players[socket.connection?.id];
  //
  // zoneStore.addPlayers(data.players);
})

// Listen for player join events
socket.connection?.on('player_join', (data) => {
  console.log('player_join', data)
  if (data.id === socket.connection?.id) {
    console.log('self');
    return;
  }
  zoneStore.addPlayer(data);
})

socket.connection?.on('ping', (data) => {
  console.log('ping', data)
})

/**
 * 1 tile is 64x32
 * the zone is 10x10
 * so the zone is 640x320
 */
/**
 * Resources
 * https://clintbellanger.net/articles/isometric_math/
 * https://gist.github.com/veleek/3be73dc61d5f5a80abc0f72c3ffe390e
 * https://gamedev.stackexchange.com/questions/116485/how-to-center-a-tilemap-in-phaser
 * https://github.com/Nulligma/phaser-isometric-test/blob/master/src/main.ts
 * https://github.com/neki-dev/isometric-snippets
 * https://github.com/itsezc/CycloneIO/blob/next/packages/client/games/HabboEngine.ts
 * https://github.com/daan93/phaser-isometric-demo/tree/main
 */
</script>