/// <reference lib="dom" />
export const game = true

import type { GameContext, InputState } from "@/shared/game"
import { rng } from "@/shared/utils"

const CELL = 20
const WIDTH = 30
const HEIGHT = 20
const TICK = 5

let snake: { x: number; y: number }[] = [{ x: 5, y: 5 }]
let dir = { x: 1, y: 0 }
let food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 }
let dead = false
let tick = 0

export function init() {
  snake = [{ x: 5, y: 5 }]
  dir = { x: 1, y: 0 }
  food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 }
  dead = false
  tick = 0
}

export function update(_delta: number, input: InputState) {
  if (dead) return

  const keys = input.pressed

  if (keys.has("ArrowUp") || keys.has("w")) dir = { x: 0, y: -1 }
  if (keys.has("ArrowDown") || keys.has("s")) dir = { x: 0, y: 1 }
  if (keys.has("ArrowLeft") || keys.has("a")) dir = { x: -1, y: 0 }
  if (keys.has("ArrowRight") || keys.has("d")) dir = { x: 1, y: 0 }

  // move every $TICK ticks
  if (++tick % TICK !== 0) return

  const head = { x: snake[0]!.x + dir.x, y: snake[0]!.y + dir.y }

  // death checks
  dead = head.x < 0 || head.x >= WIDTH || head.y < 0 || head.y >= HEIGHT ||
    snake.some(s => s.x === head.x && s.y === head.y)

  if (dead) return

  snake.unshift(head)

  // eat
  if (head.x === food.x && head.y === food.y) {
    food = { x: rng(WIDTH) - 1, y: rng(HEIGHT) - 1 }
  } else {
    snake.pop()
  }
}

export function draw(game: GameContext) {
  game.clear()
  game.rectfill(0, 0, game.width, game.height, "black")

  const boardW = WIDTH * CELL
  const boardH = HEIGHT * CELL

  // move board center → canvas center
  const offsetX = (game.width - boardW) / 2
  const offsetY = (game.height - boardH) / 2

  const c = game.ctx
  c.save()
  c.translate(offsetX, offsetY)

  // board background (now local 0,0 is board top-left)
  game.rectfill(0, 0, boardW, boardH, "green")

  // food
  game.rectfill(
    food.x * CELL, food.y * CELL,
    (food.x + 1) * CELL, (food.y + 1) * CELL,
    "lime"
  )

  // snake
  for (const s of snake) {
    game.rectfill(
      s.x * CELL, s.y * CELL,
      ((s.x + 1) * CELL) + .5, ((s.y + 1) * CELL) + .5,
      "magenta"
    )
  }

  // score!
  game.text(`Score: ${snake.length - 1}`, 5, boardH - 18, "cyan", 12)

  c.restore()

  if (dead) {
    game.centerText("GAME OVER", "red", 50)
  }
}
