<template>
	<MkStickyContainer>
		<template #header>
			<MkPageHeader
				v-model:tab="tab"
				:actions="headerActions"
				:tabs="headerTabs"
				:display-my-avatar="true"
			/>
		</template>
		<MkSpacer :content-max="800">
			<swiper
				:round-lengths="true"
				:touch-angle="25"
				:threshold="10"
				:centered-slides="true"
				:modules="[Virtual]"
				:space-between="20"
				:virtual="true"
				:allow-touch-move="
					defaultStore.state.swipeOnMobile &&
					(deviceKind !== 'desktop' ||
						defaultStore.state.swipeOnDesktop)
				"
				@swiper="setSwiperRef"
				@slide-change="onSlideChange"
			>
				<swiper-slide>
					<XNotifications
						:key="'tab1'"
						class="notifications"
						:include-types="includeTypes"
						:unread-only="false"
					/>
				</swiper-slide>
				<swiper-slide>
					<XNotifications
						v-if="tab === 'reactions'"
						:key="'tab2'"
						class="notifications"
						:include-types="['reaction']"
						:unread-only="false"
					/>
				</swiper-slide>
				<swiper-slide>
					<XNotes v-if="tab === 'mentions'" :key="'tab3'" :pagination="mentionsPagination" />
				</swiper-slide>
				<swiper-slide>
					<XNotes v-if="tab === 'directNotes'" :key="'tab4'" :pagination="directNotesPagination" />
				</swiper-slide>
			</swiper>
		</MkSpacer>
	</MkStickyContainer>
</template>

<script lang="ts" setup>
import { computed, ref, watch } from "vue";
import { Virtual } from "swiper/modules";
import { Swiper, SwiperSlide } from "swiper/vue";
import type { Swiper as SwiperType } from "swiper/types";
import { notificationTypes } from "firefish-js";
import XNotifications from "@/components/MkNotifications.vue";
import XNotes from "@/components/MkNotes.vue";
import * as os from "@/os";
import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata";
import { deviceKind } from "@/scripts/device-kind";
import { defaultStore } from "@/store";
import icon from "@/scripts/icon";
import "swiper/scss";
import "swiper/scss/virtual";

const tabs = ["all", "reactions", "mentions", "directNotes"];
const tab = ref(tabs[0]);
watch(tab, () => syncSlide(tabs.indexOf(tab.value)));

const includeTypes = ref<(typeof notificationTypes)[number][] | null>(null);
os.api("notifications/mark-all-as-read");

const MOBILE_THRESHOLD = 500;
const isMobile = ref(
	deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD,
);
window.addEventListener("resize", () => {
	isMobile.value =
		deviceKind === "smartphone" || window.innerWidth <= MOBILE_THRESHOLD;
});

const mentionsPagination = {
	endpoint: "notes/mentions" as const,
	limit: 10,
};

const directNotesPagination = {
	endpoint: "notes/mentions" as const,
	limit: 10,
	params: {
		visibility: "specified",
	},
};

function setFilter(ev) {
	const typeItems = notificationTypes.map((t) => ({
		text: i18n.t(`_notification._types.${t}`),
		active: includeTypes.value?.includes(t),
		action: () => {
			includeTypes.value = [t];
		},
	}));
	const items =
		includeTypes.value != null
			? [
					{
						icon: `${icon("ph-x")}`,
						text: i18n.ts.clear,
						action: () => {
							includeTypes.value = null;
						},
					},
					null,
					...typeItems,
				]
			: typeItems;
	os.popupMenu(items, ev.currentTarget ?? ev.target);
}

const headerActions = computed(() =>
	tab.value === "all"
		? [
				{
					text: i18n.ts.filter,
					icon: `${icon("ph-funnel")}`,
					highlighted: includeTypes.value != null,
					handler: setFilter,
				},
				{
					text: i18n.ts.markAllAsRead,
					icon: `${icon("ph-check")}`,
					handler: () => {
						os.apiWithDialog("notifications/mark-all-as-read");
					},
				},
			]
		: [],
);

const headerTabs = computed(() => [
	{
		key: "all",
		title: i18n.ts.all,
		icon: `${icon("ph-bell")}`,
	},
	{
		key: "reactions",
		title: i18n.ts.reaction,
		icon: `${icon("ph-smiley")}`,
	},
	{
		key: "mentions",
		title: i18n.ts.mentions,
		icon: `${icon("ph-at")}`,
	},
	{
		key: "directNotes",
		title: i18n.ts.directNotes,
		icon: `${icon("ph-envelope-simple-open")}`,
	},
]);

definePageMetadata(
	computed(() => ({
		title: i18n.ts.notifications,
		icon: `${icon("ph-bell")}`,
	})),
);

let swiperRef: SwiperType | null = null;

function setSwiperRef(swiper: SwiperType) {
	swiperRef = swiper;
	syncSlide(tabs.indexOf(tab.value));
}

function onSlideChange() {
	if (tab.value !== tabs[swiperRef!.activeIndex])
		tab.value = tabs[swiperRef!.activeIndex];
}

function syncSlide(index: number) {
	if (index !== swiperRef!.activeIndex) swiperRef!.slideTo(index);
}
</script>