<script setup lang="ts">
import { router } from '@inertiajs/vue3';
import { Bell, CheckCheck, Eye, Trash2, X } from '@lucide/vue';
import { onMounted, onUnmounted, ref } from 'vue';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
    Popover,
    PopoverContent,
    PopoverTrigger,
} from '@/components/ui/popover';
import {
    Tooltip,
    TooltipContent,
    TooltipProvider,
    TooltipTrigger,
} from '@/components/ui/tooltip';

interface NotificationItem {
    id: number;
    title: string;
    body: string | null;
    url: string | null;
    is_read: boolean;
    created_at: string;
}

const notifications = ref<NotificationItem[]>([]);
const unreadCount = ref(0);
const isOpen = ref(false);
let interval: ReturnType<typeof setInterval> | null = null;

function csrfToken(): string {
    return (
        document.querySelector('meta[name="csrf-token"]') as HTMLMetaElement
    )?.content ?? '';
}

async function fetchNotifications(): Promise<void> {
    try {
        const response = await fetch('/notifications', {
            headers: { 'X-Requested-With': 'XMLHttpRequest' },
        });

        if (response.ok) {
            const data = (await response.json()) as {
                notifications: NotificationItem[];
                unread_count: number;
            };
            notifications.value = data.notifications;
            unreadCount.value = data.unread_count;
        }
    } catch {
        // silent
    }
}

