<template>
  <NuxtLayout name="default">
    <NotFound v-if="notFound" />
    <ContentBuilder v-else-if="showContentBuilder" :hero="page?.hero" :content="page?.content" />
    <CollectionDetail v-else :data="detail" />
  </NuxtLayout>
</template>

<script setup lang="ts">
import type Article from "~~/types/collection/article";
import type Event from "~~/types/collection/event";
import type Operation from "~~/types/collection/operation";
import type Vehicle from "~~/types/collection/vehicle";
import type Page from "~~/types/collection/page";

const {
  params: { slug: params },
} = useRoute();
const { findOne, find } = useStrapi();

const sitemap = useSitemap();

const detail = ref<Article | Operation | Event | Vehicle | undefined>(undefined);

const activePath = computed(() => {
  return "/" + (Array.isArray(params) ? params.join("/") : params);
});
const activePageBySitemap = computed(() => {
  return sitemap.value.find((s) => s.path == activePath.value);
});
const similarestPage = computed(() => {
  return sitemap.value.reduce(
    (bestMatch, current) => {
      const currentMatchLength = current.path
        .split("/")
        .filter(
          (segment, index) => segment != "" && segment.trim() == activePath.value.split("/")[index]?.trim()
        ).length;
      const bestMatchLength = bestMatch.path
        .split("/")
        .filter(
          (segment, index) => segment != "" && segment.trim() == activePath.value.split("/")[index]?.trim()
        ).length;

      if (currentMatchLength > bestMatchLength) {
        return current;
      } else {
        return bestMatch;
      }
    },
    { path: "", origin: "", hasCollection: false }
  );
});

const { data: pages } = await useAsyncData(
  activePath,
  () =>
    findOne<Page | Array<Page>>("pages", similarestPage.value?.document, {
      populate: {
        content: {
          populate: "*",
        },
        hero: {
          populate: "*",
        },
      },
      filters: !similarestPage.value?.document
        ? {
            slug: { $eq: Array.isArray(params) ? params.join("~") : params ?? "" },
            ref_only_access: { $eq: false },
          }
        : {},
    }),
  {
    default: () => null,
    watch: [activePath],
  }
);
const page = computed(() => {
  return Array.isArray(pages.value?.data) ? pages.value.data[0] : pages.value?.data;
});

const isCollectionDetail = computed(() => {
  return activePath.value != similarestPage.value.path && similarestPage.value.hasCollection;
});

const notFound = computed(() => {
  if (isCollectionDetail.value && detail.value) return !detail.value;
  else
    return (
      !page.value ||
      (page.value && !(page.value.content.length != 0 || page.value.hero.title || page.value.hero.banner))
    );
});

const showContentBuilder = computed(() => {
  if (isCollectionDetail.value && detail.value) return !detail.value;
  else return page.value && (page.value.content.length != 0 || page.value.hero.title || page.value.hero.banner);
});

if (isCollectionDetail) {
  let collectionOfDetail = [
    ...new Set(
      page.value?.content
        .filter((c) => c.__component == "shared.list")
        .filter((c) => c.lookup.enable_detail)
        .map((c) => c.lookup.collection)
    ),
  ];

  for (const element of collectionOfDetail) {
    const detailKey = `detail-${element}-${activePath.value.substring(activePath.value.lastIndexOf("/") + 1)}`;
    const { data: details } = await useAsyncData(
      detailKey,
      () =>
        find<Article | Operation | Event | Vehicle>(element ?? "", {
          populate: "*",
          filters: {
            slug: {
              $eq: activePath.value.substring(activePath.value.lastIndexOf("/") + 1),
            },
          },
        }),
      {
        watch: [activePath],
      }
    );
    if (details.value?.data[0]) {
      detail.value = details.value?.data[0];
      break;
    }
  }
}
</script>
