<template>
  <MenuHome v-if="activeView === 'home'" @change-view="changeView" />

  <MenuWrapper
    v-else-if="activeView === 'menu'"
    :categories="categories"
    :fallback-image="fallbackImage"
    @back="goHome"
  />

  <MenuCampaings
    v-else-if="activeView === 'campaigns'"
    :campaigns="campaigns"
    :fallback-image="fallbackImage"
    @back="goHome"
  />

  <MenuContact v-else-if="activeView === 'contact'" @back="goHome" />
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from "vue";

type Image = {
  src?: string;
  alt?: string;
};

type MenuParent = {
  id: number;
  title: string;
  image?: Image;
};

type MenuItem = {
  title: string;
  description?: string;
  image?: Image;
  price?: string;
};

type MenuCategory = {
  parent?: MenuParent;
  title: string;
  description?: string;
  image?: Image;
  items?: MenuItem[];
};

type Campaign = {
  title: string;
  excerpt: string;
  description: string;
  image: {
    src: string;
    alt: string;
  };
  startDate: string;
  endDate: string;
  tags: string[];
  discount: string;
};

type ActiveView = "home" | "menu" | "campaigns" | "contact";

defineProps<{
  categories: MenuCategory[];
  campaigns: Campaign[];
  fallbackImage?: string;
}>();

const emit = defineEmits<{
  viewChange: [view: ActiveView];
}>();

const activeView = ref<ActiveView>("home");

function isActiveView(value: string): value is ActiveView {
  return ["home", "menu", "campaigns", "contact"].includes(value);
}

function getViewFromHash(): ActiveView {
  const hash = window.location.hash.replace("#", "");
  const view = hash.split("/")[0];

  return isActiveView(view) ? view : "home";
}

function updateHash(view: ActiveView) {
  const path = window.location.pathname;
  const hash = view === "home" ? "" : `#${view}`;

  window.history.pushState({ view }, "", `${path}${hash}`);
}

function setView(view: ActiveView, push = true) {
  activeView.value = view;
  emit("viewChange", view);

  if (push) {
    updateHash(view);
  }

  window.scrollTo({
    top: 0,
    behavior: "smooth",
  });
}

function changeView(view: ActiveView) {
  setView(view, true);
}

function goHome() {
  setView("home", true);
}

function handlePopState() {
  setView(getViewFromHash(), false);
}

onMounted(() => {
  const initialView = getViewFromHash();

  activeView.value = initialView;
  emit("viewChange", initialView);

  window.addEventListener("popstate", handlePopState);
});

onUnmounted(() => {
  window.removeEventListener("popstate", handlePopState);
});
</script>