<template>
  <div v-if="data?.lookup.list_with_date != 'none'" class="flex flex-row justify-between w-full max-w-4xl mx-auto">
    <svg
      viewBox="0 0 24 24"
      class="h-5 w-5 cursor-pointer fill-none stroke-2 stroke-black"
      :class="allowLeft ? '' : 'pointer-events-none opacity-75'"
      @click="changeTimedData(allowLeft ?? 0)"
    >
      <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
    </svg>
    <h1>{{ activeYear }}</h1>
    <svg
      viewBox="0 0 24 24"
      class="h-5 w-5 cursor-pointer fill-none stroke-2 stroke-black"
      :class="allowRight ? '' : 'pointer-events-none opacity-75'"
      @click="changeTimedData(allowRight ?? 0)"
    >
      <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
    </svg>
  </div>
  <div
    class="flex gap-2 w-full max-w-4xl mx-auto"
    :class="data?.lookup.show_image ? 'flex-row flex-wrap justify-center' : ' flex-col'"
  >
    <div v-for="(item, index) in collection" :key="item.slug" class="contents">
      <h4 v-if="data?.lookup.list_with_date == 'by-month' && getDate(index) != ''" class="w-full text-center">
        {{ getDate(index) }}
      </h4>
      <BaseListImageItem
        v-if="data?.lookup.show_image"
        :data="item"
        :lookup="data?.lookup"
        :number-overwrite="getNumber(index)"
        :allow-navigation="data.lookup.enable_detail"
      />
      <BaseListItem
        v-else-if="data?.lookup"
        :data="item"
        :lookup="data?.lookup"
        :number-overwrite="getNumber(index)"
        :allow-navigation="data.lookup.enable_detail"
      />
    </div>
  </div>
  <div
    v-if="pagination.pageCount > 1"
    class="flex flex-row w-full max-w-4xl mx-auto justify-between items-center select-none pt-4"
  >
    <p class="text-sm font-normal text-gray-500">
      Elemente <span class="font-semibold text-gray-900">{{ showingText }}</span> von
      <span class="font-semibold text-gray-900">{{ entryCount }}</span>
    </p>
    <ul class="flex flex-row text-sm h-8">
      <li
        class="flex h-8 w-8 items-center justify-center text-gray-500 bg-white border border-gray-300 first:rounded-s-lg last:rounded-e-lg"
        :class="[
          currentPage > 1 ? 'cursor-pointer hover:bg-gray-100 hover:text-gray-700' : 'opacity-50 pointer-events-none',
        ]"
        @click="changeTimedPage(currentPage - 1)"
      >
        <svg viewBox="0 0 24 24" class="h-5 w-4 cursor-pointer fill-none stroke-2 stroke-black">
          <path stroke-linecap="round" stroke-linejoin="round" d="M15.75 19.5 8.25 12l7.5-7.5" />
        </svg>
      </li>
      <li
        v-for="page in displayedPagesNumbers"
        :key="page"
        class="flex h-8 w-8 items-center justify-center text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700 first:rounded-s-lg last:rounded-e-lg"
        :class="[currentPage - 1 == page ? 'font-bold border-primary' : '', page != '.' ? ' cursor-pointer' : '']"
        @click="changeTimedPage(page)"
      >
        {{ typeof page == "number" ? page + 1 : "..." }}
      </li>
      <li
        class="flex h-8 w-8 items-center justify-center text-gray-500 bg-white border border-gray-300 first:rounded-s-lg last:rounded-e-lg"
        :class="[
          currentPage < pagination.pageCount
            ? 'cursor-pointer hover:bg-gray-100 hover:text-gray-700'
            : 'opacity-50 pointer-events-none',
        ]"
        @click="changeTimedPage(currentPage + 1)"
      >
        <svg viewBox="0 0 24 24" class="h-4 w-4 cursor-pointer fill-none stroke-2 stroke-black">
          <path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
        </svg>
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import type { PropType } from "vue";
import type SharedList from "~~/types/component/shared/list";
import type BaseCollection from "~~/types/collection/baseCollection";

interface Meta {
  page: number;
  pageSize: number;
  pageCount: number;
  total: number;
}

const runtimeConfig = useRuntimeConfig();
const baseUrl = runtimeConfig.public.strapi.url;
const { find } = useStrapi();

const props = defineProps({
  data: Object as PropType<SharedList>,
});
const collection = ref<Array<BaseCollection> | undefined>();
const years = ref<Array<number>>([]);
const pagination = ref<Meta>({ page: 0, pageSize: 0, pageCount: 0, total: 0 });
const activeYear = ref<number>(0);

