import { Vec3 } from "../../../engine/math/Vec3"
import type { Mesh } from "../../../engine/scene/Mesh"
import type { Tree, TreeSpecies } from "../Tree"
import { blob, lerp, limb, TAU, rng } from "./treekit"

// Silver birch: tall, slender, near-straight trunk under an airy, high, slightly
// drooping canopy -- a lean silhouette between the broad oak and conical spruce.
// Trunk = white birch bark, foliage = oak leaf (the white trunk carries the read).

export const birch: TreeSpecies = { kind: "birch", trunk: "birch", foliage: "leaf", build }

function build(tree: Tree, trunk: Mesh, leaves: Mesh, lod: "full" | "impostor"): void {
  const base = tree.position
  const g = tree.growth
  const rand = rng(tree.seed)
  const h = lerp(1, 8.5, g)
  const rTrunk = lerp(0.03, 0.16, g)
  const canopyY = base.y + h * 0.75
  const blobR = h * 0.22
  if (lod === "impostor") {
    limb(trunk, base, { x: base.x, y: base.y + h * 0.9, z: base.z }, rTrunk, rTrunk * 0.5, 3)
    blob(leaves, { x: base.x, y: canopyY, z: base.z }, blobR * 1.1, rand, 4, 2)
    return
  }
  limb(trunk, base, { x: base.x, y: base.y + h * 0.88, z: base.z }, rTrunk, rTrunk * 0.35, 5)

  const spread = h * 0.22
  // Sparse small blobs clustered high, biased downward so the crown droops.
  const blobs = 2 + Math.round(g * 2)
  for (let i = 0; i < blobs; i++) {
    const angle = rand() * TAU
    const rad = i === 0 ? 0 : spread * (0.5 + rand() * 0.5)
    const center = {
      x: base.x + Math.cos(angle) * rad,
      y: canopyY + (rand() - 0.6) * spread,
      z: base.z + Math.sin(angle) * rad,
    }
    blob(leaves, center, blobR * (0.7 + rand() * 0.4), rand)
  }
  // Grown birches trail a few thin, near-horizontal drooping twigs.
  if (g > 0.5) {
    const branches = 2 + Math.round(rand())
    for (let i = 0; i < branches; i++) {
      const angle = rand() * TAU
      const dir = Vec3.normalize({ x: Math.cos(angle), y: 0.6, z: Math.sin(angle) })
      const start = { x: base.x, y: base.y + h * 0.7, z: base.z }
      const end = Vec3.add(start, Vec3.scale(dir, h * 0.22))
      limb(trunk, start, end, rTrunk * 0.4, rTrunk * 0.15, 4)
      blob(leaves, end, blobR * 0.55, rand)
    }
  }
}
