<template>
  <section class="block min-h-screen pb-10 lg:hidden">
    <div class="mx-auto w-full max-w-md">
      <!-- BREADCRUMB -->
      <nav class="relative px-4 py-2 bg-[#fff] mb-3">
        <div class="flex items-center gap-1 overflow-hidden text-xs">
          <button
            type="button"
            class="flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-dark/50 transition hover:bg-dark hover:text-white"
            @click="goHome"
          >
            <component :is="icons.home" class="h-4 w-4" />
          </button>

          <span class="text-dark/25">/</span>

          <button
            type="button"
            class="truncate px-1 transition hover:text-dark"
            :class="currentStep === 'parents' ? 'text-dark/80' : 'text-dark/50'"
            @click="goMenuRoot"
          >
            {{ t("Main Menu") }}
          </button>

          <template v-if="selectedParent">
            <span class="text-dark/25">/</span>

            <button
              v-if="hasMultipleChildCategories"
              type="button"
              class="truncate px-1 transition hover:text-dark"
              :class="
                currentStep === 'categories' ? 'text-dark/80' : 'text-dark/50'
              "
              @click="goToParent"
            >
              {{ selectedParent.title }}
            </button>

            <span v-else class="truncate px-1 text-dark">
              {{ selectedParent.title }}
            </span>
          </template>

          <template
            v-if="
              selectedCategory &&
              currentStep === 'items' &&
              hasMultipleChildCategories
            "
          >
            <span class="text-dark/25">/</span>

            <span class="truncate px-1 text-dark">
              {{ selectedCategory.title }}
            </span>
          </template>
        </div>
      </nav>

      <!-- ROOT TITLE -->
      <h1
        v-if="currentStep === 'parents'"
        class="text-2xl font-medium tracking-tight text-dark text-center mb-3"
      >
        {{ t("Main Menu") }}
      </h1>

      <!-- PARENTS -->
      <div v-if="currentStep === 'parents'" class="grid grid-cols-2 gap-3 px-4">
        <button
          v-for="parent in parents"
          :key="parent.id"
          type="button"
          class="group relative overflow-hidden rounded-xl bg-dark text-left text-white"
          @click="selectParent(parent.id)"
        >
          <img
            :src="parent.image?.src || placeholderImage"
            :alt="parent.image?.alt || parent.title"
            class="absolute inset-0 h-full w-full object-cover opacity-70 transition duration-500 group-hover:scale-105"
            @error="setPlaceholderImage"
          />

          <div
            class="absolute inset-0 bg-linear-to-t from-black/75 via-black/20 to-transparent"
          />

          <div class="relative flex h-full flex-col justify-between p-4">
            <div
              class="ml-auto flex h-9 w-9 items-center justify-center rounded-full bg-white/15 text-lg backdrop-blur transition group-hover:bg-white group-hover:text-dark"
            >
              →
            </div>

            <span
              class="block text-base font-medium leading-tight tracking-tight"
            >
              {{ parent.title }}
            </span>
          </div>
        </button>
      </div>

      <!-- CATEGORIES -->
      <div v-else-if="currentStep === 'categories'" class="space-y-3 px-4">
        <button
          v-for="category in childCategories"
          :key="category.title"
          type="button"
          class="group flex w-full items-center gap-4 rounded-xl border border-dark/10 bg-[#fff] p-3 text-left backdrop-blur transition hover:bg-white"
          @click="selectCategory(category.title)"
        >
          <div class="h-24 w-24 shrink-0 overflow-hidden rounded-xl bg-white">
            <img
              :src="category.image?.src || placeholderImage"
              :alt="category.image?.alt || category.title"
              class="h-full w-full object-cover transition group-hover:scale-105"
              @error="setPlaceholderImage"
            />
          </div>

          <div class="min-w-0 flex-1">
            <h2 class="text-base font-medium leading-snug text-dark">
              {{ category.title }}
            </h2>

            <p
              v-if="category.description"
              class="mt-1 line-clamp-2 text-sm leading-relaxed text-dark/45"
            >
              {{ category.description }}
            </p>
          </div>

          <span class="shrink-0 text-xl text-dark/35">→</span>
        </button>
      </div>

      <!-- ITEMS -->
      <div v-else class="space-y-5 px-4">
        <div
          v-if="hasMultipleChildCategories"
          class="sticky top-0 z-20 -mx-4 bg-[#fff] px-4 py-3 backdrop-blur-xl"
        >
          <div class="flex gap-2 overflow-x-auto no-scrollbar">
            <button
              v-for="category in childCategories"
              :key="category.title"
              type="button"
              class="shrink-0 rounded-full border px-4 py-2 text-sm transition"
              :class="
                selectedCategoryTitle === category.title
                  ? 'border-highlight bg-[#fff] text-highlight'
                  : 'border-dark/10 bg-[#fff] text-dark/55'
              "
              @click="selectCategory(category.title)"
            >
              {{ category.title }}
            </button>
          </div>
        </div>

        <div
          v-for="item in currentItems"
          :key="item.title"
          class="rounded-xl border border-dark/10 bg-[#fff] p-3"
        >
          <div class="flex gap-4">
            <div class="h-24 w-24 shrink-0 overflow-hidden rounded-xl bg-white">
              <img
                :src="item.image?.src || placeholderImage"
                :alt="item.image?.alt || item.title"
                class="h-full w-full object-cover"
                @error="setPlaceholderImage"
              />
            </div>

            <div class="min-w-0 flex-1">
              <div class="flex items-start justify-between gap-3">
                <h3 class="text-base font-medium leading-snug text-dark">
                  {{ item.title }}
                </h3>

                <span
                  v-if="item.price"
                  class="shrink-0 text-sm font-medium text-dark"
                >
                  {{ item.price }}
                </span>
              </div>

              <p
                v-if="item.description"
                class="mt-2 text-sm leading-relaxed text-dark/45"
              >
                {{ item.description }}
              </p>
            </div>
          </div>
        </div>

        <p
          v-if="!currentItems.length"
          class="py-10 text-center text-sm text-dark/40"
        >
          {{ t("No items found") }}
        </p>
      </div>
    </div>
  </section>