async function markAsRead(notification: NotificationItem): Promise<void> {
    if (notification.is_read) {
        return;
    }

    try {
        await fetch(`/notifications/${notification.id}/read`, {
            method: 'PATCH',
            headers: {
                'X-CSRF-TOKEN': csrfToken(),
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        notification.is_read = true;
        unreadCount.value = Math.max(0, unreadCount.value - 1);
    } catch {
        // silent
    }
}

function openNotification(notification: NotificationItem): void {
    if (!notification.is_read) {
        void markAsRead(notification);
    }

    if (notification.url) {
        isOpen.value = false;
        router.visit(notification.url);
    }
}

async function deleteNotification(id: number): Promise<void> {
    try {
        await fetch(`/notifications/${id}`, {
            method: 'DELETE',
            headers: {
                'X-CSRF-TOKEN': csrfToken(),
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        const idx = notifications.value.findIndex((n) => n.id === id);

        if (idx !== -1) {
            if (!notifications.value[idx].is_read) {
                unreadCount.value = Math.max(0, unreadCount.value - 1);
            }

            notifications.value.splice(idx, 1);
        }
    } catch {
        // silent
    }
}

async function markAllAsRead(): Promise<void> {
    try {
        await fetch('/notifications/read-all', {
            method: 'PATCH',
            headers: {
                'X-CSRF-TOKEN': csrfToken(),
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        notifications.value.forEach((n) => {
            n.is_read = true;
        });
        unreadCount.value = 0;
    } catch {
        // silent
    }
}

async function deleteAll(): Promise<void> {
    try {
        await fetch('/notifications', {
            method: 'DELETE',
            headers: {
                'X-CSRF-TOKEN': csrfToken(),
                'X-Requested-With': 'XMLHttpRequest',
            },
        });
        notifications.value = [];
        unreadCount.value = 0;
    } catch {
        // silent
    }
}

function timeAgo(dateStr: string): string {
    const now = Date.now();
    const then = new Date(dateStr).getTime();
    const seconds = Math.floor((now - then) / 1000);

    if (seconds < 60) {
        return 'Baru saja';
    }

    if (seconds < 3600) {
        return `${Math.floor(seconds / 60)}m lalu`;
    }

    if (seconds < 86400) {
        return `${Math.floor(seconds / 3600)}j lalu`;
    }

    return `${Math.floor(seconds / 86400)}h lalu`;
}

onMounted(() => {
    void fetchNotifications();
    interval = setInterval(() => void fetchNotifications(), 30000);
});

onUnmounted(() => {
    if (interval) {
        clearInterval(interval);
    }
});
</script>

<template>
    <TooltipProvider>
        <Popover v-model:open="isOpen">
            <PopoverTrigger as-child>
                <Button variant="ghost" size="icon" class="relative size-8">
                    <Bell class="size-4" />
                    <Badge v-if="unreadCount > 0" variant="destructive"
                        class="absolute -top-1 -right-1 flex size-4 items-center justify-center rounded-full p-0 text-[10px]">
                        {{ unreadCount > 99 ? '99+' : unreadCount }}
                    </Badge>
                </Button>
            </PopoverTrigger>

            <PopoverContent align="end" :side-offset="8" class="w-80 p-0">
                <!-- Header -->
                <div class="flex items-center justify-between border-b px-4 py-3">
                    <h4 class="text-sm font-semibold">Notifikasi</h4>
                    <div class="flex items-center gap-1">
                        <Tooltip v-if="unreadCount > 0">
                            <TooltipTrigger as-child>
                                <button
                                    class="flex items-center rounded p-1 text-muted-foreground hover:text-foreground"
                                    @click="markAllAsRead">
                                    <CheckCheck class="size-3.5" />
                                </button>
                            </TooltipTrigger>
                            <TooltipContent class="z-[300]">Tandai semua dibaca</TooltipContent>
                        </Tooltip>
                        <Tooltip v-if="notifications.length > 0">
                            <TooltipTrigger as-child>
                                <button
                                    class="flex items-center rounded p-1 text-muted-foreground hover:text-destructive"
                                    @click="deleteAll">
                                    <Trash2 class="size-3.5" />
                                </button>
                            </TooltipTrigger>
                            <TooltipContent class="z-[300]">Hapus semua</TooltipContent>
                        </Tooltip>
                    </div>
                </div>

                <!-- List -->
                <div class="max-h-80 overflow-y-auto">
                    <div v-if="notifications.length === 0" class="px-4 py-8 text-center text-sm text-muted-foreground">
                        Tidak ada notifikasi
                    </div>
                    <div v-for="notification in notifications" :key="notification.id"
                        class="group flex items-start gap-3 border-b px-4 py-3 transition-colors hover:bg-accent"
                        :class="{ 'bg-primary/5': !notification.is_read }">
                        <!-- Unread dot -->
                        <div class="mt-1.5 size-2 shrink-0 rounded-full"
                            :class="notification.is_read ? 'bg-transparent' : 'bg-primary'" />

                        <!-- Content -->
                        <div class="min-w-0 flex-1 cursor-pointer" @click="openNotification(notification)">
                            <p class="text-sm font-medium leading-tight">
                                {{ notification.title }}
                            </p>
                            <p v-if="notification.body"
                                class="mt-0.5 text-xs leading-snug text-muted-foreground">
                                {{ notification.body }}
                            </p>
                            <p class="mt-1 text-[10px] text-muted-foreground">
                                {{ timeAgo(notification.created_at) }}
                            </p>
                        </div>

                        <!-- Actions -->
                        <div
                            class="flex shrink-0 items-center gap-0.5 opacity-0 transition-opacity group-hover:opacity-100">
                            <Tooltip v-if="!notification.is_read">
                                <TooltipTrigger as-child>
                                    <button
                                        class="rounded p-1 text-muted-foreground hover:bg-muted hover:text-foreground"
                                        @click.stop="markAsRead(notification)">
                                        <Eye class="size-3.5" />
                                    </button>
                                </TooltipTrigger>
                                <TooltipContent class="z-[300]">Tandai dibaca</TooltipContent>
                            </Tooltip>
                            <Tooltip>
                                <TooltipTrigger as-child>
                                    <button
                                        class="rounded p-1 text-muted-foreground hover:bg-muted hover:text-destructive"
                                        @click.stop="deleteNotification(notification.id)">
                                        <X class="size-3.5" />
                                    </button>
                                </TooltipTrigger>
                                <TooltipContent class="z-[300]">Hapus</TooltipContent>
                            </Tooltip>
                        </div>
                    </div>
                </div>
            </PopoverContent>
        </Popover>
    </TooltipProvider>
</template>
