<script setup lang="ts">
const { onRender, onClick } = useScreen();

const app = useAppStore();
const store = useSettingsStore();
const { assets } = useAssets();
const confirmationModal = useConfirmationModal();
const achievements = useAchievementsStore();

const GRID_SIZE = 4;
const GRID_START_X = 32;
const GRID_START_Y = 40;
const CELL_SIZE = 16;
const SPACING = 16;
const ANIMATION_SPEED = 475;

const originalSelectedCol = app.color.col;
const originalSelectedRow = app.color.row;
const originalColor = app.color.hex;

let selectedCol = app.color.col;
let selectedRow = app.color.row;
let selectorX = GRID_START_X + selectedCol * (CELL_SIZE + SPACING) - 4;
let selectorY = GRID_START_Y + selectedRow * (CELL_SIZE + SPACING) - 4;

const select = (col: number, row: number) => {
  selectedCol = col;
  selectedRow = row;
  app.setColor(col, row);
};

useKeyDown((key) => {
  switch (key) {
    case "NDS_UP":
      if (selectedRow > 0) select(selectedCol, selectedRow - 1);
      break;
    case "NDS_RIGHT":
      if (selectedCol < GRID_SIZE - 1) select(selectedCol + 1, selectedRow);
      break;
    case "NDS_DOWN":
      if (selectedRow < GRID_SIZE - 1) select(selectedCol, selectedRow + 1);
      break;
    case "NDS_LEFT":
      if (selectedCol > 0) select(selectedCol - 1, selectedRow);
      break;
  }
});

onClick((x, y) => {
  const relativeX = x - GRID_START_X;
  const relativeY = y - GRID_START_Y;

  const col = Math.floor(relativeX / (CELL_SIZE + SPACING));
  const row = Math.floor(relativeY / (CELL_SIZE + SPACING));

  const cellLocalX = relativeX % (CELL_SIZE + SPACING);
  const cellLocalY = relativeY % (CELL_SIZE + SPACING);

  if (
    rectContains([0, 0, GRID_SIZE - 1, GRID_SIZE - 1], [col, row]) &&
    rectContains([0, 0, CELL_SIZE + 1, CELL_SIZE + 1], [cellLocalX, cellLocalY])
  ) {
    select(col, row);
  }
});

onRender((ctx, deltaTime) => {
  assets.images.settings.bottomScreen.user.colorPalette.draw(ctx, 16, 32);

  // animate
  const finalSelectorX = GRID_START_X + selectedCol * (CELL_SIZE + SPACING) - 4;
  const finalSelectorY = GRID_START_Y + selectedRow * (CELL_SIZE + SPACING) - 4;

  const dx = finalSelectorX - selectorX;
  const dy = finalSelectorY - selectorY;

  if (dx > 0) {
    selectorX += ANIMATION_SPEED * (deltaTime / 1000);
    if (selectorX > finalSelectorX) selectorX = finalSelectorX;
  } else if (dx < 0) {
    selectorX -= ANIMATION_SPEED * (deltaTime / 1000);
    if (selectorX < finalSelectorX) selectorX = finalSelectorX;
  } else if (dy > 0) {
    selectorY += ANIMATION_SPEED * (deltaTime / 1000);
    if (selectorY > finalSelectorY) selectorY = finalSelectorY;
  } else if (dy < 0) {
    selectorY -= ANIMATION_SPEED * (deltaTime / 1000);
    if (selectorY < finalSelectorY) selectorY = finalSelectorY;
  }

  // selector
  ctx.fillStyle = APP_COLORS[selectedRow]![selectedCol]!;

  const offsets = [0, 3, 7, 11, 15, 19, 22];
  for (const offset of offsets) {
    ctx.fillRect(selectorX + offset, selectorY + 0, 2, 1);
    ctx.fillRect(selectorX + offset, selectorY + 23, 2, 1);
    ctx.fillRect(selectorX + 0, selectorY + offset, 1, 2);
    ctx.fillRect(selectorX + 23, selectorY + offset, 1, 2);
  }

  // preview
  ctx.fillRect(192, 96, 32, 32);
});

const handleCancel = () => {
  select(originalSelectedCol, originalSelectedRow);
  store.closeSubMenu();
};

const handleConfirm = () => {
  app.save();

  if (app.color.hex !== originalColor) {
    achievements.unlock("settings_color_change");
  }

  if (!achievements.advancement.colors.includes(app.color.hex)) {
    achievements.advancement.colors.push(app.color.hex);
    if (achievements.advancement.colors.length === APP_COLORS.flat().length) {
      achievements.unlock("settings_color_try_all");
    }
  }

  confirmationModal.open({
    text: $t("settings.user.color.confirmation"),
    onClosed: () => store.closeSubMenu(),
  });
  setTimeout(() => {
    confirmationModal.close();
  }, 2000);
};
</script>

<template>
  <CommonButtons
    :y-offset="0"
    b-label="Cancel"
    a-label="Confirm"
    @activate-b="handleCancel"
    @activate-a="handleConfirm"
  />
</template>
