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

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

const CELL = 20
const COLS = 30   // 600 px wide
const ROWS = 12   // 240 px tall of bricks

const PADDLE_W = 6
const PADDLE_H = 1
const BALL_SPEED = 4

const ROW_COLORS = ["red", "orange", "yellow", "green", "blue", "magenta"]

let paddleX = 0
let ball = { x: 0, y: 0, dx: BALL_SPEED, dy: -BALL_SPEED }
let bricks: { x: number, y: number, alive: boolean }[] = []
let score = 0
let dead = false

export function init() {
  paddleX = (COLS * CELL - PADDLE_W * CELL) / 2
  ball = {
    x: COLS * CELL / 2,
    y: ROWS * CELL + 60,
    dx: BALL_SPEED,
    dy: -BALL_SPEED
  }

  bricks = []
  for (let r = 0; r < ROWS; r++) {
    for (let c = 0; c < COLS; c += 2) {
      bricks.push({
        x: c * CELL,
        y: r * CELL,
        alive: true
      })
    }
  }

  dead = false
}

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

  if (input.pressed.has("ArrowLeft") || input.pressed.has("a")) {
    paddleX -= 6
  }
  if (input.pressed.has("ArrowRight") || input.pressed.has("d")) {
    paddleX += 6
  }

  // keep paddle on screen
  paddleX = Math.max(0, Math.min(paddleX, COLS * CELL - PADDLE_W * CELL))

  // move ball
  ball.x += ball.dx
  ball.y += ball.dy

  // wall bounce
  if (ball.x < 0 || ball.x > COLS * CELL) ball.dx *= -1
  if (ball.y < 0) ball.dy *= -1

  // paddle bounce
  const paddleY = ROWS * CELL + 60
  const paddleH = CELL

  if (
    ball.x > paddleX &&
    ball.x < paddleX + PADDLE_W * CELL &&
    ball.y + 6 >= paddleY &&
    ball.y - 6 <= paddleY + paddleH
  ) {
    ball.dy *= -1
    ball.y = paddleY - 6
  }

  // brick collision
  for (const b of bricks) {
    if (!b.alive) continue
    if (
      ball.x > b.x &&
      ball.x < b.x + (CELL * 2) &&
      ball.y > b.y &&
      ball.y < b.y + CELL
    ) {
      score += 100
      b.alive = false
      ball.dy *= -1
    }
  }

  // death
  if (ball.y > ROWS * CELL + 100) dead = true
}

export function draw(game: GameContext) {
  game.clear("#6C6FF6")

  const boardW = COLS * CELL
  const boardH = ROWS * CELL + 100
  const offsetX = (game.width - boardW) / 2
  const offsetY = (game.height - boardH) / 2

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

  // background
  game.rectfill(0, 0, boardW, boardH, "black")

  // paddle
  game.rectfill(
    paddleX,
    ROWS * CELL + 60,
    paddleX + PADDLE_W * CELL,
    ROWS * CELL + 60 + CELL,
    "white"
  )

  // ball
  game.circfill(ball.x, ball.y, 6, "red")

  // bricks
  for (const b of bricks) {
    if (b.alive) {
      const color = pickColor(b.x, b.y)
      game.rectfill(b.x, b.y, (b.x + (CELL * 2)) - .5, (b.y + CELL) - .5, color)
    }
  }
  // score!
  game.text(`Score: ${score}`, 5, boardH - 18, "cyan", 12)

  c.restore()

  // ya dead
  if (dead) {
    game.centerTextX("GAME OVER", boardH + 30, "red", 24)
  }
}

function pickColor(x: number, y: number): string {
  const row = Math.floor(y / CELL)
  const colorIndex = Math.floor(row / 2) % ROW_COLORS.length
  return ROW_COLORS[colorIndex] || "white"
}