</template>

<script setup lang="ts">
import { computed, onMounted, onUnmounted, ref } from "vue";
import { useI18n } from "vue-i18n";
import { useIcons } from "@/composables/useIcons";

const icons = useIcons();

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 Step = "parents" | "categories" | "items";

const props = withDefaults(
  defineProps<{
    categories: MenuCategory[];
    fallbackImage?: string;
  }>(),
  {
    fallbackImage: "/images/banner/parallax.webp",
  },
);

const emit = defineEmits<{
  back: [];
}>();

const { t } = useI18n();

const placeholderImage = "/images/banner/parallax.webp";

const selectedParentId = ref<number | null>(null);
const selectedCategoryTitle = ref<string | null>(null);

const parents = computed<MenuParent[]>(() => {
  const map = new Map<number, MenuParent>();

  props.categories.forEach((category) => {
    if (!category.parent) return;

    if (!map.has(category.parent.id)) {
      map.set(category.parent.id, {
        ...category.parent,
        image: category.parent.image || {
          src: placeholderImage,
          alt: category.parent.title,
        },
      });
    }
  });

  return Array.from(map.values()).sort((a, b) => a.id - b.id);
});

const selectedParent = computed(() => {
  return parents.value.find((parent) => parent.id === selectedParentId.value);
});

const childCategories = computed<MenuCategory[]>(() => {
  if (!selectedParentId.value) return [];

  return props.categories.filter((category) => {
    return category.parent?.id === selectedParentId.value;
  });
});

const hasMultipleChildCategories = computed(() => {
  return childCategories.value.length > 1;
});

const selectedCategory = computed<MenuCategory | undefined>(() => {
  return childCategories.value.find((category) => {
    return category.title === selectedCategoryTitle.value;
  });
});

const currentItems = computed<MenuItem[]>(() => {
  return selectedCategory.value?.items ?? [];
});

const currentStep = computed<Step>(() => {
  if (!selectedParentId.value) return "parents";

  if (hasMultipleChildCategories.value && !selectedCategoryTitle.value) {
    return "categories";
  }

  return "items";
});

function buildHash(parentId?: number | null, categoryTitle?: string | null) {
  if (!parentId) return "#menu";

  if (!categoryTitle) return `#menu/p/${parentId}`;

  return `#menu/p/${parentId}/c/${encodeURIComponent(categoryTitle)}`;
}

function pushMenuHash(parentId?: number | null, categoryTitle?: string | null) {
  window.history.pushState(
    {},
    "",
    `${window.location.pathname}${buildHash(parentId, categoryTitle)}`,
  );
}

function applyStateFromHash() {
  const hash = window.location.hash.replace("#", "");
  const parts = hash.split("/");

  if (parts[0] !== "menu") return;

  const parentIndex = parts.indexOf("p");
  const categoryIndex = parts.indexOf("c");

  const parentId =
    parentIndex >= 0 && parts[parentIndex + 1]
      ? Number(parts[parentIndex + 1])
      : null;

  const categoryTitle =
    categoryIndex >= 0 && parts[categoryIndex + 1]
      ? decodeURIComponent(parts[categoryIndex + 1])
      : null;

  if (!parentId || !parents.value.some((parent) => parent.id === parentId)) {
    selectedParentId.value = null;
    selectedCategoryTitle.value = null;
    return;
  }

  selectedParentId.value = parentId;

  const children = props.categories.filter((category) => {
    return category.parent?.id === parentId;
  });

  if (children.length === 1) {
    selectedCategoryTitle.value = children[0].title;
    return;
  }

  if (
    categoryTitle &&
    children.some((category) => category.title === categoryTitle)
  ) {
    selectedCategoryTitle.value = categoryTitle;
  } else {
    selectedCategoryTitle.value = null;
  }
}

function selectParent(parentId: number) {
  selectedParentId.value = parentId;

  const children = props.categories.filter((category) => {
    return category.parent?.id === parentId;
  });

  if (children.length === 1) {
    selectedCategoryTitle.value = children[0].title;
    pushMenuHash(parentId);
  } else {
    selectedCategoryTitle.value = null;
    pushMenuHash(parentId);
  }

  scrollTop();
}

function selectCategory(title: string) {
  selectedCategoryTitle.value = title;
  pushMenuHash(selectedParentId.value, title);
  scrollTop();
}

function goHome() {
  emit("back");
}

function goMenuRoot() {
  selectedParentId.value = null;
  selectedCategoryTitle.value = null;
  pushMenuHash();
  scrollTop();
}

function goToParent() {
  if (!selectedParentId.value) return;

  if (!hasMultipleChildCategories.value) {
    goMenuRoot();
    return;
  }

  selectedCategoryTitle.value = null;
  pushMenuHash(selectedParentId.value);
  scrollTop();
}

function handlePopState() {
  applyStateFromHash();
  scrollTop();
}

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

function setPlaceholderImage(event: Event) {
  const image = event.target as HTMLImageElement;
  image.src = props.fallbackImage || placeholderImage;
}

onMounted(() => {
  applyStateFromHash();
  window.addEventListener("popstate", handlePopState);
});

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

<style scoped>
.no-scrollbar::-webkit-scrollbar {
  display: none;
}

.no-scrollbar {
  -ms-overflow-style: none;
  scrollbar-width: none;
}
</style>