<template>
    <div
        ref="elRef"
        v-size="{ max: [500, 450] }"
        class="qglefbjs notification"
        :class="notification.type"
    >
        <div class="head">
            <MagAvatar
                v-if="
                    notification.type === 'Renote' ||
                    notification.type === 'Reply' ||
                    notification.type === 'Mention' ||
                    notification.type === 'Quote' ||
                    notification.type === 'PollEnd'
                "
                class="icon"
                :user="notification.note.user"
            />
            <MagAvatar
                v-else-if="
                    notification.type === 'Reaction' ||
                    notification.type === 'FollowRequestAccepted' ||
                    notification.type === 'Follow' ||
                    notification.type === 'FollowRequestReceived'
                "
                class="icon"
                :user="notification.user"
            />
            <img
                v-else-if="notification.icon"
                class="icon"
                :src="notification.icon"
                alt=""
            />
            <div class="sub-icon" :class="notification.type">
                <i
                    v-if="notification.type === 'Follow'"
                    class="ph-hand-waving ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'FollowRequestReceived'"
                    class="ph-clock ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'FollowRequestAccepted'"
                    class="ph-check ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'Renote'"
                    class="ph-repeat ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'Reply'"
                    class="ph-arrow-bend-up-left ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'Mention'"
                    class="ph-at ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'Quote'"
                    class="ph-quotes ph-bold"
                ></i>
                <i
                    v-else-if="notification.type === 'PollEnd'"
                    class="ph-microphone-stage ph-bold"
                ></i>
                <!-- notification.reaction が null になることはまずないが、ここでoptional chaining使うと一部ブラウザで刺さるので念の為 -->
                <MagEmoji
                    v-else-if="
                        showEmojiReactions && notification.type === 'Reaction'
                    "
                    ref="reactionRef"
                    :emoji="notification.reaction"
                    :is-reaction="true"
                    :normal="true"
                    :no-style="true"
                />
                <MagEmoji
                    v-else-if="
                        !showEmojiReactions && notification.type === 'Reaction'
                    "
                    :emoji="defaultReaction"
                    :is-reaction="true"
                    :normal="true"
                    :no-style="true"
                />
            </div>
        </div>
        <div class="tail">
            <header>
                <span v-if="notification.type === 'PollEnd'">{{
                    i18n.ts._notification.pollEnded
                }}</span>
                <MkA
                    v-if="
                        notification.type === 'Renote' ||
                        notification.type === 'Reply' ||
                        notification.type === 'Mention' ||
                        notification.type === 'Quote' ||
                        notification.type === 'PollEnd'
                    "
                    v-user-preview="notification.note.user.id"
                    class="name"
                    :to="userPage(notification.note.user)"
                    ><MkUserName :user="notification.note.user"
                /></MkA>
                <MkA
                    v-else-if="
                        notification.type === 'Reaction' ||
                        notification.type === 'FollowRequestAccepted' ||
                        notification.type === 'Follow' ||
                        notification.type === 'FollowRequestReceived'
                    "
                    v-user-preview="notification.user.id"
                    class="name"
                    :to="userPage(notification.user)"
                    ><MkUserName :user="notification.user"
                /></MkA>
                <span v-else>{{ notification.header }}</span>
                <MkTime
                    v-if="withTime"
                    :time="notification.created_at"
                    class="time"
                />
            </header>
            <MkA
                v-if="notification.type === 'Reaction'"
                class="text"
                :to="notePage(notification.note)"
                :title="getNoteSummary(notification.note)"
            >
                <span>{{ i18n.ts._notification.reacted }}</span>
                <i class="ph-quotes ph-fill ph-lg"></i>
                <Mfm
                    :text="getNoteSummary(notification.note)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.emojis"
                />
                <i class="ph-quotes ph-fill ph-lg"></i>
            </MkA>
            <MkA
                v-if="notification.type === 'Renote'"
                class="text"
                :to="notePage(notification.note.renoted_note!)"
                :title="getNoteSummary(notification.note.renoted_note!)"
            >
                <span>{{ i18n.ts._notification.renoted }}</span>
                <i class="ph-quotes ph-fill ph-lg"></i>
                <Mfm
                    :text="getNoteSummary(notification.note.renoted_note!)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.renoted_note!.emojis"
                />
                <i class="ph-quotes ph-fill ph-lg"></i>
            </MkA>
            <MkA
                v-if="notification.type === 'Reply'"
                class="text"
                :to="notePage(notification.note)"
                :title="getNoteSummary(notification.note)"
            >
                <Mfm
                    :text="getNoteSummary(notification.note)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.emojis"
                />
            </MkA>
            <MkA
                v-if="notification.type === 'Mention'"
                class="text"
                :to="notePage(notification.note)"
                :title="getNoteSummary(notification.note)"
            >
                <Mfm
                    :text="getNoteSummary(notification.note)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.emojis"
                />
            </MkA>
            <MkA
                v-if="notification.type === 'Quote'"
                class="text"
                :to="notePage(notification.note)"
                :title="getNoteSummary(notification.note)"
            >
                <Mfm
                    :text="getNoteSummary(notification.note)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.emojis"
                />
            </MkA>
            <MkA
                v-if="notification.type === 'PollEnd'"
                class="text"
                :to="notePage(notification.note)"
                :title="getNoteSummary(notification.note)"
            >
                <i class="ph-quotes ph-fill ph-lg"></i>
                <Mfm
                    :text="getNoteSummary(notification.note)"
                    :plain="true"
                    :nowrap="!full"
                    :custom-emojis="notification.note.emojis"
                />
                <i class="ph-quotes ph-fill ph-lg"></i>
            </MkA>
            <span
                v-if="notification.type === 'Follow'"
                class="text"
                style="opacity: 0.7"
                >{{ i18n.ts.youGotNewFollower }}
                <div v-if="full">
                    <MkFollowButton
                        :user="notification.user"
                        :full="true"
                        :hideMenu="true"
                    />
                </div>
            </span>
            <span
                v-if="notification.type === 'FollowRequestAccepted'"
                class="text"
                style="opacity: 0.7"
                >{{ i18n.ts.followRequestAccepted }}</span
            >
            <span
                v-if="notification.type === 'FollowRequestReceived'"
                class="text"
                style="opacity: 0.7"
                >{{ i18n.ts.receiveFollowRequest }}
                <div v-if="full && !followRequestDone">
                    <MkFollowApproveButton
                        :user="notification.user"
                        @refresh="followRequestDone = true"
                    />
                </div>
            </span>
            <span v-if="notification.type === 'App'" class="text">
                <Mfm :text="notification.body" :nowrap="!full" />
            </span>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { onMounted, onUnmounted, ref, watch } from "vue";
