// @ts-nocheck
import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
  ArrowLeft,
  Bell,
  Camera,
  CheckCircle2,
  Circle,
  Clock3,
  Loader2,
  MessageSquare,
  Printer,
  QrCode,
  PlugZap,
  Smile,
  Sparkles,
  ShoppingCart,
  Menu,
  Users,
  AlertTriangle,
} from 'lucide-react';
import toast from 'react-hot-toast';

import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { AdminLayout } from '../components/AdminLayout';
import {
  EventToolkit,
  EventToolkitTask,
  TenantEmotion,
  TenantEvent,
  TenantPhoto,
  EventStats,
  getEvent,
  getEventStats,
  getEventToolkit,
  toggleEvent,
  submitTenantFeedback,
  updatePhotoVisibility,
  createEventAddonCheckout,
  featurePhoto,
  unfeaturePhoto,
  getEmotions,
} from '../api';
import { buildLimitWarnings } from '../lib/limitWarnings';
import { getApiErrorMessage } from '../lib/apiError';
import { isAuthError } from '../auth/tokens';
import {
  ADMIN_EVENTS_PATH,
  ADMIN_EVENT_EDIT_PATH,
  ADMIN_EVENT_INVITES_PATH,
  ADMIN_EVENT_MEMBERS_PATH,
  ADMIN_EVENT_PHOTOBOOTH_PATH,
  ADMIN_EVENT_PHOTOS_PATH,
  ADMIN_EVENT_TASKS_PATH,
  ADMIN_EVENT_BRANDING_PATH,
  buildEngagementTabPath,
} from '../constants';
import { buildEventTabs } from '../lib/eventTabs';
import { formatEventDate } from '../lib/events';
import {
  SectionCard,
  SectionHeader,
} from '../components/tenant';
import { AddonsPicker } from '../components/Addons/AddonsPicker';
import { AddonSummaryList } from '../components/Addons/AddonSummaryList';
import { EventAddonCatalogItem, getAddonCatalog } from '../api';
import { GuestBroadcastCard } from '../components/GuestBroadcastCard';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from '@/components/ui/sheet';
import { filterEmotionsByEventType } from '../lib/emotions';
type ToolkitState = {
  data: EventToolkit | null;
  loading: boolean;
  error: string | null;
};

type WorkspaceState = {
  event: TenantEvent | null;
  stats: EventStats | null;
  loading: boolean;
  busy: boolean;
  error: string | null;
};

export default function EventDetailPage() {
  const { slug: slugParam } = useParams<{ slug?: string }>();
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const { t } = useTranslation('management');
  const { t: tCommon } = useTranslation('common');

  const slug = slugParam ?? null;

  const [state, setState] = React.useState<WorkspaceState>({
    event: null,
    stats: null,
    loading: true,
    busy: false,
    error: null,
  });

  const [toolkit, setToolkit] = React.useState<ToolkitState>({ data: null, loading: true, error: null });
  const [addonBusyId, setAddonBusyId] = React.useState<string | null>(null);
  const [addonRefreshCount, setAddonRefreshCount] = React.useState(0);
  const [addonsCatalog, setAddonsCatalog] = React.useState<EventAddonCatalogItem[]>([]);
  const [emotions, setEmotions] = React.useState<TenantEmotion[]>([]);

  const load = React.useCallback(async () => {
    if (!slug) {
      setState({ event: null, stats: null, loading: false, busy: false, error: t('events.errors.missingSlug', 'Kein Event ausgewählt.') });
      setToolkit({ data: null, loading: false, error: null });
      return;
    }

    setState((prev) => ({ ...prev, loading: true, error: null }));
    setToolkit((prev) => ({ ...prev, loading: true, error: null }));

    try {
      const [eventData, statsData, addonOptions] = await Promise.all([getEvent(slug), getEventStats(slug), getAddonCatalog()]);
      setState((prev) => ({ ...prev, event: eventData, stats: statsData, loading: false }));
      setAddonsCatalog(addonOptions);
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          error: getApiErrorMessage(error, t('events.errors.loadFailed', 'Event konnte nicht geladen werden.')),
          loading: false,
        }));
      }
    }

    try {
      const toolkitData = await getEventToolkit(slug);
      setToolkit({ data: toolkitData, loading: false, error: null });
    } catch (error) {
      if (!isAuthError(error)) {
        setToolkit({
          data: null,
          loading: false,
          error: getApiErrorMessage(error, t('toolkit.errors.loadFailed', 'Toolkit-Daten konnten nicht geladen werden.')),
        });
      }
    }
  }, [slug, t]);

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

  React.useEffect(() => {
    let cancelled = false;
    (async () => {
      try {
        const list = await getEmotions();
        if (!cancelled) {
          setEmotions(list);
        }
      } catch (error) {
        if (!isAuthError(error)) {
          console.warn('Failed to load emotions for event detail', error);
        }
      }
    })();

    return () => {
      cancelled = true;
    };
  }, []);

  async function handleToggle(): Promise<void> {
    if (!slug) {
      return;
    }

    setState((prev) => ({ ...prev, busy: true, error: null }));

    try {
      const updated = await toggleEvent(slug);
      setState((prev) => ({
        ...prev,
        busy: false,
        event: updated,
        stats: prev.stats
          ? {
              ...prev.stats,
              status: updated.status,
              is_active: Boolean(updated.is_active),
            }
          : prev.stats,
      }));
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          busy: false,
          error: getApiErrorMessage(error, t('events.errors.toggleFailed', 'Status konnte nicht angepasst werden.')),
        }));
      } else {
        setState((prev) => ({ ...prev, busy: false }));
      }
    }
  }

  const { event, stats, loading, busy, error } = state;
  const toolkitData = toolkit.data;

  const eventName = event ? resolveName(event.name) : t('events.placeholders.untitled', 'Unbenanntes Event');
  const subtitle = t('events.workspace.detailSubtitle', 'Behalte Status, Aufgaben und QR-Codes deines Events im Blick.');
  const currentTabKey = 'overview';

  const eventTabs = React.useMemo(() => {
    if (!event) return [];
    const translateMenu = (key: string, fallback: string) => t(key, { defaultValue: fallback });
    const counts = {
      photos: stats?.uploads_total ?? event.photo_count ?? undefined,
      tasks: toolkitData?.tasks?.summary?.total ?? event.tasks_count ?? undefined,
    };
    return buildEventTabs(event, translateMenu, counts);
  }, [event, stats?.uploads_total, toolkitData?.tasks?.summary?.total, t]);

  const brandingAllowed = React.useMemo(() => {
    const settings = (event?.settings ?? {}) as Record<string, unknown>;
    return Boolean(settings.branding_allowed ?? true);
  }, [event]);

  const limitWarnings = React.useMemo(
    () => (event?.limits ? buildLimitWarnings(event.limits, (key, options) => tCommon(`limits.${key}`, options)) : []),
    [event?.limits, tCommon],
  );
  const [dismissedWarnings, setDismissedWarnings] = React.useState<Set<string>>(new Set());

  React.useEffect(() => {
    const slug = event?.slug;
    if (!slug || typeof window === 'undefined') {
      setDismissedWarnings(new Set());
      return;
    }
    try {
      const raw = window.localStorage.getItem(`tenant-admin:dismissed-limit-warnings:${slug}`);
      if (!raw) {
        setDismissedWarnings(new Set());
        return;
      }
      const parsed = JSON.parse(raw) as string[];
      setDismissedWarnings(new Set(parsed));
    } catch {
      setDismissedWarnings(new Set());
    }
  }, [event?.slug]);

  const visibleWarnings = React.useMemo(
    () => limitWarnings.filter((warning) => !dismissedWarnings.has(warning.id)),
    [limitWarnings, dismissedWarnings],
  );

  const dismissWarning = React.useCallback(
    (id: string) => {
      const slug = event?.slug;
      setDismissedWarnings((prev) => {
        const next = new Set(prev);
        next.add(id);
        if (slug && typeof window !== 'undefined') {
          window.localStorage.setItem(
            `tenant-admin:dismissed-limit-warnings:${slug}`,
            JSON.stringify(Array.from(next)),
          );
        }
        return next;
      });
    },
    [event?.slug],
  );

