<script setup lang="ts">
import { until } from "@vueuse/core";
import gsap from "gsap";

const app = useAppStore();
const store = useSettingsStore();
const confirmationModal = useConfirmationModal();
const { onRender } = useScreen();
const { assets } = useAssets();
const renderingModeAssets =
  assets.images.settings.bottomScreen.options.renderingMode;

const HEADER_HEIGHT = renderingModeAssets.buttonHeader.rect.height;
const HEADER_SLIDE_DURATION = 0.2;
const BUTTON_STAGGER = 0.3;
const SLIDE_OFFSET = 96;
const SLIDE_DURATION = 0.25;

const isAnimating = ref(true);

const bLabel = ref($t("common.goBack"));
const aLabel = ref($t("common.select"));

const animation = reactive({
  _3dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
  _2dMode: { headerOffsetY: HEADER_HEIGHT * 3, opacity: 0 },
  outroOffsetY: 0,
  outroOpacity: 1,
});

const animateIntro = async () => {
  isAnimating.value = true;
  await gsap
    .timeline()
    .to(
      animation._3dMode,
      {
        opacity: 1,
        headerOffsetY: 0,
        duration: HEADER_SLIDE_DURATION,
        ease: "none",
      },
      0,
    )
    .to(
      animation._2dMode,
      {
        opacity: 1,
        headerOffsetY: 0,
        duration: HEADER_SLIDE_DURATION,
        ease: "none",
      },
      BUTTON_STAGGER,
    )
    .call(
      () => {
        bLabel.value = $t("common.cancel");
        aLabel.value = $t("common.confirm");
      },
      [],
      SUBMENU_LABEL_CHANGE_DELAY,
    );
  isAnimating.value = false;
};

const animateOutro = async () => {
  isAnimating.value = true;
  await gsap
    .timeline()
    .to(
      animation,
      { outroOffsetY: SLIDE_OFFSET, duration: SLIDE_DURATION, ease: "none" },
      0,
    )
    .to(
      animation,
      { outroOpacity: 0, duration: SLIDE_DURATION, ease: "none" },
      0,
    );
};

onMounted(() => {
  animateIntro();
});

const { selected, selectorPosition } = useButtonNavigation({
  buttons: {
    _3dMode: [11, 27, 233, 74],
    _2dMode: [11, 91, 233, 74],
  },
  initialButton: app.settings.renderingMode === "3d" ? "_3dMode" : "_2dMode",
  onActivate: () => handleActivateA(),
  navigation: {
    _3dMode: { down: "_2dMode" },
    _2dMode: { up: "_3dMode" },
  },
  disabled: isAnimating,
  selectorAnimation: {
    ease: "none",
    duration: 0.065,
  },
});

const handleActivateB = async () => {
  if (isAnimating.value) return;
  await animateOutro();
  store.closeSubMenu();
};

const handleActivateA = () => {
  if (isAnimating.value) return;
  const mode = selected.value === "_3dMode" ? "3d" : "2d";
  app.setRenderingMode(mode);

  const showConfirmation = () => {
    confirmationModal.open({
      text:
        mode === "3d"
          ? $t("settings.options.renderingMode.confirmation3d")
          : $t("settings.options.renderingMode.confirmation2d"),
      onClosed: async () => {
        await animateOutro();
        store.closeSubMenu(true);
      },
      keepButtonsDown: true,
      timeout: 2000,
    });
  };

  until(() => app.ready)
    .toBeTruthy()
    .then(showConfirmation);
};

onRender((ctx) => {
  ctx.font = "10px NDS10";
  ctx.textBaseline = "top";

  const drawButton = (
    title: string,
    logo: AtlasImage,
    y: number,
    active: boolean,
    key: "_3dMode" | "_2dMode",
  ) => {
    ctx.save();
    ctx.translate(16, y + animation.outroOffsetY);

    const buttonWidth = renderingModeAssets.buttonBody.rect.width;

    const bodyImg = active
      ? renderingModeAssets.buttonActiveBody
      : renderingModeAssets.buttonBody;
    const headerImg = active
      ? renderingModeAssets.buttonActiveHeader
      : renderingModeAssets.buttonHeader;
    const colorOpts = active ? { colored: true } : undefined;

    ctx.globalAlpha = animation[key].opacity * animation.outroOpacity;

    bodyImg.draw(ctx, 0, HEADER_HEIGHT - 2, colorOpts);
    ctx.fillStyle = "#282828";
    const descKey = key === "_3dMode" ? "3dDescription" : "2dDescription";
    const text = $t(`settings.options.renderingMode.${descKey}`);
    fillTextHCenteredMultiline(ctx, text, 0, y, buttonWidth, 15);

    ctx.translate(0, animation[key].headerOffsetY);
    headerImg.draw(ctx, 0, 0, colorOpts);
    ctx.fillStyle = "#000000";
    fillImageTextHCentered(ctx, logo, title, 0, 4, buttonWidth, 4);

    ctx.globalAlpha = 1;

    ctx.restore();
  };

  drawButton(
    $t("settings.options.renderingMode.3dMode"),
    renderingModeAssets._3dMode,
    32,
    selected.value === "_3dMode",
    "_3dMode",
  );
  drawButton(
    $t("settings.options.renderingMode.2dMode"),
    renderingModeAssets._2dMode,
    96,
    selected.value === "_2dMode",
    "_2dMode",
  );
});
</script>

<template>
  <CommonButtons
    :y-offset="confirmationModal.buttonsYOffset + store.submenuButtonsOffsetY"
    :b-label="bLabel"
    :a-label="aLabel"
    no-keyboard-a
    @activate-a="handleActivateA"
    @activate-b="handleActivateB"
  />

  <CommonButtonSelector
    :rect="[
      selectorPosition[0],
      selectorPosition[1] + animation.outroOffsetY,
      selectorPosition[2],
      selectorPosition[3],
    ]"
    :opacity="animation[selected].opacity * animation.outroOpacity"
  />
</template>