if (props.data?.lookup.list_with_date != "none") {
  const { data: year } = await useAsyncData<Array<number>>(
    "range" + (props.data?.lookup.documentId ?? ""),
    () => $fetch(`${baseUrl}/api/custom/${props.data?.lookup.collection}/distinct-years`),
    {
      watch: [() => props.data],
    }
  );
  years.value = year.value ?? [];
  activeYear.value = years.value[0] ?? 0;
}
const { data: collections } = await useAsyncData(
  props.data?.lookup.documentId ?? "",
  () =>
    find<BaseCollection>(props.data?.lookup.collection ?? "", {
      ...(props.data?.lookup?.list_with_date != "none"
        ? {
            sort: "date:desc",
            filters: {
              date: {
                //@ts-ignore
                $between: [`${activeYear.value}-01-01 00:00:00.000000`, `${activeYear.value}-12-31 23:59:59.999`],
              },
            },
            pagination: {
              page: 1,
              pageSize: 10,
              withCount: true,
            },
          }
        : {
            pagination: {
              page: 1,
              pageSize: 10,
              withCount: true,
            },
          }),
    }),
  {
    watch: [() => props.data],
  }
);
collection.value = collections.value?.data;
pagination.value = (collections.value?.meta.pagination as unknown as {
  page: number;
  pageSize: number;
  pageCount: number;
  total: number;
}) ?? {
  page: 0,
  pageSize: 0,
  pageCount: 0,
  total: 0,
};

const numberOffset = computed(() => {
  return (pagination.value.page - 1) * pagination.value.pageSize;
});

const allowRight = computed<number | undefined>(() => {
  return years.value.filter((y) => y < activeYear.value).sort((a, b) => b - a)[0];
});
const allowLeft = computed(() => {
  return years.value.filter((y) => y > activeYear.value).sort((a, b) => a - b)[0];
});

const currentPage = computed(() => pagination.value.page);
const entryCount = computed(() => pagination.value.total);
const showingStart = computed(() => (currentPage.value - 1) * pagination.value.pageSize);
const showingEnd = computed(() => {
  let max = (currentPage.value - 1) * pagination.value.pageSize + pagination.value.pageSize;
  if (max > entryCount.value) max = entryCount.value;
  return max;
});
const showingText = computed(() => `${entryCount.value != 0 ? showingStart.value + 1 : 0} - ${showingEnd.value}`);
const displayedPagesNumbers = computed(() => {
  let stateOfPush = false;

  return [...new Array(pagination.value.pageCount)].reduce((acc, curr, index) => {
    if (
      index <= 1 ||
      index >= pagination.value.pageCount - 2 ||
      (currentPage.value - 1 <= index && index <= currentPage.value + 1)
    ) {
      acc.push(index);
      stateOfPush = false;
      return acc;
    }
    if (stateOfPush == true) return acc;
    acc.push(".");
    stateOfPush = true;

    return acc;
  }, []);
});

function getNumber(index: number): number {
  if (props.data?.lookup.items_with_number == "inverted") {
    return pagination.value.total - numberOffset.value - index;
  } else {
    return numberOffset.value + index + 1;
  }
}

function getDate(index: number): string {
  let thisElement = collection.value?.[index];
  let beforeElement = collection.value?.[index - 1];

  if (thisElement && beforeElement) {
    let thisElementDate = new Date(thisElement.date ?? "").toLocaleDateString("de", { month: "long" });
    let beforeElementDate = new Date(beforeElement.date ?? "").toLocaleDateString("de", { month: "long" });
    if (thisElementDate == beforeElementDate) return "";
    else return thisElementDate;
  } else if (thisElement) {
    return new Date(thisElement.date ?? "").toLocaleDateString("de", { month: "long" });
  } else return "";
}

async function changeTimedData(year: number) {
  activeYear.value = year;
  const data = await find<BaseCollection>(props.data?.lookup.collection ?? "", {
    sort: "date:desc",
    filters: {
      date: {
        // @ts-ignore
        $between: [`${activeYear.value}-01-01 00:00:00.000000`, `${activeYear.value}-12-31 23:59:59.999`],
      },
    },
    pagination: {
      page: 1,
      pageSize: 10,
      withCount: true,
    },
  });

  collection.value = data?.data;
  pagination.value = (data?.meta.pagination as unknown as {
    page: number;
    pageSize: number;
    pageCount: number;
    total: number;
  }) ?? {
    page: 0,
    pageSize: 0,
    pageCount: 0,
    total: 0,
  };
}
async function changeTimedPage(page: number = 1) {
  const data = await find<BaseCollection>(props.data?.lookup.collection ?? "", {
    sort: "date:desc",
    filters: {
      date: {
        // @ts-ignore
        $between: [`${activeYear.value}-01-01 00:00:00.000000`, `${activeYear.value}-12-31 23:59:59.999`],
      },
    },
    pagination: {
      page,
      pageSize: 10,
      withCount: true,
    },
  });

  collection.value = data?.data;
  pagination.value = (data?.meta.pagination as unknown as {
    page: number;
    pageSize: number;
    pageCount: number;
    total: number;
  }) ?? {
    page: 0,
    pageSize: 0,
    pageCount: 0,
    total: 0,
  };
}
</script>