const shownWarningToasts = React.useRef<Set<string>>(new Set());
  //const [addonBusyId, setAddonBusyId] = React.useState<string | null>(null);

  const handleAddonPurchase = React.useCallback(
    async (scope: 'photos' | 'guests' | 'gallery', addonKeyOverride?: string) => {
      if (!slug) return;

      const defaultAddons: Record<typeof scope, string> = {
        photos: 'extra_photos_500',
        guests: 'extra_guests_100',
        gallery: 'extend_gallery_30d',
      };

      const addonKey = addonKeyOverride ?? defaultAddons[scope];
      setAddonBusyId(scope);
      try {
        const currentUrl = window.location.origin + window.location.pathname;
        const successUrl = `${currentUrl}?addon_success=1`;
        const checkout = await createEventAddonCheckout(slug, {
          addon_key: addonKey,
          quantity: 1,
          success_url: successUrl,
          cancel_url: currentUrl,
        });
        if (checkout.checkout_url) {
          window.location.href = checkout.checkout_url;
        } else {
          toast(t('events.errors.checkoutMissing', 'Checkout konnte nicht gestartet werden.'));
        }
      } catch (err) {
        toast(getApiErrorMessage(err, t('events.errors.checkoutFailed', 'Add-on Checkout fehlgeschlagen.')));
      } finally {
        setAddonBusyId(null);
      }
    },
    [slug, t],
  );

  React.useEffect(() => {
    limitWarnings.forEach((warning) => {
      const id = `${warning.id}-${warning.message}`;
      if (shownWarningToasts.current.has(id)) {
        return;
      }

      shownWarningToasts.current.add(id);
      toast(warning.message, {
        icon: warning.tone === 'danger' ? '🚨' : '⚠️',
        id,
      });
    });
  }, [limitWarnings]);

  React.useEffect(() => {
    const success = searchParams.get('addon_success');
    if (success && slug) {
      toast(t('events.success.addonApplied', 'Add-on angewendet. Limits aktualisieren sich in Kürze.'));
      void load();
      setAddonRefreshCount(3);
      const params = new URLSearchParams(window.location.search);
      params.delete('addon_success');
      const search = params.toString();
      navigate(search ? `${window.location.pathname}?${search}` : window.location.pathname, { replace: true });
    }
  }, [searchParams, slug, load, navigate, t]);

  React.useEffect(() => {
    if (addonRefreshCount <= 0) {
      return;
    }
    const timer = setTimeout(() => {
      void load();
      setAddonRefreshCount((count) => count - 1);
    }, 8000);
    return () => clearTimeout(timer);
  }, [addonRefreshCount, load]);

  if (!slug) {
    return (
      <AdminLayout
        title={t('events.errors.notFoundTitle', 'Event nicht gefunden')}
        subtitle={t('events.errors.notFoundCopy', 'Bitte wähle ein Event aus der Übersicht.')}
      >
        <SectionCard>
          <p className="text-sm text-slate-600 dark:text-slate-300">
            {t('events.errors.notFoundBody', 'Ohne gültige Kennung können wir keine Daten laden. Kehre zur Eventliste zurück und wähle dort ein Event aus.')}
          </p>
        </SectionCard>
      </AdminLayout>
    );
  }

  return (
    <AdminLayout
      title={eventName}
      subtitle={subtitle}
      tabs={eventTabs}
      currentTabKey={currentTabKey}
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>{t('events.alerts.failedTitle', 'Aktion fehlgeschlagen')}</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {visibleWarnings.length > 0 && (
        <div className="mb-6 space-y-2">
          {visibleWarnings.map((warning) => (
            <Alert
              key={warning.id}
              variant={warning.tone === 'danger' ? 'destructive' : 'default'}
              className={warning.tone === 'warning' ? 'border-amber-400/40 bg-amber-50 text-amber-900' : undefined}
            >
              <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
                <AlertDescription className="flex items-center gap-2 text-sm">
                  <AlertTriangle className="h-4 w-4" />
                  {warning.message}
                </AlertDescription>
                <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:gap-3">
                  {(['photos', 'guests', 'gallery'] as const).includes(warning.scope) ? (
                    <>
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => { void handleAddonPurchase(warning.scope as 'photos' | 'guests' | 'gallery'); }}
                        disabled={addonBusyId === warning.scope}
                        className="justify-start"
                      >
                        <ShoppingCart className="mr-2 h-4 w-4" />
                        {warning.scope === 'photos'
                          ? t('events.actions.buyMorePhotos', 'Mehr Fotos freischalten')
                          : warning.scope === 'guests'
                            ? t('events.actions.buyMoreGuests', 'Mehr Gäste freischalten')
                            : t('events.actions.extendGallery', 'Galerie verlängern')}
                      </Button>
                      {addonsCatalog.length > 0 ? (
                        <AddonsPicker
                          addons={addonsCatalog}
                          scope={warning.scope as 'photos' | 'guests' | 'gallery'}
                          onCheckout={(key) => { void handleAddonPurchase(warning.scope as 'photos' | 'guests' | 'gallery', key); }}
                          busy={addonBusyId === warning.scope}
                          t={(key, fallback) => t(key, fallback)}
                        />
                      ) : null}
                    </>
                  ) : null}
                  <Button
                    variant="ghost"
                    size="sm"
                    onClick={() => dismissWarning(warning.id)}
                    className="justify-start text-slate-600 hover:text-slate-900"
                  >
                    {tCommon('actions.dismiss', 'Hinweis ausblenden')}
                  </Button>
                </div>
              </div>
            </Alert>
          ))}
        </div>
      )}

      {toolkit.error && (
        <Alert variant="default">
          <AlertTitle>{toolkit.error}</AlertTitle>
        </Alert>
      )}

      {loading ? (
        <WorkspaceSkeleton />
      ) : event ? (
        <div className="space-y-6">
          <div className="space-y-6">
            <div className="flex flex-wrap items-center justify-between gap-3 rounded-3xl border border-slate-200 bg-white/85 p-4 shadow-sm dark:border-white/10 dark:bg-white/5">
              <div className="space-y-2">
                <p className="text-[10px] font-semibold uppercase tracking-[0.35em] text-rose-500 dark:text-rose-200">
                  {t('events.workspace.hero.badge', 'Event')}
                </p>
                <h1 className="text-xl font-semibold text-slate-900 dark:text-white">{resolveName(event.name)}</h1>
                <p className="text-sm text-slate-600 dark:text-slate-300">
                  {t('events.workspace.hero.description', 'Konzentriere dich auf Aufgaben, Moderation und QR-Code für dieses Event.')}
                </p>
                <div className="flex flex-wrap gap-2 text-xs">
                  <Badge variant="secondary" className="gap-1 rounded-full bg-emerald-100 text-emerald-800 dark:bg-emerald-500/20 dark:text-emerald-100">
                    <Sparkles className="h-3.5 w-3.5" />
                    {getStatusLabel(event, t)}
                  </Badge>
                  <Badge variant="outline" className="gap-1 rounded-full border-slate-200 text-slate-700 dark:border-white/10 dark:text-white">
                    <CalendarIcon />
                    {formatDate(event.event_date)}
                  </Badge>
                  <Badge variant="outline" className="gap-1 rounded-full border-slate-200 text-slate-700 dark:border-white/10 dark:text-white">
                    <Circle className={`h-3 w-3 ${event.is_active ? 'text-emerald-500' : 'text-slate-400'}`} />
                    {t('events.workspace.hero.liveBadge', 'Live?')} {event.is_active ? t('events.workspace.activeYes', 'Ja') : t('events.workspace.activeNo', 'Nein')}
                  </Badge>
                  <Badge variant="outline" className="gap-1 rounded-full border-slate-200 text-slate-700 dark:border-white/10 dark:text-white">
                    <Smile className="h-3.5 w-3.5 text-rose-500" />
                    {resolveEventType(event)}
                  </Badge>
                </div>
              </div>
              <div className="flex flex-wrap items-center gap-2">
                <Button variant="outline" size="sm" onClick={() => navigate(ADMIN_EVENTS_PATH)} className="rounded-full border-pink-200 text-pink-600 hover:bg-pink-50">
                  <ArrowLeft className="h-4 w-4" /> {t('events.actions.backToList', 'Zurück zur Liste')}
                </Button>
                <Button variant="outline" size="sm" onClick={() => navigate(ADMIN_EVENT_EDIT_PATH(event.slug))} className="rounded-full border-fuchsia-200 text-fuchsia-700 hover:bg-fuchsia-50">
                  <Sparkles className="h-4 w-4" /> {t('events.actions.edit', 'Bearbeiten')}
                </Button>
                <Button
                  variant="outline"
                  size="sm"
                  onClick={() => { void handleToggle(); }}
                  disabled={busy}
                  className="rounded-full border-slate-200"
                >
                  {busy ? (
                    <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                  ) : event.is_active ? (
                    <CheckCircle2 className="mr-2 h-4 w-4 text-emerald-500" />
                  ) : (
                    <Circle className="mr-2 h-4 w-4 text-slate-500" />
                  )}
                  {event.is_active ? t('events.workspace.actions.pause', 'Event pausieren') : t('events.workspace.actions.activate', 'Event aktivieren')}
                </Button>
              </div>
            </div>

            <div className="grid gap-6 xl:grid-cols-[minmax(0,1.4fr)_minmax(0,0.8fr)]">
              <TaskOverviewCard tasks={toolkitData?.tasks} navigateToTasks={() => navigate(ADMIN_EVENT_TASKS_PATH(event.slug))} />
              <InviteSummary
                invites={toolkitData?.invites}
                navigateToInvites={() => navigate(`${ADMIN_EVENT_INVITES_PATH(event.slug)}?tab=layout`)}
              />
            </div>
            {brandingAllowed ? (
            <BrandingMissionCard
              event={event}
              invites={toolkitData?.invites}
              emotions={emotions}
              onOpenBranding={() => navigate(ADMIN_EVENT_BRANDING_PATH(event.slug))}
              onOpenCollections={() => navigate(buildEngagementTabPath('collections'))}
              onOpenTasks={() => navigate(ADMIN_EVENT_TASKS_PATH(event.slug))}
              onOpenEmotions={() => navigate(buildEngagementTabPath('emotions'))}
            />
            ) : null}
            {event.addons?.length ? (
              <SectionCard>
                <SectionHeader
                  title={t('events.sections.addons.title', 'Add-ons & Upgrades')}
                  description={t('events.sections.addons.description', 'Zusätzliche Kontingente für dieses Event.')}
                />
                <AddonSummaryList addons={event.addons} t={(key, fallback) => t(key, fallback)} />
              </SectionCard>
            ) : null}
            <GalleryShareCard
              invites={toolkitData?.invites}
              onManageInvites={() => navigate(`${ADMIN_EVENT_INVITES_PATH(event.slug)}?tab=layout`)}
            />
            {event.limits?.gallery ? <GalleryStatusCard gallery={event.limits.gallery} /> : null}
            <FeedbackCard slug={event.slug} />
            <QuickActionsMenu slug={event.slug} navigate={navigate} />
          </div>
        </div>
      ) : (
        <SectionCard>
          <p className="text-sm text-slate-600 dark:text-slate-300">
            {t('events.errors.notFoundBody', 'Ohne gültige Kennung können wir keine Daten laden. Kehre zur Eventliste zurück und wähle dort ein Event aus.')}
          </p>
        </SectionCard>
      )}
    </AdminLayout>
  );
}

