import gsap from "gsap";

export const SETTINGS_MENUS = [
  "options",
  "clock",
  "user",
  "touchScreen",
] as const;

export const SETTINGS_SUB_MENUS = [
  "optionsLanguage",
  "options2048",
  "optionsStartUp",
  "clockAchievements",
  "clockTime",
  "clockDate",
  "userBirthday",
  "userUserName",
  "userSnake",
  "userColor",
  "touchScreenTapTap",
] as const;

export type SettingsMenu = (typeof SETTINGS_MENUS)[number];
export type SettingsSubMenu = (typeof SETTINGS_SUB_MENUS)[number];
export type SettingsNavigableButton =
  | SettingsMenu
  | Exclude<SettingsSubMenu, "touchScreenTapTap">;

export const useSettingsStore = defineStore("settings", {
  state: () => ({
    currentMenu: null as SettingsMenu | null,
    currentSubMenu: null as SettingsSubMenu | null,
    menuExpanded: false,
    selectedButton: "options" as SettingsNavigableButton,
    notificationYOffset: 48,
    barOffsetY: 24,
    menuOffsets: [0, -48, -48, -48] as [number, number, number, number],
    menuYOffset: 72,

    animatingNotification: false,

    isIntro: true,
    isOutro: false,
  }),

  actions: {
    openMenu(menu: SettingsMenu, expanded: boolean = false) {
      this.currentMenu = menu;
      this.menuExpanded = expanded;
      this.currentSubMenu = null;
    },

    openSubMenu(submenu: SettingsSubMenu) {
      this.currentSubMenu = submenu;

      const achievements = useAchievementsStore();
      if (!achievements.advancement.visitedSettings.includes(submenu)) {
        achievements.advancement.visitedSettings.push(submenu);
      }
      if (
        achievements.advancement.visitedSettings.length ===
        SETTINGS_SUB_MENUS.length
      ) {
        achievements.unlock("settings_visit_all");
      }
    },

    closeSubMenu() {
      this.currentSubMenu = null;
    },

    animateIntro() {
      this.isIntro = true;

      gsap
        .timeline()
        // bars
        .fromTo(
          this,
          { barOffsetY: 24 },
          { barOffsetY: 0, duration: 0.2, ease: "none" },
          0,
        )
        // title notification
        .fromTo(
          this,
          { notificationYOffset: 48 },
          { notificationYOffset: 0, duration: 0.2, ease: "none" },
          0.1,
        )
        // menus slide up
        .fromTo(
          this,
          { menuYOffset: 72 },
          { menuYOffset: 0, duration: 0.2, ease: "none" },
          0,
        )
        // menus accordion
        .fromTo(
          this.menuOffsets,
          { 1: -48 },
          { 1: 0, duration: 0.1, ease: "none" },
          0.2,
        )
        .fromTo(
          this.menuOffsets,
          { 2: -48 },
          { 2: 0, duration: 0.1, ease: "none" },
          0.3,
        )
        .fromTo(
          this.menuOffsets,
          { 3: -48 },
          { 3: 0, duration: 0.1, ease: "none" },
          0.4,
        )
        .call(() => {
          this.isIntro = false;
        });
    },

    animateOutro() {
      this.isOutro = true;

      gsap
        .timeline()
        // title notification
        .fromTo(
          this,
          { notificationYOffset: 0 },
          { notificationYOffset: 48, duration: 0.2, ease: "none" },
          0,
        )
        // bars
        .fromTo(
          this,
          { barOffsetY: 0 },
          { barOffsetY: 24, duration: 0.2, ease: "none" },
          0.1,
        )
        // menus accordion
        .fromTo(
          this.menuOffsets,
          { 3: 0 },
          { 3: -48, duration: 0.1, ease: "none" },
          0,
        )
        .fromTo(
          this.menuOffsets,
          { 2: 0 },
          { 2: -48, duration: 0.1, ease: "none" },
          0.1,
        )
        .fromTo(
          this.menuOffsets,
          { 1: 0 },
          { 1: -48, duration: 0.1, ease: "none" },
          0.2,
        )
        // menus slide down
        .fromTo(
          this,
          { menuYOffset: 0 },
          { menuYOffset: 72, duration: 0.2, ease: "none" },
          0.3,
        )
        .call(() => {
          const app = useAppStore();
          app.navigateTo("home");
          this.isOutro = false;
        });
    },
  },
});
