import { NotificationItem } from '@/components/admin/NotificationItem';
import { Button } from '@/components/ui/button';
import {
    Sheet,
    SheetContent,
    SheetHeader,
    SheetTitle,
} from '@/components/ui/sheet';
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs';
import type { AdminNotification } from '@/types/admin';
import { Bell, CheckCheck } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';

type Tab = 'all' | 'unread' | 'critical';

function groupByDate(
    items: AdminNotification[],
): { label: string; items: AdminNotification[] }[] {
    const today = new Date();
    today.setHours(0, 0, 0, 0);
    const yesterday = new Date(today);
    yesterday.setDate(today.getDate() - 1);
    const weekAgo = new Date(today);
    weekAgo.setDate(today.getDate() - 7);

    const groups: Record<string, AdminNotification[]> = {
        Today: [],
        Yesterday: [],
        'This Week': [],
        Earlier: [],
    };

    for (const n of items) {
        const d = new Date(n.created_at);
        d.setHours(0, 0, 0, 0);
        if (d >= today) groups['Today'].push(n);
        else if (d >= yesterday) groups['Yesterday'].push(n);
        else if (d >= weekAgo) groups['This Week'].push(n);
        else groups['Earlier'].push(n);
    }

    return Object.entries(groups)
        .filter(([, g]) => g.length > 0)
        .map(([label, items]) => ({ label, items }));
}

export function NotificationSheet({
    open,
    onOpenChange,
    onCountChange,
}: {
    open: boolean;
    onOpenChange: (v: boolean) => void;
    onCountChange: () => void;
}) {
    const [notifications, setNotifications] = useState<AdminNotification[]>([]);
    const [loading, setLoading] = useState(false);
    const [tab, setTab] = useState<Tab>('all');

    const fetchNotifications = async () => {
        setLoading(true);
        try {
            const res = await fetch('/admin/api/notifications', {
                headers: { Accept: 'application/json' },
            });
            if (res.ok) {
                const data = await res.json();
                setNotifications(data.data ?? []);
            }
        } finally {
            setLoading(false);
        }
    };

    useEffect(() => {
        if (open) fetchNotifications();
    }, [open]);

    const filtered = useMemo(() => {
        if (tab === 'unread') return notifications.filter((n) => !n.read_at);
        if (tab === 'critical')
            return notifications.filter((n) => n.data.severity === 'critical');
        return notifications;
    }, [notifications, tab]);

    const unreadCount = notifications.filter((n) => !n.read_at).length;
    const criticalCount = notifications.filter(
        (n) => n.data.severity === 'critical',
    ).length;

    const handleDismiss = async (id: string) => {
        setNotifications((prev) =>
            prev.map((n) =>
                n.id === id ? { ...n, read_at: new Date().toISOString() } : n,
            ),
        );
        onCountChange();
        await fetch(`/admin/api/notifications/${id}/read`, {
            method: 'POST',
            headers: { Accept: 'application/json', 'X-CSRF-TOKEN': getCsrf() },
        });
    };

    const handleMarkAllRead = async () => {
        setNotifications((prev) =>
            prev.map((n) => ({
                ...n,
                read_at: n.read_at ?? new Date().toISOString(),
            })),
        );
        onCountChange();
        await fetch('/admin/api/notifications/read-all', {
            method: 'POST',
            headers: { Accept: 'application/json', 'X-CSRF-TOKEN': getCsrf() },
        });
    };

    const groups = groupByDate(filtered);

    return (
        <Sheet open={open} onOpenChange={onOpenChange}>
            <SheetContent
                side="right"
                className="flex w-[400px] flex-col gap-0 p-0 sm:max-w-[400px]"
            >
                <SheetHeader className="border-border border-b px-5 py-4">
                    <div className="flex items-center justify-between">
                        <SheetTitle className="text-base font-semibold">
                            Notifications
                        </SheetTitle>
                        {unreadCount > 0 && (
                            <Button
                                variant="ghost"
                                size="sm"
                                onClick={handleMarkAllRead}
                                className="text-muted-foreground hover:text-foreground h-8 gap-1.5 text-xs"
                            >
                                <CheckCheck className="h-3.5 w-3.5" />
                                Mark all read
                            </Button>
                        )}
                    </div>

                    <Tabs value={tab} onValueChange={(v) => setTab(v as Tab)}>
                        <TabsList className="h-8 w-full">
                            <TabsTrigger value="all" className="flex-1 text-xs">
                                All
                            </TabsTrigger>
                            <TabsTrigger
                                value="unread"
                                className="flex-1 text-xs"
                            >
                                Unread {unreadCount > 0 && `(${unreadCount})`}
                            </TabsTrigger>
                            <TabsTrigger
                                value="critical"
                                className="flex-1 text-xs"
                            >
                                Critical{' '}
                                {criticalCount > 0 && `(${criticalCount})`}
                            </TabsTrigger>
                        </TabsList>
                    </Tabs>
                </SheetHeader>

                <div className="flex-1 overflow-y-auto">
                    {loading ? (
                        <div className="flex flex-col gap-2 p-4">
                            {[1, 2, 3].map((i) => (
                                <div
                                    key={i}
                                    className="bg-muted h-16 animate-pulse rounded-xl"
                                />
                            ))}
                        </div>
                    ) : groups.length === 0 ? (
                        <div className="flex flex-col items-center justify-center gap-3 py-20 text-center">
                            <div className="bg-muted flex h-12 w-12 items-center justify-center rounded-full">
                                <Bell className="text-muted-foreground h-5 w-5" />
                            </div>
                            <p className="text-muted-foreground text-sm">
                                You're all caught up
                            </p>
                        </div>
                    ) : (
                        <div className="flex flex-col gap-4 p-4">
                            {groups.map(({ label, items }) => (
                                <div key={label}>
                                    <p className="text-muted-foreground mb-2 px-1 text-[11px] font-semibold tracking-wider uppercase">
                                        {label}
                                    </p>
                                    <div className="flex flex-col gap-1.5">
                                        {items.map((n) => (
                                            <NotificationItem
                                                key={n.id}
                                                notification={n}
                                                onDismiss={handleDismiss}
                                            />
                                        ))}
                                    </div>
                                </div>
                            ))}
                        </div>
                    )}
                </div>
            </SheetContent>
        </Sheet>
    );
}

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