function resolveName(name: TenantEvent['name']): string {
  if (typeof name === 'string' && name.trim().length > 0) {
    return name.trim();
  }

  if (name && typeof name === 'object') {
    return name.de ?? name.en ?? Object.values(name)[0] ?? 'Event';
  }

  return 'Event';
}

type RecapContentProps = {
  event: TenantEvent;
  stats: EventStats;
  busy: boolean;
  onToggleEvent: () => void;
  onExtendGallery: () => void;
};

function RecapContent({ event, stats, busy, onToggleEvent, onExtendGallery }: RecapContentProps) {
  const { t } = useTranslation('management');
  const navigate = useNavigate();

  const galleryExpiresAt = event.package?.expires_at ?? event.limits?.gallery?.expires_at ?? null;
  const galleryStatusLabel = event.is_active
    ? t('events.recap.galleryOpen', 'Galerie geöffnet')
    : t('events.recap.galleryClosed', 'Galerie geschlossen');

  const counts = {
    photos: stats.uploads_total ?? stats.total ?? 0,
    pending: stats.pending_photos ?? 0,
    likes: stats.likes_total ?? stats.likes ?? 0,
  };

  return (
    <div className="space-y-6">
      <div className="grid gap-4 lg:grid-cols-2">
        <div className="rounded-3xl border border-slate-200 bg-white/85 p-5 shadow-sm dark:border-white/10 dark:bg-white/5">
          <div className="flex items-start justify-between gap-3">
            <div>
              <p className="text-xs font-semibold uppercase tracking-[0.3em] text-emerald-500">
                {t('events.recap.galleryTitle', 'Galerie-Status')}
              </p>
              <p className="mt-1 text-lg font-semibold text-slate-900 dark:text-white">{galleryStatusLabel}</p>
              <p className="text-sm text-slate-600 dark:text-slate-300">
                {t('events.recap.galleryCounts', '{{photos}} Fotos, {{pending}} offen, {{likes}} Likes', counts)}
              </p>
            </div>
            <Badge variant={event.is_active ? 'default' : 'outline'} className="bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-100">
              {event.is_active ? t('events.recap.open', 'Offen') : t('events.recap.closed', 'Geschlossen')}
            </Badge>
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <Button size="sm" variant={event.is_active ? 'secondary' : 'default'} disabled={busy} onClick={onToggleEvent}>
              {busy ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <Sparkles className="mr-2 h-4 w-4" />}
              {event.is_active ? t('events.recap.closeGallery', 'Galerie schließen') : t('events.recap.openGallery', 'Galerie öffnen')}
            </Button>
            <Button size="sm" variant="outline" onClick={() => navigate(ADMIN_EVENT_PHOTOS_PATH(event.slug))}>
              <Camera className="mr-2 h-4 w-4" />
              {t('events.recap.moderate', 'Uploads ansehen')}
            </Button>
          </div>
          {event.public_url ? (
            <div className="mt-4 flex items-center gap-2 text-sm text-slate-600 dark:text-slate-300">
              <span className="truncate" title={event.public_url}>{event.public_url}</span>
              <Button size="icon" variant="ghost" className="h-8 w-8" onClick={() => navigator.clipboard.writeText(event.public_url!)}>
                <QrCode className="h-4 w-4" />
              </Button>
            </div>
          ) : null}
        </div>

        <div className="rounded-3xl border border-slate-200 bg-white/85 p-5 shadow-sm dark:border-white/10 dark:bg-white/5">
          <div className="flex items-start justify-between gap-3">
            <div>
              <p className="text-xs font-semibold uppercase tracking-[0.3em] text-indigo-500">
                {t('events.recap.exportTitle', 'Export & Backup')}
              </p>
              <p className="mt-1 text-lg font-semibold text-slate-900 dark:text-white">
                {t('events.recap.exportCopy', 'Alle Assets sichern')}
              </p>
              <p className="text-sm text-slate-600 dark:text-slate-300">
                {t('events.recap.exportHint', 'Zip/CSV Export und Backup anstoßen.')}
              </p>
            </div>
            <Badge variant="outline" className="border-indigo-200 text-indigo-700 dark:border-indigo-800 dark:text-indigo-200">
              {t('events.recap.backup', 'Backup')}
            </Badge>
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <Button size="sm" onClick={() => navigate(ADMIN_EVENT_PHOTOS_PATH(event.slug))}>
              <ArrowLeft className="mr-2 h-4 w-4 rotate-180" />
              {t('events.recap.exportAll', 'Alles exportieren')}
            </Button>
            <Button size="sm" variant="outline" onClick={() => navigate(ADMIN_EVENT_PHOTOS_PATH(event.slug))}>
              <Printer className="mr-2 h-4 w-4" />
              {t('events.recap.exportHighlights', 'Highlights exportieren')}
            </Button>
          </div>
        </div>
      </div>

      <div className="grid gap-4 lg:grid-cols-2">
        <div className="rounded-3xl border border-slate-200 bg-white/85 p-5 shadow-sm dark:border-white/10 dark:bg-white/5">
          <div className="flex items-start justify-between gap-3">
            <div>
              <p className="text-xs font-semibold uppercase tracking-[0.3em] text-amber-500">
                {t('events.recap.retentionTitle', 'Aufbewahrung & Verlängerung')}
              </p>
              <p className="mt-1 text-lg font-semibold text-slate-900 dark:text-white">
                {galleryExpiresAt
                  ? t('events.recap.expiresAt', 'Läuft ab am {{date}}', { date: formatEventDate(galleryExpiresAt, undefined) })
                  : t('events.recap.noExpiry', 'Ablaufdatum nicht gesetzt')}
              </p>
              <p className="text-sm text-slate-600 dark:text-slate-300">
                {t('events.recap.retentionHint', 'Verlängere die Galerie-Laufzeit mit einem Add-on. Verlängerungen addieren sich.')}
              </p>
            </div>
            <Badge variant="outline" className="border-amber-200 text-amber-700 dark:border-amber-800 dark:text-amber-100">
              {t('events.recap.expiry', 'Ablauf')}
            </Badge>
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <Button size="sm" variant="default" onClick={onExtendGallery}>
              <Clock3 className="mr-2 h-4 w-4" />
              {t('events.recap.extend30', '+30 Tage verlängern')}
            </Button>
            <Button size="sm" variant="outline" onClick={() => navigate(ADMIN_EVENT_EDIT_PATH(event.slug))}>
              {t('events.recap.archive', 'Archivieren/Löschen')}
            </Button>
          </div>
        </div>

        <div className="rounded-3xl border border-slate-200 bg-white/85 p-5 shadow-sm dark:border-white/10 dark:bg-white/5">
          <div className="flex items-start justify-between gap-3">
            <div>
              <p className="text-xs font-semibold uppercase tracking-[0.3em] text-rose-500">
                {t('events.recap.commsTitle', 'Kommunikation')}
              </p>
              <p className="mt-1 text-lg font-semibold text-slate-900 dark:text-white">
                {t('events.recap.commsCopy', 'Kein Gast-Newsletter aktiv')}
              </p>
              <p className="text-sm text-slate-600 dark:text-slate-300">
                {t('events.recap.commsHint', 'Push wirkt vor allem live. Teile den Link manuell mit deinem Team oder auf Social Media.')}
              </p>
            </div>
            <Badge variant="outline" className="border-rose-200 text-rose-700 dark:border-rose-800 dark:text-rose-100">
              {t('events.recap.manual', 'Manuell')}
            </Badge>
          </div>
          {event.public_url ? (
            <div className="mt-4 flex items-center gap-2 rounded-2xl border border-dashed border-slate-200 bg-white/70 p-3 text-sm text-slate-700 dark:border-white/10 dark:bg-white/10 dark:text-slate-200">
              <div className="flex-1 truncate" title={event.public_url}>{event.public_url}</div>
              <Button size="sm" variant="ghost" onClick={() => navigator.clipboard.writeText(event.public_url!)}>
                {t('events.recap.copyLink', 'Link kopieren')}
              </Button>
            </div>
          ) : null}
        </div>
      </div>
    </div>
  );
}

