import React from 'react';
import { useNavigate } from 'react-router-dom';
import { AlertTriangle, Bell, CheckCircle2, Clock, Plus } from 'lucide-react';
import { useTranslation } from 'react-i18next';

import { Button } from '@/components/ui/button';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuTrigger,
  DropdownMenuSeparator,
} from '@/components/ui/dropdown-menu';
import { Badge } from '@/components/ui/badge';
import { Skeleton } from '@/components/ui/skeleton';

import { getDashboardSummary, getEvents, type DashboardSummary, type TenantEvent } from '../api';
import { ADMIN_EVENT_CREATE_PATH, ADMIN_EVENT_VIEW_PATH, ADMIN_EVENTS_PATH } from '../constants';
import { isAuthError } from '../auth/tokens';

export type NotificationTone = 'info' | 'warning' | 'success';

interface TenantNotification {
  id: string;
  title: string;
  description?: string;
  tone: NotificationTone;
  action?: {
    label: string;
    onSelect: () => void;
  };
}

export function NotificationCenter() {
  const navigate = useNavigate();
  const { t } = useTranslation('dashboard');
  const [open, setOpen] = React.useState(false);
  const [loading, setLoading] = React.useState(true);
  const [notifications, setNotifications] = React.useState<TenantNotification[]>([]);
  const [dismissed, setDismissed] = React.useState<Set<string>>(new Set());

  const visibleNotifications = React.useMemo(
    () => notifications.filter((notification) => !dismissed.has(notification.id)),
    [notifications, dismissed]
  );

  const unreadCount = visibleNotifications.length;

  const refresh = React.useCallback(async () => {
    setLoading(true);

    try {
      const [events, summary] = await Promise.all([
        getEvents().catch(() => [] as TenantEvent[]),
        getDashboardSummary().catch(() => null as DashboardSummary | null),
      ]);

      setNotifications(buildNotifications({
        events,
        summary,
        navigate,
        t,
      }));
    } catch (error) {
      if (!isAuthError(error)) {
        console.error('[NotificationCenter] Failed to load data', error);
      }
    } finally {
      setLoading(false);
    }
  }, [navigate, t]);

  React.useEffect(() => {
    refresh();
  }, [refresh]);

  const handleDismiss = React.useCallback((id: string) => {
    setDismissed((prev) => {
      const next = new Set(prev);
      next.add(id);
      return next;
    });
  }, []);

  const iconForTone: Record<NotificationTone, React.ReactNode> = React.useMemo(
    () => ({
      info: <Clock className="h-4 w-4 text-slate-400" />,
      warning: <AlertTriangle className="h-4 w-4 text-amber-500" />,
      success: <CheckCircle2 className="h-4 w-4 text-emerald-500" />,
    }),
    []
  );

  return (
    <DropdownMenu open={open} onOpenChange={(next) => {
      setOpen(next);
      if (next) {
        refresh();
      }
    }}>
      <DropdownMenuTrigger asChild>
        <Button
          variant="ghost"
          size="icon"
          className="relative rounded-full border border-transparent text-slate-600 hover:text-rose-600 dark:text-slate-200"
          aria-label={t('notifications.trigger', { defaultValue: 'Benachrichtigungen' })}
        >
          <Bell className="h-5 w-5" />
          {unreadCount > 0 ? (
            <Badge className="absolute -right-1 -top-1 rounded-full bg-rose-600 px-1.5 text-[10px] font-semibold text-white">
              {unreadCount}
            </Badge>
          ) : null}
        </Button>
      </DropdownMenuTrigger>
      <DropdownMenuContent align="end" className="w-80 space-y-1 p-0">
        <DropdownMenuLabel className="flex items-center justify-between py-2">
          <span>{t('notifications.title', { defaultValue: 'Notifications' })}</span>
          {!loading && unreadCount === 0 ? (
            <Badge variant="outline">{t('notifications.empty', { defaultValue: 'Aktuell ruhig' })}</Badge>
          ) : null}
        </DropdownMenuLabel>
        <DropdownMenuSeparator />
        {loading ? (
          <div className="space-y-2 p-3">
            <Skeleton className="h-12 w-full rounded-xl" />
            <Skeleton className="h-12 w-full rounded-xl" />
          </div>
        ) : (
          <div className="max-h-80 space-y-1 overflow-y-auto p-1">
            {visibleNotifications.length === 0 ? (
              <p className="px-3 py-4 text-sm text-slate-500">
                {t('notifications.empty.message', { defaultValue: 'Alles erledigt – wir melden uns bei Neuigkeiten.' })}
              </p>
            ) : (
              visibleNotifications.map((item) => (
                <DropdownMenuItem key={item.id} className="flex flex-col gap-1 py-3" onSelect={(event) => event.preventDefault()}>
                  <div className="flex items-start gap-3">
                    <span className="mt-0.5">{iconForTone[item.tone]}</span>
                    <div className="flex-1 space-y-1">
                      <p className="text-sm font-semibold text-slate-900 dark:text-white">{item.title}</p>
                      {item.description ? (
                        <p className="text-xs text-slate-600 dark:text-slate-300">{item.description}</p>
                      ) : null}
                      <div className="flex flex-wrap gap-2 pt-1">
                        {item.action ? (
                          <Button
                            size="sm"
                            variant="outline"
                            className="h-7 rounded-full px-3 text-xs"
                            onClick={() => {
                              item.action?.onSelect();
                              setOpen(false);
                            }}
                          >
                            {item.action.label}
                          </Button>
                        ) : null}
                        <Button
                          size="sm"
                          variant="ghost"
                          className="h-7 rounded-full px-3 text-xs text-slate-500 hover:text-rose-600"
                          onClick={() => handleDismiss(item.id)}
                        >
                          {t('notifications.action.dismiss', { defaultValue: 'Ausblenden' })}
                        </Button>
                      </div>
                    </div>
                  </div>
                </DropdownMenuItem>
              ))
            )}
          </div>
        )}
        <DropdownMenuSeparator />
        <DropdownMenuItem
          className="flex items-center gap-2 text-xs"
          onClick={(event) => {
            event.preventDefault();
            setDismissed(new Set());
            refresh();
          }}
        >
          <Plus className="h-3.5 w-3.5" />
          {t('notifications.action.refresh', { defaultValue: 'Neue Hinweise laden' })}
        </DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

function buildNotifications({
  events,
  summary,
  navigate,
  t,
}: {
  events: TenantEvent[];
  summary: DashboardSummary | null;
  navigate: ReturnType<typeof useNavigate>;
  t: (key: string, options?: Record<string, unknown>) => string;
}): TenantNotification[] {
  const items: TenantNotification[] = [];
  const primary = events[0] ?? null;
  const now = Date.now();

  if (events.length === 0) {
    items.push({
      id: 'no-events',
      title: t('notifications.noEvents.title', { defaultValue: 'Legen wir los' }),
      description: t('notifications.noEvents.description', {
        defaultValue: 'Erstelle dein erstes Event, um Uploads, Aufgaben und Einladungen freizuschalten.',
      }),
      tone: 'warning',
      action: {
        label: t('notifications.noEvents.cta', { defaultValue: 'Event erstellen' }),
        onSelect: () => navigate(ADMIN_EVENT_CREATE_PATH),
      },
    });

    return items;
  }

  events.forEach((event) => {
    if (event.status !== 'published') {
      items.push({
        id: `draft-${event.id}`,
        title: t('notifications.draftEvent.title', { defaultValue: 'Event noch als Entwurf' }),
        description: t('notifications.draftEvent.description', {
          defaultValue: 'Veröffentliche das Event, um Einladungen und Galerie freizugeben.',
        }),
        tone: 'info',
        action: event.slug
          ? {
              label: t('notifications.draftEvent.cta', { defaultValue: 'Event öffnen' }),
              onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(event.slug!)),
            }
          : undefined,
      });
    }

    const eventDate = event.event_date ? new Date(event.event_date).getTime() : null;
    if (eventDate && eventDate > now) {
      const days = Math.round((eventDate - now) / (1000 * 60 * 60 * 24));
      if (days <= 7) {
        items.push({
          id: `upcoming-${event.id}`,
          title: t('notifications.upcomingEvent.title', { defaultValue: 'Event startet bald' }),
          description: t('notifications.upcomingEvent.description', {
            defaultValue: days === 0
              ? 'Heute findet ein Event statt – checke Uploads und Tasks.'
              : `Noch ${days} Tage – bereite Einladungen und Aufgaben vor.`,
          }),
          tone: 'info',
          action: event.slug
            ? {
                label: t('notifications.upcomingEvent.cta', { defaultValue: 'Zum Event' }),
                onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(event.slug!)),
              }
            : undefined,
        });
      }
    }

    const pendingUploads = Number(event.pending_photo_count ?? 0);
    if (pendingUploads > 0) {
      items.push({
        id: `pending-uploads-${event.id}`,
        title: t('notifications.pendingUploads.title', { defaultValue: 'Uploads warten auf Freigabe' }),
        description: t('notifications.pendingUploads.description', {
          defaultValue: `${pendingUploads} neue Uploads benötigen Moderation.`,
        }),
        tone: 'warning',
        action: event.slug
          ? {
              label: t('notifications.pendingUploads.cta', { defaultValue: 'Uploads öffnen' }),
              onSelect: () => navigate(`${ADMIN_EVENT_VIEW_PATH(event.slug!)}#photos`),
            }
          : undefined,
      });
    }
  });

  if ((summary?.new_photos ?? 0) > 0) {
    items.push({
      id: 'summary-new-photos',
      title: t('notifications.newPhotos.title', { defaultValue: 'Neue Fotos eingetroffen' }),
      description: t('notifications.newPhotos.description', {
        defaultValue: `${summary?.new_photos ?? 0} Uploads warten auf dich.`,
      }),
      tone: 'success',
      action: primary?.slug
        ? {
            label: t('notifications.newPhotos.cta', { defaultValue: 'Galerie öffnen' }),
            onSelect: () => navigate(ADMIN_EVENT_VIEW_PATH(primary.slug!)),
          }
        : {
            label: t('notifications.newPhotos.ctaFallback', { defaultValue: 'Events ansehen' }),
            onSelect: () => navigate(ADMIN_EVENTS_PATH),
          },
    });
  }

  return items;
}
