<script setup lang="ts">
import OptionsMenu from "./Options/Menu.vue";
import OptionsStartUp from "./Options/StartUp.vue";
import OptionsLanguage from "./Options/Language.vue";
import OptionsGbaMode from "./Options/GbaMode.vue";

import UserMenu from "./User/Menu.vue";
import UserColor from "./User/Color.vue";
import UserBirthday from "./User/Birthday.vue";

import ClockMenu from "./Clock/Menu.vue";
import TouchScreenMenu from "./TouchScreen/Menu.vue";
import Selector from "~/components/Common/ButtonSelector.vue";

const app = useAppStore();
const settingsStore = useSettingsStore();

const isMainMenu = (button: string): button is SettingsMenu =>
  SETTINGS_MENUS.includes(button as SettingsMenu);

const isSubMenu = (button: string): button is SettingsSubMenu =>
  SETTINGS_SUB_MENUS.includes(button as SettingsSubMenu);

const getParentMenu = (submenu: string): SettingsMenu => {
  const match = submenu.match(/^(options|clock|user|touchScreen)/);
  if (!match?.[1]) throw new Error(`Invalid submenu: '${submenu}'`);
  return match[1] as SettingsMenu;
};

const { selectedButton: selected, selectorPosition } = useButtonNavigation({
  buttons: {
    options: [31, 119, 49, 49],
    optionsLanguage: [31, 71, 49, 49],
    optionsGbaMode: [79, 71, 49, 49],
    optionsStartUp: [31, 23, 49, 49],

    clock: [79, 119, 49, 49],
    clockAlarm: [79, 71, 49, 49],
    clockTime: [127, 71, 49, 49],
    clockDate: [79, 23, 49, 49],

    user: [127, 119, 49, 49],
    userBirthday: [79, 71, 49, 49],
    userName: [127, 71, 49, 49],
    userMessage: [175, 71, 49, 49],
    userColor: [127, 23, 49, 49],

    touchScreen: [175, 119, 49, 49],
  },
  initialButton: "options",
  onButtonClick: (buttonName) => {
    if (isSubMenu(buttonName)) {
      settingsStore.openSubMenu(buttonName);
    } else {
      if (buttonName === "options") selected.value = "optionsLanguage";
      if (buttonName === "clock") selected.value = "clockAlarm";
      if (buttonName === "user") selected.value = "userName";
      if (buttonName === "touchScreen") throw new Error("Not implemented");
    }
  },
  navigation: {
    options: {
      right: "clock",
      up: "optionsLanguage",
    },
    optionsLanguage: {
      down: "options",
      up: "optionsStartUp",
      right: "optionsGbaMode",
    },
    optionsGbaMode: {
      down: ["options", false],
      left: "optionsLanguage",
      up: ["optionsStartUp", false],
    },
    optionsStartUp: {
      right: ["optionsGbaMode", false],
      down: "optionsLanguage",
    },

    clock: {
      left: "options",
      right: "user",
      up: "clockAlarm",
    },
    clockAlarm: {
      down: "clock",
      up: "clockDate",
      right: "clockTime",
    },
    clockTime: {
      down: ["clock", false],
      left: "clockAlarm",
      up: ["clockDate", false],
    },
    clockDate: {
      right: ["clockTime", false],
      down: "clockAlarm",
    },

    user: {
      left: "clock",
      right: "touchScreen",
      up: "userName",
    },
    userBirthday: {
      down: ["user", false],
      up: ["userColor", false],
      right: "userName",
    },
    userName: {
      down: "user",
      left: "userBirthday",
      right: "userMessage",
      up: "userColor",
    },
    userMessage: {
      down: ["user", false],
      left: "userName",
      up: ["userColor", false],
    },
    userColor: {
      left: ["userBirthday", false],
      right: ["userMessage", false],
      down: "userName",
    },

    touchScreen: {
      left: "user",
    },
  },
  disabled: computed(() => settingsStore.currentSubMenu !== null),
});

const isSubmenuSelected = computed(() => isSubMenu(selected.value));
const selectedSubmenuParent = computed(() =>
  isSubmenuSelected.value ? getParentMenu(selected.value) : null,
);

provide("menusContext", {
  isSubmenuSelected,
  selectedSubmenuParent,
});

watch(
  selected,
  (newSelected) => {
    if (settingsStore.currentSubMenu === null) {
      if (isMainMenu(newSelected)) {
        settingsStore.openMenu(newSelected, false);
      } else if (isSubMenu(newSelected)) {
        const parentMenu = getParentMenu(newSelected);
        if (parentMenu) {
          settingsStore.openMenu(parentMenu, true);
        }
      }
    }
  },
  { immediate: true },
);

const viewComponents: Record<string, Component> = {
  optionsStartUp: OptionsStartUp,
  optionsLanguage: OptionsLanguage,
  optionsGbaMode: OptionsGbaMode,

  userColor: UserColor,
  userBirthday: UserBirthday,
};
</script>

<template>
  <template v-if="!settingsStore.currentSubMenu">
    <OptionsMenu :x="33" :y="121" />
    <ClockMenu :x="81" :y="121" />
    <UserMenu :x="129" :y="121" />
    <TouchScreenMenu :x="177" :y="121" :opacity="1" />

    <Selector :rect="selectorPosition" :opacity="1" />

    <CommonButtons
      v-if="isSubmenuSelected"
      :y-offset="0"
      b-label="Go back"
      a-label="Select"
      @activate-b="selected = getParentMenu(selected)"
    />
    <CommonButtons
      v-else
      :y-offset="0"
      b-label="Quit"
      a-label="Select"
      @activate-b="app.navigateTo('home')"
    />
  </template>
  <component :is="viewComponents[settingsStore.currentSubMenu]" v-else />
</template>