function QuickActionsMenu({ slug, navigate }: { slug: string; navigate: ReturnType<typeof useNavigate> }) {
  const { t } = useTranslation('management');

  const actions = [
    { key: 'photos', icon: <Camera className="h-4 w-4" />, label: t('events.quickActions.moderate', 'Fotos moderieren'), onClick: () => navigate(ADMIN_EVENT_PHOTOS_PATH(slug)) },
    { key: 'tasks', icon: <Sparkles className="h-4 w-4" />, label: t('events.quickActions.tasks', 'Aufgaben bearbeiten'), onClick: () => navigate(ADMIN_EVENT_TASKS_PATH(slug)) },
    { key: 'invites', icon: <QrCode className="h-4 w-4" />, label: t('events.quickActions.invites', 'Layouts & QR verwalten'), onClick: () => navigate(`${ADMIN_EVENT_INVITES_PATH(slug)}?tab=layout`) },
    { key: 'roles', icon: <Users className="h-4 w-4" />, label: t('events.quickActions.roles', 'Team & Rollen anpassen'), onClick: () => navigate(ADMIN_EVENT_MEMBERS_PATH(slug)) },
    { key: 'photobooth', icon: <PlugZap className="h-4 w-4" />, label: t('events.quickActions.photobooth', 'Photobooth anbinden'), onClick: () => navigate(ADMIN_EVENT_PHOTOBOOTH_PATH(slug)) },
    { key: 'print', icon: <Printer className="h-4 w-4" />, label: t('events.quickActions.print', 'Layouts als PDF drucken'), onClick: () => navigate(`${ADMIN_EVENT_INVITES_PATH(slug)}?tab=export`) },
  ];

  return (
    <Sheet>
      <SheetTrigger asChild>
        <Button
          size="icon"
          className="fixed right-6 z-40 h-12 w-12 rounded-full bg-rose-500 text-white shadow-xl shadow-rose-300/50 hover:bg-rose-600 focus-visible:ring-2 focus-visible:ring-rose-300"
          style={{ bottom: '90px' }}
          aria-label={t('events.quickActions.badge', 'Schnellaktionen')}
        >
          <Menu className="h-5 w-5" />
        </Button>
      </SheetTrigger>
      <SheetContent side="bottom" className="rounded-t-3xl border border-slate-200 bg-white/95 p-4 text-slate-900 dark:border-white/10 dark:bg-slate-950">
        <SheetHeader>
          <SheetTitle className="text-lg font-semibold">{t('events.quickActions.title', 'Starte in die Moderation')}</SheetTitle>
        </SheetHeader>
        <div className="mt-4 grid gap-2">
          {actions.map((action) => (
            <Button
              key={action.key}
              variant="ghost"
              className="flex items-center justify-start gap-3 rounded-2xl border border-slate-200 bg-white/90 text-left text-sm font-semibold text-slate-800 hover:border-rose-200 hover:bg-rose-50 dark:border-white/10 dark:bg-white/5 dark:text-white"
              onClick={action.onClick}
            >
              {action.icon}
              {action.label}
            </Button>
          ))}
        </div>
      </SheetContent>
    </Sheet>
  );
}

