import type { Texture } from "engine/render/Texture"
import type { Textures } from "game/textures"
import barkUrl from "assets/bark.png"
import beeUrl from "assets/bee.png"
import birchUrl from "assets/birch.png"
import crateUrl from "assets/crate.png"
import floorUrl from "assets/floor.png"
import flowerUrl from "assets/flower.png"
import frogUrl from "assets/frog.png"
import grassUrl from "assets/grass.png"
import leafUrl from "assets/leaf.png"
import needleUrl from "assets/needle.png"
import npcUrl from "assets/npc.png"
import robinUrl from "assets/robin.png"
import rockUrl from "assets/rock.png"
import skyboxUrl from "assets/rockies.skybox.png"
import wallUrl from "assets/wall.png"

/** Load every game texture up front. Call once before starting the loop. */
export async function loadTextures(): Promise<Textures> {
  const [floor, grass, bark, birch, leaf, needle, rock, flower, wall, crate, npc, frog, bee, robin, skybox] = await Promise.all([
    loadTexture(floorUrl),
    loadTexture(grassUrl),
    loadTexture(barkUrl),
    loadTexture(birchUrl),
    loadTexture(leafUrl),
    loadTexture(needleUrl),
    loadTexture(rockUrl),
    loadTexture(flowerUrl),
    loadTexture(wallUrl),
    loadTexture(crateUrl),
    loadTexture(npcUrl),
    loadTexture(frogUrl),
    loadTexture(beeUrl),
    loadTexture(robinUrl),
    loadTexture(skyboxUrl),
  ])
  return { floor, grass, bark, birch, leaf, needle, rock, flower, wall, crate, npc, frog, bee, robin, skybox }
}

function loadTexture(url: string): Promise<Texture> {
  return new Promise((resolve, reject) => {
    const image = new Image()
    image.addEventListener("load", () => resolve(toTexture(image)))
    image.addEventListener("error", () => reject(new Error(`failed to load ${url}`)))
    image.src = url
  })
}

/** Draw a loaded image into a canvas and read its pixels back as a Texture.
 *  ImageData bytes are RGBA, identical to how Color packs a Uint32, so the
 *  buffer is reused directly with no per-pixel conversion. */
function toTexture(image: HTMLImageElement): Texture {
  const canvas = document.createElement("canvas")
  canvas.width = image.naturalWidth
  canvas.height = image.naturalHeight
  const ctx = canvas.getContext("2d")!
  ctx.drawImage(image, 0, 0)
  const pixels = ctx.getImageData(0, 0, canvas.width, canvas.height)
  return { width: pixels.width, height: pixels.height, data: new Uint32Array(pixels.data.buffer) }
}
