<script setup lang="ts">
import { router, usePage } from '@inertiajs/vue3';
import {
    AlertTriangle,
    Bell,
    FileUp,
    Mail,
    RefreshCw,
    Send,
} from 'lucide-vue-next';
import { computed } from 'vue';
import { Button } from '@/components/ui/button';
import {
    DropdownMenu,
    DropdownMenuContent,
    DropdownMenuItem,
    DropdownMenuLabel,
    DropdownMenuSeparator,
    DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import type { NotificationType } from '@/types/notification';

type NotificationItem = {
    id: string;
    type: string;
    data: {
        notification_type?: NotificationType;
        declaration_id?: number;
        declaration_title?: string;
        sender_name?: string;
        url?: string;
    };
    read_at: string | null;
    created_at: string;
};

type UserNotifications = {
    unread_count: number;
    readUrl: string | null;
    readAllUrl: string | null;
    notificationsUrl: string | null;
    items: NotificationItem[] | undefined;
};

const iconMap: Record<NotificationType, typeof Send> = {
    nudge: Send,
    declaration_overdue: AlertTriangle,
    document_uploaded: FileUp,
    bulk_notification: Mail,
    status_changed: RefreshCw,
};

const page = usePage();

const userNotifications = computed<UserNotifications>(() => {
    return (page.props as Record<string, unknown>)
        .userNotifications as UserNotifications;
});

const unreadCount = computed(() => userNotifications.value?.unread_count ?? 0);
const items = computed(() => userNotifications.value?.items ?? []);
const isLoading = computed(() => userNotifications.value?.items === undefined);

function getIcon(notificationType?: NotificationType) {
    if (!notificationType) return Bell;
    return iconMap[notificationType] ?? Bell;
}

function getDescription(notification: NotificationItem): string {
    const type = notification.data?.notification_type;
    const title = notification.data?.declaration_title ?? 'Déclaration';
    const sender = notification.data?.sender_name;

    switch (type) {
        case 'nudge':
            return sender
                ? `Notification de ${sender} sur ${title}`
                : `Notification sur ${title}`;
        case 'declaration_overdue':
            return `Déclaration en retard : ${title}`;
        case 'document_uploaded':
            return `Document téléversé pour ${title}`;
        case 'status_changed':
            return `Statut modifié : ${title}`;
        case 'bulk_notification':
            return `Notification groupée : ${title}`;
        default:
            return title;
    }
}

function markAsRead(notification: NotificationItem) {
    const readUrl = userNotifications.value?.readUrl;
    if (!readUrl) return;

    const url = readUrl.replace('__ID__', notification.id);
    router.post(url, {}, { preserveScroll: true });
}

function navigateToNotification(notification: NotificationItem) {
    const targetUrl = notification.data?.url;

    if (!notification.read_at) {
        const readUrl = userNotifications.value?.readUrl;
        if (readUrl) {
            const url = readUrl.replace('__ID__', notification.id);
            router.post(url, {}, {
                preserveScroll: true,
                onSuccess: () => {
                    if (targetUrl) {
                        router.visit(targetUrl);
                    }
                },
            });
            return;
        }
    }

    if (targetUrl) {
        router.visit(targetUrl);
    }
}

function markAllAsRead() {
    const readAllUrl = userNotifications.value?.readAllUrl;
    if (!readAllUrl) return;

    router.post(readAllUrl, {}, { preserveScroll: true });
}

function navigateToAll() {
    const url = userNotifications.value?.notificationsUrl;
    if (url) {
        router.visit(url);
    }
}
</script>

<template>
    <DropdownMenu>
        <DropdownMenuTrigger as-child>
            <Button variant="ghost" size="icon" class="relative">
                <Bell class="size-4" />
                <span
                    v-if="unreadCount > 0"
                    class="absolute -top-0.5 -right-0.5 flex size-4 items-center justify-center rounded-full bg-destructive text-[10px] font-bold text-destructive-foreground"
                >
                    {{ unreadCount > 9 ? '9+' : unreadCount }}
                </span>
            </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end" class="w-80">
            <div class="flex items-center justify-between px-2 py-1.5">
                <DropdownMenuLabel class="p-0">
                    Notifications
                </DropdownMenuLabel>
                <button
                    v-if="unreadCount > 0"
                    class="text-xs text-muted-foreground hover:text-foreground"
                    @click.stop="markAllAsRead"
                >
                    Tout marquer comme lu
                </button>
            </div>
            <DropdownMenuSeparator />

            <div
                v-if="isLoading"
                class="px-2 py-4 text-center text-sm text-muted-foreground"
            >
                Chargement...
            </div>

            <div
                v-else-if="!items.length"
                class="flex flex-col items-center gap-2 px-2 py-6 text-center text-sm text-muted-foreground"
            >
                <Bell class="size-8 text-muted-foreground/50" />
                Aucune notification
            </div>

            <template v-else>
                <DropdownMenuItem
                    v-for="notification in items"
                    :key="notification.id"
                    class="flex cursor-pointer items-start gap-3 p-3"
                    :class="{
                        'bg-muted/50': !notification.read_at,
                        'opacity-60': notification.read_at,
                    }"
                    @click="navigateToNotification(notification)"
                >
                    <component
                        :is="getIcon(notification.data?.notification_type)"
                        class="mt-0.5 size-4 shrink-0 text-muted-foreground"
                    />
                    <div class="flex-1 space-y-1">
                        <p class="text-xs leading-snug">
                            {{ getDescription(notification) }}
                        </p>
                        <p class="text-xs text-muted-foreground">
                            {{ notification.created_at }}
                        </p>
                    </div>
                    <span
                        v-if="!notification.read_at"
                        class="mt-1 size-2 shrink-0 rounded-full bg-primary"
                    />
                </DropdownMenuItem>

            </template>

            <DropdownMenuSeparator v-if="!isLoading" />
            <DropdownMenuItem
                v-if="!isLoading"
                class="justify-center text-xs text-muted-foreground"
                @click="navigateToAll"
            >
                Voir toutes les notifications
            </DropdownMenuItem>
        </DropdownMenuContent>
    </DropdownMenu>
</template>