import MkFollowButton from "@/components/MkFollowButton.vue";
import XReactionTooltip from "@/components/MkReactionTooltip.vue";
import { getNoteSummary } from "@/scripts/get-note-summary";
import { notePage } from "@/filters/note";
import { userPage } from "@/filters/user";
import * as os from "@/os";
import { stream } from "@/stream";
import { useTooltip } from "@/scripts/use-tooltip";
import { defaultStore } from "@/store";
import { instance } from "@/instance";
import MkFollowApproveButton from "@/components/MkFollowApproveButton.vue";
import { packed } from "magnetar-common";
import { i18n } from "@/i18n";

const props = withDefaults(
    defineProps<{
        notification: packed.PackNotification;
        withTime?: boolean;
        full?: boolean;
    }>(),
    {
        withTime: false,
        full: false,
    },
);

const emit = defineEmits(["refresh"]);
const elRef = ref<HTMLElement>(null);
const reactionRef = ref(null);

const showEmojiReactions =
    defaultStore.state.enableEmojiReactions ||
    defaultStore.state.showEmojisInReactionNotifications;
const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReaction)
    ? instance.defaultReaction
    : "⭐";

let readObserver: IntersectionObserver | undefined;
let connection;

onMounted(() => {
    if (!props.notification.is_read) {
        readObserver = new IntersectionObserver((entries, observer) => {
            if (!entries.some((entry) => entry.isIntersecting)) return;
            stream.send("readNotification", {
                id: props.notification.id,
            });
            observer.disconnect();
        });

        readObserver.observe(elRef.value);

        connection = stream.useChannel("main");
        connection.on("readAllNotifications", () => readObserver!.disconnect());

        watch(
            () => props.notification.is_read,
            () => {
                readObserver!.disconnect();
            },
        );
    }
});

