<template>
  <div class="collections">
    <img
      class="collections-banner"
      tabindex="0"
      aria-description="You've reached the banner area of the Collections section; this section has one image; please use the tab key to go through the content."
      :src="bannerUrl"
    />

    <div class="container">
      <Breadcrumb
        :parents="[
          {
            label: 'Collections',
            routeParams: {
              name: 'Collections',
              params: { type: NAV_LIST[0].type },
            },
          },
        ]"
        :cur-route="curRoute"
      />

      <div class="collections-main">
        <Menu />

        <div
          v-loading="loading"
          element-loading-background="rgba(122, 122, 122, 0.8)"
          class="collections-main__right"
        >
          <Waterfall :list="list" :gutter="30" :hasAroundGutter="false">
            <template #item="{ item, url }">
              <div
                class="collections-item"
                aria-label="Link"
                @click="handleItemClick(item)"
              >
                <img
                  alt=""
                  :src="url"
                  aria-label="Image link"
                  :style="{ height: item.imgHeight + 'px' }"
                />
                <div class="collections-item__inner">
                  <p tabindex="0" :aria-description="item.name">
                    {{ item.name }}
                  </p>
                  <p tabindex="0" :aria-description="item.digest">
                    {{ item.digest }}
                  </p>
                </div>
              </div>
            </template>
          </Waterfall>

          <p v-if="noData" class="no-more">no more</p>

          <div v-if="rendering && pageNum > 1" style="text-align: center">
            <VanLoading color="var(--van-primary-color)" />
          </div>
        </div>
      </div>
    </div>
  </div>

  <DetailDialog v-model:visible="visible" :id="checkedItemId" />
</template>

<script lang="ts" setup>
import { Waterfall } from "vue-waterfall-plugin-next";
import { useRoute } from "vue-router";
import { computed, onBeforeUnmount, onMounted, ref, watch } from "vue";
import { getBaseURL } from "@dage/service";
import { useBaseStore } from "@/stores/base";
import Breadcrumb from "@/components/Breadcrumb/index.vue";
import { getCollectionListApi, type CollectionListItem } from "@/api";
import Menu from "./components/Menu.vue";
import DetailDialog from "./components/DetailDialog/index.vue";
import { NAV_LIST } from "./constants";
import "vue-waterfall-plugin-next/dist/style.css";
import { PaginationType, usePagination } from "@/utils/usePagination";

const baseUrl = getBaseURL();
const baseStore = useBaseStore();
const bannerUrl = computed(() => {
  return (
    baseUrl +
    baseStore.bannerList.find((i) => i.name === "Collections")?.thumbPc
  );
});
const route = useRoute();
const curRoute = computed(() =>
  NAV_LIST.find((i) => i.type === (route.params.type as string))
);
const visible = ref(false);
const checkedItemId = ref<number | null>(null);
// 当前页图片数据是否全部加载完成
const rendering = ref(false);
const list = ref<any[]>([]);
const loading = computed(
  () => (rendering.value || fetchLoading.value) && pageNum.value === 1
);

const {
  pageNum,
  list: sourceList,
  noData,
  noMore,
  loading: fetchLoading,
  resetParams,
  getList,
} = usePagination<CollectionListItem>(
  (params) => {
    return getCollectionListApi({
      type: curRoute.value?.name,
      ...params,
    });
  },
  PaginationType.DEFAULT,
  20
);

const handleItemClick = (item: any) => {
  checkedItemId.value = item.id;
  visible.value = true;
};

const getImgRatio: (url: string) => Promise<number> = (url: string) => {
  return new Promise((res) => {
    const img = new Image();
    img.src = url;
    img.onload = () => {
      const ratio = Math.round((img.height / img.width) * 100) / 100;
      res(ratio);
    };
    img.onerror = () => {
      res(0);
    };
  });
};

const handleScroll = () => {
  // 检查用户是否滚动到页面底部
  if (
    window.innerHeight + window.scrollY >= document.body.offsetHeight &&
    !rendering.value &&
    !loading.value &&
    !noMore.value
  ) {
    console.log("Scrolled to bottom");
    pageNum.value += 1;
    getList();
  }
};

onMounted(() => {
  window.addEventListener("scroll", handleScroll);
});

onBeforeUnmount(() => {
  window.removeEventListener("scroll", handleScroll);
});

watch(sourceList, async (v) => {
  if (!v.length) return;

  rendering.value = true;

  try {
    for (const i of v) {
      const url = baseUrl + i.thumb;
      const ratio = await getImgRatio(url);

      list.value.push({
        ...i,
        imgHeight: 303 * ratio,
        src: url,
      });
    }
  } finally {
    rendering.value = false;
  }
});

watch(
  route,
  () => {
    if (route.name !== "Collections") return;

    list.value = [];
    resetParams();
    getList();
  },
  {
    immediate: true,
  }
);
</script>

<style lang="scss" scoped>
@import "./index.scss";
</style>