function InviteSummary({ invites, navigateToInvites }: { invites: EventToolkit['invites'] | undefined; navigateToInvites: () => void }) {
  const { t } = useTranslation('management');

  return (
    <SectionCard className="space-y-3">
      <SectionHeader
        eyebrow={t('events.invites.badge', 'QR-Codes')}
        title={t('events.invites.title', 'QR-Codes & Layouts')}
        description={t('events.invites.subtitle', 'Behält aktive QR-Codes und Layouts im Blick.')}
      />
      <div className="space-y-3 text-sm text-slate-700 dark:text-slate-300">
        <div className="flex gap-2 text-sm text-slate-900">
          <Badge variant="outline" className="border-amber-200 text-amber-700 dark:border-amber-500/30 dark:text-amber-200">
            {t('events.invites.activeCount', { defaultValue: '{{count}} aktiv', count: invites?.summary.active ?? 0 })}
          </Badge>
          <Badge variant="outline" className="border-amber-200 text-amber-700 dark:border-amber-500/30 dark:text-amber-200">
            {t('events.invites.totalCount', { defaultValue: '{{count}} gesamt', count: invites?.summary.total ?? 0 })}
          </Badge>
        </div>

        {invites?.items?.length ? (
          <ul className="space-y-2 text-xs">
            {invites.items.slice(0, 3).map((invite) => (
              <li key={invite.id} className="rounded-lg border border-amber-100 bg-amber-50/70 p-3">
                <p className="text-sm font-semibold text-slate-900">{invite.label ?? invite.url}</p>
                <p className="truncate text-[11px] text-amber-700">{invite.url}</p>
              </li>
            ))}
          </ul>
        ) : (
          <p className="text-xs text-slate-500">{t('events.invites.empty', 'Noch keine QR-Codes erstellt.')}</p>
        )}

        <Button variant="outline" onClick={navigateToInvites} className="border-amber-200 text-amber-700 hover:bg-amber-50">
          <QrCode className="mr-2 h-4 w-4" /> {t('events.invites.manage', 'QR-Codes & Layouts verwalten')}
        </Button>
      </div>
    </SectionCard>
  );
}

function TaskOverviewCard({ tasks, navigateToTasks }: { tasks: EventToolkit['tasks'] | undefined; navigateToTasks: () => void }) {
  const { t } = useTranslation('management');

  return (
    <SectionCard className="space-y-3">
      <SectionHeader
        eyebrow={t('events.tasks.badge', 'Aufgaben')}
        title={t('events.tasks.title', 'Aktive Aufgaben')}
        description={t('events.tasks.subtitle', 'Motiviere Gäste mit klaren Aufgaben & Highlights.')}
        endSlot={(
          <Badge variant="outline" className="border-pink-200 text-pink-600 dark:border-pink-500/30 dark:text-pink-200">
            {t('events.tasks.summary', {
              defaultValue: '{{completed}} von {{total}} erledigt',
              completed: tasks?.summary.completed ?? 0,
              total: tasks?.summary.total ?? 0,
            })}
          </Badge>
        )}
      />
      <div className="space-y-3 text-sm text-slate-700 dark:text-slate-300">
        {tasks?.items?.length ? (
          <div className="space-y-2">
            {tasks.items.slice(0, 4).map((task) => (
              <TaskRow key={task.id} task={task} />
            ))}
          </div>
        ) : (
          <p className="text-xs text-slate-500">{t('events.tasks.empty', 'Noch keine Aufgaben zugewiesen.')}</p>
        )}

        <Button variant="outline" onClick={navigateToTasks} className="border-pink-200 text-pink-600 hover:bg-pink-50">
          <Sparkles className="mr-2 h-4 w-4" /> {t('events.tasks.manage', 'Aufgabenbereich öffnen')}
        </Button>
      </div>
    </SectionCard>
  );
}

function TaskRow({ task }: { task: EventToolkitTask }) {
  const { t } = useTranslation('management');
  return (
    <div className="flex items-start justify-between rounded-lg border border-pink-100 bg-white/80 px-3 py-2 text-xs text-slate-600">
      <div className="space-y-1">
        <p className="text-sm font-semibold text-slate-900">{task.title}</p>
        {task.description ? <p>{task.description}</p> : null}
      </div>
      <Badge variant={task.is_completed ? 'default' : 'outline'} className={task.is_completed ? 'bg-emerald-500/20 text-emerald-600' : 'border-pink-200 text-pink-600'}>
        {task.is_completed ? t('events.tasks.status.completed', 'Done') : t('events.tasks.status.open', 'Open')}
      </Badge>
    </div>
  );
}

function BrandingMissionCard({
  event,
  invites,
  emotions,
  onOpenBranding,
  onOpenCollections,
  onOpenTasks,
  onOpenEmotions,
}: {
  event: TenantEvent;
  invites?: EventToolkit['invites'];
  emotions?: TenantEmotion[];
  onOpenBranding: () => void;
  onOpenCollections: () => void;
  onOpenTasks: () => void;
  onOpenEmotions: () => void;
}) {
  const { t } = useTranslation('management');

  const palette = extractBrandingPalette(event.settings);
  const activeInvites = invites?.summary.active ?? 0;
  const eventTypeId = event.event_type_id ?? event.event_type?.id ?? null;
  const spotlightEmotions = React.useMemo(
    () => filterEmotionsByEventType(emotions ?? [], eventTypeId).slice(0, 4),
    [emotions, eventTypeId],
  );

  return (
    <SectionCard className="space-y-4">
      <SectionHeader
        eyebrow={t('events.branding.badge', 'Branding & Story')}
        title={t('events.branding.title', 'Branding & Aufgaben-Sets')}
        description={t('events.branding.subtitle', 'Stimme Farben, Schriftarten und Aufgabenpakete aufeinander ab.')}
      />
      <div className="grid gap-4 md:grid-cols-2">
        <div className="rounded-2xl border border-indigo-100 bg-indigo-50/80 p-4 text-sm text-indigo-900 shadow-inner shadow-indigo-100 dark:border-indigo-300/40 dark:bg-indigo-500/10 dark:text-indigo-100">
          <p className="text-xs uppercase tracking-[0.3em]">{t('events.branding.brandingTitle', 'Branding')}</p>
          <p className="mt-1 text-base font-semibold">{palette.font ?? t('events.branding.brandingFallback', 'Aktuelle Auswahl')}</p>
          <p className="text-xs text-indigo-900/70 dark:text-indigo-100/80">
            {t('events.branding.brandingCopy', 'Passe Farben & Schriftarten im Layout-Editor an.')}
          </p>
          <div className="mt-3 flex gap-2">
            {(palette.colors.length ? palette.colors : ['#f472b6', '#fef3c7', '#312e81']).map((color) => (
              <span
                key={color}
                className="h-10 w-10 rounded-xl border border-white/70 shadow"
                style={{ backgroundColor: color }}
              />
            ))}
          </div>
          <Button size="sm" variant="secondary" className="mt-4 rounded-full bg-white/80 text-indigo-900 hover:bg-white" onClick={onOpenBranding}>
            {t('events.branding.brandingCta', 'Branding anpassen')}
          </Button>
        </div>
        <div className="rounded-2xl border border-rose-100 bg-rose-50/80 p-4 text-sm text-rose-900 shadow-inner shadow-rose-100 dark:border-rose-300/40 dark:bg-rose-500/10 dark:text-rose-100">
          <p className="text-xs uppercase tracking-[0.3em]">{t('events.branding.collectionsTitle', 'Aufgaben-Sets')}</p>
          <p className="mt-1 text-base font-semibold">
            {event.event_type?.name ?? t('events.branding.collectionsFallback', 'Empfohlene Story')}
          </p>
          <p className="text-xs text-rose-900/70 dark:text-rose-100/80">
            {t('events.branding.collectionsCopy', 'Importiere passende Kollektionen oder aktiviere Emotionen im Aufgabenbereich.')}
          </p>
          <div className="mt-3 flex flex-wrap gap-2 text-xs">
            <Badge variant="outline" className="border-rose-200 text-rose-700 dark:border-rose-300/40 dark:text-rose-100">
              {t('events.branding.collectionsActive', { defaultValue: '{{count}} aktive Links', count: activeInvites })}
            </Badge>
            <Badge variant="outline" className="border-rose-200 text-rose-700 dark:border-rose-300/40 dark:text-rose-100">
              {t('events.branding.tasksCount', {
                defaultValue: '{{count}} Aufgaben',
                count: Number(event.tasks_count ?? 0),
              })}
            </Badge>
          </div>
          <div className="mt-4 rounded-xl border border-rose-100/80 bg-white/70 p-3 text-xs text-rose-900/80">
            <p className="text-[10px] uppercase tracking-[0.3em] text-rose-400">
              {t('events.branding.emotionsTitle', 'Emotionen')}
            </p>
            {spotlightEmotions.length ? (
              <div className="mt-2 flex flex-wrap gap-2">
                {spotlightEmotions.map((emotion) => (
                  <span
                    key={emotion.id}
                    className="flex items-center gap-1 rounded-full px-3 py-1 text-xs font-semibold shadow-sm"
                    style={{
                      backgroundColor: `${emotion.color ?? '#fecdd3'}33`,
                      color: emotion.color ?? '#be123c',
                    }}
                  >
                    {emotion.icon ? <span>{emotion.icon}</span> : null}
                    {emotion.name}
                  </span>
                ))}
              </div>
            ) : (
              <p className="mt-2 text-xs text-rose-900/70">
                {t('events.branding.emotionsEmpty', 'Aktiviere Emotionen, um Aufgaben zu kategorisieren.')}
              </p>
            )}
            <Button
              size="sm"
              variant="ghost"
              className="mt-3 h-8 px-0 text-rose-700 hover:bg-rose-100/70"
              onClick={onOpenEmotions}
            >
              {t('events.branding.emotionsCta', 'Emotionen verwalten')}
            </Button>
          </div>
          <div className="mt-4 flex flex-wrap gap-2">
            <Button size="sm" variant="outline" className="border-rose-200 text-rose-700 hover:bg-rose-100" onClick={onOpenTasks}>
              {t('events.branding.collectionsManage', 'Aufgaben bearbeiten')}
            </Button>
            <Button size="sm" variant="ghost" className="text-rose-700 hover:bg-rose-100/80" onClick={onOpenCollections}>
              {t('events.branding.collectionsImport', 'Aufgaben-Set importieren')}
            </Button>
          </div>
        </div>
      </div>
    </SectionCard>
  );
}