onUnmounted(() => {
    if (readObserver) readObserver.disconnect();
    if (connection) connection.dispose();
});

const followRequestDone = ref(false);

useTooltip(reactionRef, (showing) => {
    if (props.notification.type !== "Reaction") return;

    os.popup(
        XReactionTooltip,
        {
            showing,
            reaction: props.notification.reaction,
            targetElement: reactionRef.value.$el,
        },
        {},
        "closed",
    );
});
</script>

<style lang="scss" scoped>
.qglefbjs {
    position: relative;
    box-sizing: border-box;
    padding: 24px 32px;
    font-size: 0.9em;
    overflow-wrap: break-word;
    display: flex;
    contain: content;

    &.max-width_500px {
        padding-block: 16px;
        font-size: 0.9em;
    }
    &.max-width_450px {
        padding: 12px 16px;
    }

    > .head {
        position: sticky;
        top: 0;
        flex-shrink: 0;
        width: 42px;
        height: 42px;
        margin-right: 8px;

        > .icon {
            display: block;
            width: 100%;
            height: 100%;
            border-radius: 6px;
        }

        > .sub-icon {
            position: absolute;
            z-index: 1;
            bottom: -2px;
            right: -2px;
            width: 20px;
            height: 20px;
            box-sizing: border-box;
            border-radius: 100%;
            background: var(--panel);
            box-shadow: 0 0 0 3px var(--panel);
            font-size: 12px;
            text-align: center;

            &:empty {
                display: none;
            }

            > * {
                color: #fff;
                width: 100%;
                height: 100%;
            }

            &.Follow,
            &.FollowRequestAccepted,
            &.FollowRequestReceived {
                padding: 3px;
                background: #31748f;
                pointer-events: none;
            }

            &.Renote {
                padding: 3px;
                background: #31748f;
                pointer-events: none;
            }

            &.Quote {
                padding: 3px;
                background: #31748f;
                pointer-events: none;
            }

            &.Reply {
                padding: 3px;
                background: #c4a7e7;
                pointer-events: none;
            }

            &.Mention {
                padding: 3px;
                background: #908caa;
                pointer-events: none;
            }

            &.PollEnd {
                padding: 3px;
                background: #908caa;
                pointer-events: none;
            }
        }
    }

    > .tail {
        flex: 1;
        min-width: 0;

        > header {
            display: flex;
            align-items: baseline;
            white-space: nowrap;

            > .name {
                text-overflow: ellipsis;
                white-space: nowrap;
                min-width: 0;
                overflow: hidden;
            }

            > .time {
                margin-left: auto;
                font-size: 0.9em;
            }
        }

        > .text {
            white-space: nowrap;
            display: -webkit-box;
            -webkit-line-clamp: 3;
            -webkit-box-orient: vertical;
            overflow: hidden;
            text-overflow: ellipsis;

            > span:first-child {
                opacity: 0.7;
                &::after {
                    content: ": ";
                }
            }

            > i {
                vertical-align: super;
                font-size: 50%;
                opacity: 0.5;
            }

            > i:first-child {
                margin-right: 4px;
            }

            > i:last-child {
                margin-left: 4px;
            }
        }
    }
}
</style>
