const audio = document.getElementById("musica");
const startButton = document.getElementById("startButton");
const debugTextArea = document.getElementById("debug");
const canvas = document.getElementById("tablero");
const ctx = canvas.getContext("2d");
ctx.scale(20, 20);
const marcador = document.getElementById("score");
const FILAS = 20;
const COLUMNAS = 10;
const FPS = 60;

const PIEZAS = [
  [[1, 1, 1, 1]],
  [
    [2, 2, 2],
    [0, 0, 2],
  ],
  [
    [3, 3, 3],
    [3, 0, 0],
  ],
  [
    [4, 4],
    [4, 4],
  ],
  [
    [5, 5, 0],
    [0, 5, 5],
  ],
  [
    [0, 6, 6],
    [6, 6, 0],
  ],
  [
    [7, 7, 7],
    [0, 7, 0],
  ],
];
const COLORES_PIEZAS = {
  0: "#282829", // Fondo oscuro
  1: "#FFFFFF", // Blanco para cyan
  2: "#FFA500", // Naranja
  3: "#FFFF00", // Amarillo
  4: "#00FF00", // Verde
  5: "#FF0000", // Rojo
  6: "#800080", // Púrpura
  7: "#0000FF", // Azul
};

const KEYDOWNHANDLER = (event) => {
  if (event.key === "ArrowDown") {
    moverPiezaAbajo();
  } else if (event.key === "ArrowLeft") {
    moverPiezaIzquierda();
  } else if (event.key === "ArrowRight") {
    moverPiezaDerecha();
  } else if (event.key === " ") {
    rotarPieza();
  } else if (event.key === "1") {
    toggleDebug();
  } else if (event.key === "Escape") {
    gameOver();
  }
};

let debugFlag = false;
let lineasVelocidad = 10;
let velocidadCaida = 400;
let intervalBuclePrincipal;
let tiempoUltimoMovimiento = 0;
let tablero = [];
let puntuacion = 0;
let piezaJugador;
let piezaJugadorX;
let piezaJugadorY;

audio.preload = "auto";

function generaPiezaAleatoria() {
  const indice = Math.floor(Math.random() * PIEZAS.length);
  return PIEZAS[indice];
}

function dibujaPiezaEnTablero(pieza, offsetX, offsetY) {
  pieza.forEach((fila, y) => {
    fila.forEach((valor, x) => {
      if (valor) {
        dibujarCuadro(x + offsetX, y + offsetY, valor);
      }
    });
  });
}

function soltarNuevaPieza() {
  piezaJugador = generaPiezaAleatoria();
  piezaJugadorX = Math.floor(COLUMNAS / 2) - 1;
  piezaJugadorY = 0;
}

function dibujarTablero() {
  for (let fila = 0; fila < FILAS; fila++) {
    for (let columna = 0; columna < COLUMNAS; columna++) {
      dibujarCuadro(columna, fila, tablero[fila][columna]);
    }
  }
}

function dibujarCuadro(x, y, color) {
  ctx.fillStyle = COLORES_PIEZAS[color];
  ctx.fillRect(x, y, 1, 1);
}

function actualizaMarcador() {
  marcador.textContent = puntuacion;
}

function inicializarTablero() {
  for (let fila = 0; fila < FILAS; fila++) {
    tablero[fila] = [];
    for (let columna = 0; columna < COLUMNAS; columna++) {
      tablero[fila][columna] = 0;
    }
  }
  puntuacion = 0;
  dibujarTablero();
  actualizaMarcador();
  soltarNuevaPieza();
}

function moverPiezaAbajo() {
  piezaJugadorY++;
  if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) {
    if (piezaJugadorY <= 1) {
      gameOver();
    }
    piezaJugadorY--;
    fijarPiezaTablero();
    soltarNuevaPieza();
  }
}

function moverPiezaIzquierda() {
  piezaJugadorX--;
  if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) {
    piezaJugadorX++; // Deshacer el movimiento si hay colisión
  }
}