function GalleryShareCard({
  invites,
  onManageInvites,
}: {
  invites?: EventToolkit['invites'];
  onManageInvites: () => void;
}) {
  const { t } = useTranslation('management');
  const primaryInvite = React.useMemo(
    () => invites?.items?.find((invite) => invite.is_active) ?? invites?.items?.[0] ?? null,
    [invites?.items],
  );

  const handleCopy = React.useCallback(async () => {
    if (!primaryInvite?.url) {
      return;
    }
    try {
      await navigator.clipboard.writeText(primaryInvite.url);
      toast.success(t('events.galleryShare.copied', 'Link kopiert'));
    } catch (err) {
      console.error(err);
      toast.error(t('events.galleryShare.copyFailed', 'Konnte Link nicht kopieren'));
    }
  }, [primaryInvite, t]);

  if (!primaryInvite) {
    return (
      <SectionCard className="space-y-3">
        <SectionHeader
          eyebrow={t('events.galleryShare.badge', 'Galerie')}
          title={t('events.galleryShare.title', 'Galerie teilen')}
          description={t('events.galleryShare.emptyDescription', 'Erstelle einen QR-Codeslink, um Fotos zu teilen.')}
        />
        <Button onClick={onManageInvites} className="w-full rounded-full bg-brand-rose text-white shadow-md shadow-rose-300/40">
          {t('events.galleryShare.createInvite', 'QR-Code erstellen')}
        </Button>
      </SectionCard>
    );
  }

  return (
    <SectionCard className="space-y-3">
      <SectionHeader
        eyebrow={t('events.galleryShare.badge', 'Galerie')}
        title={t('events.galleryShare.title', 'Galerie-Link & QR')}
        description={t('events.galleryShare.description', 'Teile den Link nach dem Event oder lade QR-Karten herunter.')}
      />
      <div className="rounded-2xl border border-slate-200 bg-white/90 p-4 text-sm text-slate-700 dark:border-white/10 dark:bg-white/5 dark:text-slate-200">
        <p className="text-xs uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400">
          {primaryInvite.label ?? t('events.galleryShare.linkLabel', 'Standard-Link')}
        </p>
        <p className="mt-2 truncate text-base font-semibold text-slate-900 dark:text-white">{primaryInvite.url}</p>
        <div className="mt-3 flex flex-wrap gap-2 text-xs">
          <Badge variant="outline" className="border-slate-200 text-slate-600 dark:border-white/20 dark:text-white">
            {t('events.galleryShare.scans', { defaultValue: '{{count}} Aufrufe', count: primaryInvite.usage_count })}
          </Badge>
          {typeof primaryInvite.usage_limit === 'number' && (
            <Badge variant="outline" className="border-slate-200 text-slate-600 dark:border-white/20 dark:text-white">
              {t('events.galleryShare.limit', { defaultValue: 'Limit {{count}}', count: primaryInvite.usage_limit })}
            </Badge>
          )}
        </div>
        <div className="mt-4 flex flex-wrap gap-2">
          <Button size="sm" className="rounded-full bg-brand-rose px-4 text-white shadow-rose-400/40" onClick={handleCopy}>
            {t('events.galleryShare.copy', 'Link kopieren')}
          </Button>
          <Button size="sm" variant="outline" onClick={onManageInvites}>
            {t('events.galleryShare.manage', 'Layouts & QR öffnen')}
          </Button>
        </div>
      </div>
    </SectionCard>
  );
}

function GalleryStatusCard({ gallery }: { gallery: GallerySummary }) {
  const { t } = useTranslation('management');

  const stateLabel =
    gallery.state === 'expired'
      ? t('events.galleryStatus.stateExpired', 'Galerie abgelaufen')
      : gallery.state === 'warning'
        ? t('events.galleryStatus.stateWarning', 'Galerie läuft bald ab')
        : t('events.galleryStatus.stateOk', 'Galerie aktiv');

  const expiresLabel =
    gallery.expires_at && gallery.state !== 'unlimited'
      ? formatDate(gallery.expires_at)
      : t('events.galleryStatus.noExpiry', 'Kein Ablaufdatum gesetzt');

  const daysRemaining =
    typeof gallery.days_remaining === 'number' && gallery.days_remaining >= 0
      ? gallery.days_remaining
      : null;

  return (
    <SectionCard className="space-y-3">
      <SectionHeader
        eyebrow={t('events.galleryStatus.badge', 'Laufzeit')}
        title={t('events.galleryStatus.title', 'Galerie-Laufzeit & Verfügbarkeit')}
        description={t('events.galleryStatus.subtitle', 'Halte im Blick, wie lange Gäste noch auf die Galerie zugreifen können.')}
      />
      <div className="flex flex-col gap-3 rounded-2xl border border-slate-200 bg-white/90 p-4 text-sm text-slate-700 dark:border-white/10 dark:bg-white/5 dark:text-slate-200 md:flex-row md:items-center md:justify-between">
        <div className="space-y-1">
          <p className="text-xs uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400">
            {t('events.galleryStatus.stateLabel', 'Status')}
          </p>
          <p className="text-sm font-semibold text-slate-900 dark:text-white">{stateLabel}</p>
          <p className="text-xs text-slate-600 dark:text-slate-300">
            {t('events.galleryStatus.expiresAt', {
              defaultValue: 'Ablaufdatum: {{date}}',
              date: expiresLabel,
            })}
          </p>
        </div>
        <div className="space-y-1">
          <p className="text-xs uppercase tracking-[0.3em] text-slate-500 dark:text-slate-400">
            {t('events.galleryStatus.daysLabel', 'Verbleibende Tage')}
          </p>
          <p className="text-2xl font-semibold text-slate-900 dark:text-white">
            {daysRemaining !== null ? daysRemaining : '—'}
          </p>
        </div>
      </div>
    </SectionCard>
  );
}


