import config from '@/config'
import Tilemap = Phaser.Tilemaps.Tilemap
import TilemapLayer = Phaser.Tilemaps.TilemapLayer
import Tileset = Phaser.Tilemaps.Tileset
import Tile = Phaser.Tilemaps.Tile
import type { AssetDataT, Zone as ZoneT } from '@/types'
import { loadTexture } from '@/composables/gameComposable'

export function getTile(layer: TilemapLayer | Tilemap, x: number, y: number): Tile | undefined {
  const tile = layer.getTileAtWorldXY(x, y)
  if (!tile) return undefined
  return tile
}

export function tileToWorldXY(layer: TilemapLayer | Tilemap, pos_x: number, pos_y: number) {
  const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
  if (!worldPoint) return { positionX: 0, positionY: 0 }

  const positionX = worldPoint.x + config.tile_size.y
  const positionY = worldPoint.y

  return { positionX, positionY }
}

export function tileToWorldX(layer: TilemapLayer | Tilemap, pos_x: number, pos_y: number): number {
  const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
  if (!worldPoint) return 0

  return worldPoint.x + config.tile_size.x / 2
}

export function tileToWorldY(layer: TilemapLayer | Tilemap, pos_x: number, pos_y: number): number {
  const worldPoint = layer.tileToWorldXY(pos_x, pos_y)
  if (!worldPoint) return 0

  return worldPoint.y + config.tile_size.y * 1.5
}

/**
 * Can also be used to replace tiles
 * @param zone
 * @param layer
 * @param x
 * @param y
 * @param tileName
 */
export function placeTile(zone: Tilemap, layer: TilemapLayer, x: number, y: number, tileName: string) {
  let tileImg = zone.getTileset(tileName) as Tileset
  if (!tileImg) {
    tileImg = zone.getTileset('blank_tile') as Tileset
  }
  layer.putTileAt(tileImg.firstgid, x, y)
}

export function setLayerTiles(zone: Tilemap, layer: TilemapLayer, tiles: string[][]) {
  if (!tiles) return

  tiles.forEach((row: string[], y: number) => {
    row.forEach((tile: string, x: number) => {
      placeTile(zone, layer, x, y, tile)
    })
  })
}

export function createTileArray(width: number, height: number, tile: string = 'blank_tile') {
  return Array.from({ length: height }, () => Array.from({ length: width }, () => tile))
}

export const calculateIsometricDepth = (x: number, y: number, width: number = 0, height: number = 0, isCharacter: boolean = false) => {
  const baseDepth = x + y
  if (isCharacter) {
    return baseDepth // @TODO: Fix collision, this is a hack
  }
  return baseDepth + (width + height) / (2 * config.tile_size.x)
}

export function FlattenZoneArray(tiles: string[][]) {
  const normalArray = []

  for (const row of tiles) {
    normalArray.push(...row)
  }

  return normalArray
}

export async function loadZoneTilesIntoScene(zone: ZoneT, scene: Phaser.Scene) {
  // Fetch the list of tiles from the server
  const tileArray: AssetDataT[] = await fetch(config.server_endpoint + '/assets/list_tiles/' + zone.id).then((response) => response.json())

  // Load each tile into the scene
  for (const tile of tileArray) {
    await loadTexture(scene, tile)
  }
}