function moverPiezaDerecha() {
  piezaJugadorX++;
  if (colisiona(piezaJugador, piezaJugadorX, piezaJugadorY)) {
    piezaJugadorX--; // Deshacer el movimiento si hay colisión
  }
}

function rotarPieza() {
  const piezaRotada = [];
  for (let y = 0; y < piezaJugador[0].length; y++) {
    piezaRotada[y] = [];
    for (let x = 0; x < piezaJugador.length; x++) {
      piezaRotada[y][x] = piezaJugador[piezaJugador.length - 1 - x][y];
    }
  }
  if (!colisiona(piezaRotada, piezaJugadorX, piezaJugadorY)) {
    piezaJugador = piezaRotada;
  }
}

function colisiona(pieza, offsetX, offsetY) {
  for (let y = 0; y < pieza.length; y++) {
    for (let x = 0; x < pieza[y].length; x++) {
      if (
        pieza[y][x] &&
        (tablero[y + offsetY] && tablero[y + offsetY][x + offsetX]) !== 0
      ) {
        return true;
      }
    }
  }
  return false;
}

function fijarPiezaTablero() {
  piezaJugador.forEach((fila, y) => {
    fila.forEach((valor, x) => {
      if (valor) {
        tablero[piezaJugadorY + y][piezaJugadorX + x] = valor;
      }
    });
  });
  revisarLineasCompletas();
}

function revisarLineasCompletas() {
  let lineasCompletas = 0;
  for (let y = FILAS - 1; y >= 0; y--) {
    let filaCompleta = true;
    for (let x = 0; x < COLUMNAS; x++) {
      if (tablero[y][x] === 0) {
        filaCompleta = false;
        break;
      }
    }
    if (filaCompleta) {
      tablero.splice(y, 1);
      tablero.unshift(Array(COLUMNAS).fill(0));
      y++;
      lineasCompletas++;
    }
  }
  if (lineasCompletas) {
    lineasVelocidad -= lineasCompletas;
    if (lineasVelocidad <= 0) {
      lineasVelocidad = 10;
      velocidadCaida -= 10;
    }
    switch (lineasCompletas) {
      case 1:
        puntuacion += 10;
        break;
      case 2:
        puntuacion += 40;
        break;
      case 3:
        puntuacion += 60;
        break;
      case 4:
        puntuacion += 80;
        break;
    }
    actualizaMarcador();
  }
}

function actualizar() {
  const ahora = Date.now();
  const deltaTiempo = ahora - tiempoUltimoMovimiento;

  if (deltaTiempo > velocidadCaida) {
    tiempoUltimoMovimiento = ahora;
    moverPiezaAbajo();
  }
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  dibujarTablero();
  dibujaPiezaEnTablero(piezaJugador, piezaJugadorX, piezaJugadorY);
  debugLog();
}

function iniciarPartida() {
  startButton.blur();
  startButton.style.visibility = "hidden";
  document.addEventListener("keydown", KEYDOWNHANDLER);
  musica.play();
  inicializarTablero();
  intervalBuclePrincipal = setInterval(actualizar, 1000 / FPS);
}

function gameOver() {
  clearInterval(intervalBuclePrincipal);
  document.removeEventListener("keydown", KEYDOWNHANDLER);
  startButton.style.visibility = "visible";
  musica.pause();
  musica.currentTime = 0;
  startButton.focus();
}

function toggleDebug() {
  if (debugFlag) {
    debugFlag = false;
    debugTextArea.style.display = "none";
  } else {
    debugFlag = true;
    debugTextArea.style.display = "block";
  }
}

function debugLog() {
  debugTextArea.value =
    `Filas: ${FILAS}\n` +
    `Columnas: ${COLUMNAS}\n` +
    `PosX: ${piezaJugadorX} - PosY: ${piezaJugadorY} \n` +
    `Lineas hasta aumento de velocidad: ${lineasVelocidad}\n` +
    `Velocidad ms/fila: ${velocidadCaida}\n`;
}