function extractBrandingPalette(
  settings: TenantEvent['settings'],
): { colors: string[]; font?: string } {
  const colors: string[] = [];
  let font: string | undefined;

  if (settings && typeof settings === 'object') {
    const brandingSource =
      (settings as Record<string, unknown>).branding && typeof (settings as Record<string, unknown>).branding === 'object'
        ? (settings as Record<string, unknown>).branding
        : settings;

    const candidateKeys = ['primary_color', 'secondary_color', 'accent_color', 'background_color', 'color'];
    candidateKeys.forEach((key) => {
      const value = (brandingSource as Record<string, unknown>)[key];
      if (typeof value === 'string' && value.trim()) {
        colors.push(value);
      }
    });

    const fontKeys = ['font_family', 'font', 'heading_font'];
    fontKeys.some((key) => {
      const value = (brandingSource as Record<string, unknown>)[key];
      if (typeof value === 'string' && value.trim()) {
        font = value;
        return true;
      }
      return false;
    });
  }

  return { colors, font };
}

// Pending photos summary moved to the dedicated Live/Photos view.

function RecentUploadsCard({ slug, photos }: { slug: string; photos: TenantPhoto[] }) {
  const { t } = useTranslation('management');
  const [entries, setEntries] = React.useState(photos);
  const [updatingId, setUpdatingId] = React.useState<number | null>(null);

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

  const handleVisibility = async (photo: TenantPhoto, visible: boolean) => {
    setUpdatingId(photo.id);
    try {
      const updated = await updatePhotoVisibility(slug, photo.id, visible);
      setEntries((prev) => prev.map((item) => (item.id === photo.id ? updated : item)));
    } catch (err) {
      toast.error(
        isAuthError(err)
          ? t('events.photos.errorAuth', 'Session abgelaufen. Bitte erneut anmelden.')
          : t('events.photos.errorVisibility', 'Sichtbarkeit konnte nicht geändert werden.'),
      );
    } finally {
      setUpdatingId(null);
    }
  };

  return (
    <SectionCard className="space-y-3">
      <SectionHeader
        eyebrow={t('events.photos.recentBadge', 'Uploads')}
        title={t('events.photos.recentTitle', 'Neueste Uploads')}
        description={t('events.photos.recentSubtitle', 'Halte Ausschau nach Highlight-Momenten der Gäste.')}
      />
      <div className="space-y-2 text-sm text-slate-700 dark:text-slate-300">
        {entries.length ? (
          <div className="grid gap-3 sm:grid-cols-2">
            {entries.slice(0, 6).map((photo) => {
              const hidden = photo.status === 'hidden';
              return (
                <div key={photo.id} className="rounded-xl border border-slate-200 bg-white/90 p-2">
                  <div className="relative overflow-hidden rounded-lg">
                    <img
                      src={photo.thumbnail_url ?? photo.url ?? undefined}
                      alt={photo.caption ?? 'Foto'}
                      className={`h-28 w-full object-cover ${hidden ? 'opacity-60' : ''}`}
                    />
                    {photo.is_featured ? (
                      <span className="absolute left-2 top-2 rounded-full bg-pink-500/90 px-2 py-0.5 text-[10px] font-semibold text-white">
                        Highlight
                      </span>
                    ) : null}
                  </div>
                  <div className="mt-2 flex flex-wrap gap-2 text-[11px] text-slate-500">
                    <Badge variant="outline">♥ {photo.likes_count}</Badge>
                    <Badge variant="outline">{photo.uploader_name ?? 'Gast'}</Badge>
                  </div>
                  <div className="mt-2 flex flex-wrap gap-2 text-xs">
                    <Button size="sm" variant="outline" disabled={updatingId === photo.id} onClick={() => handleVisibility(photo, hidden)}>
                      {hidden ? t('events.photos.show', 'Einblenden') : t('events.photos.hide', 'Verstecken')}
                    </Button>
                    <Button
                      size="sm"
                      variant={photo.is_featured ? 'secondary' : 'outline'}
                      disabled={updatingId === photo.id}
                      onClick={() => handleFeature(photo, !photo.is_featured)}
                    >
                      {photo.is_featured ? t('events.photos.unfeature', 'Highlight entfernen') : t('events.photos.feature', 'Highlight')}
                    </Button>
                  </div>
                </div>
              );
            })}
          </div>
        ) : (
          <p className="text-xs text-slate-500">{t('events.photos.recentEmpty', 'Noch keine neuen Uploads.')}</p>
        )}
      </div>
    </SectionCard>
  );
}

function FeedbackCard({ slug }: { slug: string }) {
  const { t } = useTranslation('management');
  const [sentiment, setSentiment] = React.useState<'positive' | 'neutral' | 'negative' | null>(null);
  const [message, setMessage] = React.useState('');
  const [busy, setBusy] = React.useState(false);
  const [submitted, setSubmitted] = React.useState(false);
  const [error, setError] = React.useState<string | undefined>(undefined);

  const copy = {
    positive: t('events.feedback.positive', 'Super Lauf!'),
    neutral: t('events.feedback.neutral', 'Läuft'),
    negative: t('events.feedback.negative', 'Braucht Support'),
  };

  return (
    <SectionCard className="space-y-4">
      <SectionHeader
        eyebrow={t('events.feedback.badge', 'Feedback')}
        title={t('events.feedback.title', 'Wie läuft dein Event?')}
        description={t('events.feedback.subtitle', 'Feedback hilft uns, neue Features zu priorisieren.')}
      />
      <div className="space-y-4">
        {error && (
          <Alert variant="destructive">
            <AlertTitle>{t('events.feedback.errorTitle', 'Feedback konnte nicht gesendet werden.')}</AlertTitle>
            <AlertDescription>{error}</AlertDescription>
          </Alert>
        )}

        <div className="flex flex-wrap gap-2">
          {(Object.keys(copy) as Array<'positive' | 'neutral' | 'negative'>).map((key) => (
            <Button
              key={key}
              type="button"
              variant={sentiment === key ? 'default' : 'outline'}
              className={sentiment === key ? 'bg-slate-900 text-white' : 'border-slate-300 text-slate-700'}
              onClick={() => setSentiment(key)}
            >
              {copy[key]}
            </Button>
          ))}
        </div>

        <textarea
          value={message}
          onChange={(event) => setMessage(event.target.value)}
          placeholder={t('events.feedback.placeholder', 'Optional: Lass uns wissen, was gut funktioniert oder wo du Unterstützung brauchst.')}
          className="min-h-[120px] w-full rounded-md border border-slate-200 bg-white p-3 text-sm text-slate-700 outline-none focus:border-slate-400 focus:ring-1 focus:ring-slate-300"
        />

        <Button
          type="button"
          className="bg-slate-900 text-white hover:bg-slate-800"
          disabled={busy || submitted}
          onClick={async () => {
            if (busy || submitted) return;
            setBusy(true);
            setError(undefined);

            try {
              await submitTenantFeedback({
                category: 'event_workspace',
                event_slug: slug,
                sentiment: sentiment ?? undefined,
                message: message.trim() ? message.trim() : undefined,
              });
              setSubmitted(true);
            } catch (err) {
              setError(isAuthError(err)
                ? t('events.feedback.authError', 'Deine Session ist abgelaufen. Bitte melde dich erneut an.')
                : t('events.feedback.genericError', 'Feedback konnte nicht gesendet werden.'));
            } finally {
              setBusy(false);
            }
          }}
        >
          {busy ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <MessageSquare className="mr-2 h-4 w-4" />} {submitted ? t('events.feedback.submitted', 'Danke!') : t('events.feedback.submit', 'Feedback senden')}
        </Button>
      </div>
    </SectionCard>
  );
}

function GuestNotificationStatsCard({ notifications }: { notifications?: EventToolkit['notifications'] }) {
  const { t } = useTranslation('management');

  if (!notifications || notifications.summary.total === 0) {
    return (
      <div className="flex h-full flex-col items-center justify-center rounded-2xl border border-dashed border-slate-200 bg-slate-50 px-4 py-6 text-center text-sm text-slate-500">
        <MessageSquare className="mb-3 h-6 w-6 text-slate-400" aria-hidden />
        <p>{t('events.notifications.statsEmpty', 'Noch keine Nachrichten versendet – starte mit einem Broadcast.')}</p>
      </div>
    );
  }

  const { summary, recent } = notifications;
  const topTypes = Object.entries(summary.by_type ?? {})
    .sort(([, a], [, b]) => (b ?? 0) - (a ?? 0))
    .slice(0, 3);

  return (
    <div className="space-y-4">
      <div className="grid gap-3 sm:grid-cols-3">
        <StatPill
          icon={<Bell className="h-4 w-4" />}
          label={t('events.notifications.statsTotal', 'Gesendete Nachrichten')}
          value={summary.total}
        />
        <StatPill
          icon={<MessageSquare className="h-4 w-4" />}
          label={t('events.notifications.statsBroadcasts', 'Broadcasts')}
          value={summary.broadcasts.total}
          sublabel={summary.broadcasts.last_title ?? t('events.notifications.statsBroadcastsEmpty', 'Noch kein Broadcast')}
        />
        <StatPill
          icon={<Clock3 className="h-4 w-4" />}
          label={t('events.notifications.statsLastSent', 'Letzte Sendung')}
          value={summary.last_sent_at ? formatRelativeDateTime(summary.last_sent_at) : t('events.notifications.never', 'Noch nie')}
        />
      </div>

      <div className="rounded-2xl border border-slate-200 bg-white/80 p-4">
        <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">
          {t('events.notifications.topTypes', 'Beliebteste Typen')}
        </p>
        {topTypes.length > 0 ? (
          <div className="mt-3 flex flex-wrap gap-2">
            {topTypes.map(([type, count]) => (
              <Badge key={type} variant="secondary" className="gap-2">
                {getNotificationTypeLabel(type, t)}
                <span className="rounded-full bg-slate-200 px-2 text-xs font-semibold text-slate-700">{count as number}</span>
              </Badge>
            ))}
          </div>
        ) : (
          <p className="mt-2 text-sm text-slate-500">{t('events.notifications.topTypesEmpty', 'Noch keine Verteilung verfügbar.')}</p>
        )}
      </div>

      <div className="rounded-2xl border border-slate-200 bg-white/80 p-4">
        <div className="flex items-center justify-between">
          <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">
            {t('events.notifications.recent', 'Letzte Nachrichten')}
          </p>
          <span className="text-xs text-slate-400">{recent.length} {t('events.notifications.recentCount', 'Einträge')}</span>
        </div>
        {recent.length === 0 ? (
          <p className="mt-3 text-sm text-slate-500">{t('events.notifications.recentEmpty', 'Noch keine Historie vorhanden.')}</p>
        ) : (
          <ul className="mt-3 space-y-3">
            {recent.map((item) => (
              <li key={item.id} className="rounded-xl border border-slate-100 bg-white/70 px-3 py-2">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <p className="text-sm font-semibold text-slate-900">{item.title || t('events.notifications.untitled', 'Ohne Titel')}</p>
                    <p className="text-xs text-slate-500">
                      {formatRelativeDateTime(item.created_at)} · {getAudienceLabel(item.audience_scope, t)}
                    </p>
                  </div>
                  <Badge variant="outline" className="text-xs capitalize">
                    {getNotificationTypeLabel(item.type, t)}
                  </Badge>
                </div>
              </li>
            ))}
          </ul>
        )}
      </div>
    </div>
  );
}

function StatPill({ icon, label, value, sublabel }: { icon: React.ReactNode; label: string; value: string | number; sublabel?: string | null }) {
  return (
    <div className="rounded-2xl border border-slate-200 bg-white/80 p-4">
      <div className="flex items-center gap-2 text-slate-500">
        <span className="rounded-full bg-slate-100 p-2 text-slate-600">{icon}</span>
        <p className="text-xs font-semibold uppercase tracking-wide">{label}</p>
      </div>
      <p className="mt-2 text-2xl font-semibold text-slate-900">{value}</p>
      {sublabel && <p className="text-xs text-slate-500">{sublabel}</p>}
    </div>
  );
}

function formatRelativeDateTime(value?: string | null): string {
  if (!value) {
    return '—';
  }

  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return '—';
  }

  return date.toLocaleString(undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function getNotificationTypeLabel(type: string, t: ReturnType<typeof useTranslation>['t']): string {
  switch (type) {
    case 'broadcast':
      return t('events.notifications.types.broadcast', 'Broadcast');
    case 'upload_alert':
      return t('events.notifications.types.upload', 'Upload-Status');
    case 'support_tip':
      return t('events.notifications.types.support', 'Support-Tipp');
    case 'feedback_request':
      return t('events.notifications.types.feedback', 'Feedback');
    case 'achievement_major':
      return t('events.notifications.types.achievement', 'Achievement');
    case 'photo_activity':
      return t('events.notifications.types.activity', 'Aktivität');
    default:
      return t('events.notifications.types.generic', 'System');
  }
}

function getAudienceLabel(scope: string, t: ReturnType<typeof useTranslation>['t']): string {
  if (scope === 'guest') {
    return t('events.notifications.audienceGuest', 'Gezielte Gäste');
  }

  return t('events.notifications.audienceAll', 'Alle Gäste');
}

function getStatusLabel(event: TenantEvent, t: ReturnType<typeof useTranslation>['t']): string {
  if (event.status === 'published') {
    return t('events.status.published', 'Veröffentlicht');
  }
  if (event.status === 'archived') {
    return t('events.status.archived', 'Archiviert');
  }
  return t('events.status.draft', 'Entwurf');
}

function formatDate(value: string | null | undefined): string {
  if (!value) return '—';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) {
    return '—';
  }
  return date.toLocaleDateString(undefined, { day: '2-digit', month: '2-digit', year: 'numeric' });
}

function resolveEventType(event: TenantEvent): string {
  const type = event.event_type;
  if (!type) {
    return '—';
  }

  if (type.name_translations && Object.keys(type.name_translations).length > 0) {
    return type.name_translations.de ?? type.name_translations.en ?? Object.values(type.name_translations)[0] ?? type.name ?? '—';
  }

  if (typeof type.name === 'string' && type.name.trim().length > 0) {
    return type.name;
  }

  if (type.name && typeof type.name === 'object') {
    const translations = type.name as Record<string, string>;
    return translations.de ?? translations.en ?? Object.values(translations)[0] ?? '—';
  }

  return '—';
}

function AlertList({ alerts }: { alerts: string[] }) {
  if (!alerts.length) {
    return null;
  }

  return (
    <div className="space-y-2">
      {alerts.map((alert, index) => (
        <Alert key={`workspace-alert-${index}`} variant="default">
          <AlertTitle>{alert}</AlertTitle>
        </Alert>
      ))}
    </div>
  );
}

function CalendarIcon() {
  return (
    <svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4 text-slate-500" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5">
      <rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
      <line x1="16" y1="2" x2="16" y2="6" />
      <line x1="8" y1="2" x2="8" y2="6" />
      <line x1="3" y1="10" x2="21" y2="10" />
    </svg>
  );
}

function WorkspaceSkeleton() {
  return (
    <div className="space-y-6">
      <div className="grid gap-6 xl:grid-cols-[minmax(0,1.6fr)_minmax(0,0.6fr)]">
        <SkeletonCard />
        <SkeletonCard />
      </div>
      <div className="grid gap-4 md:grid-cols-2 xl:grid-cols-4">
        {Array.from({ length: 4 }).map((_, index) => (
          <SkeletonCard key={`metric-skeleton-${index}`} />
        ))}
      </div>
      <div className="grid gap-6 xl:grid-cols-[minmax(0,1.4fr)_minmax(0,0.8fr)]">
        <SkeletonCard />
        <SkeletonCard />
      </div>
      <div className="grid gap-6 xl:grid-cols-[minmax(0,1.4fr)_minmax(0,0.8fr)]">
        <SkeletonCard />
        <SkeletonCard />
      </div>
      <SkeletonCard />
    </div>
  );
}

function SkeletonCard() {
  return <div className="h-40 animate-pulse rounded-2xl bg-gradient-to-r from-slate-100 via-white to-slate-100" />;
}
