// @ts-nocheck
import React, { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Switch } from '@/components/ui/switch';
import { motion } from 'framer-motion';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { uploadPhoto, type UploadError } from '../services/photosApi';
import { useGuestTaskProgress } from '../hooks/useGuestTaskProgress';
import { cn } from '@/lib/utils';
import {
  AlertTriangle,
  Camera,
  ChevronDown,
  Grid3X3,
  Menu,
  ImagePlus,
  Info,
  Loader2,
  RotateCcw,
  Timer,
  Sparkles,
  FlipHorizontal,
  Zap,
  ZapOff,
} from 'lucide-react';
import { getEventPackage, type EventPackage } from '../services/eventApi';
import { useTranslation, type TranslateFn } from '../i18n/useTranslation';
import { buildLimitSummaries, type LimitSummaryCard } from '../lib/limitSummaries';
import { resolveUploadErrorDialog, type UploadErrorDialog } from '../lib/uploadErrorDialog';
import { useEventStats } from '../context/EventStatsContext';
import { useEventBranding } from '../context/EventBrandingContext';
import { compressPhoto, formatBytes } from '../lib/image';
import { FADE_SCALE, FADE_UP, prefersReducedMotion } from '../lib/motion';
import { useGuestIdentity } from '../context/GuestIdentityContext';
import { useEventData } from '../hooks/useEventData';
import { isTaskModeEnabled } from '../lib/engagement';
import { getDeviceId } from '../lib/device';

interface Task {
  id: number;
  title: string;
  description: string;
  instructions?: string;
  duration: number;
  emotion?: { slug: string; name: string };
  difficulty?: 'easy' | 'medium' | 'hard';
}

type PermissionState = 'idle' | 'prompt' | 'granted' | 'denied' | 'error' | 'unsupported' | 'blocked';
type CameraMode = 'preview' | 'countdown' | 'review' | 'uploading';

type CameraPreferences = {
  facingMode: 'user' | 'environment';
  countdownSeconds: number;
  countdownEnabled: boolean;
  gridEnabled: boolean;
  mirrorFrontPreview: boolean;
  flashPreferred: boolean;
};

type TaskPayload = Partial<Task> & { id: number };

function isTaskPayload(value: unknown): value is TaskPayload {
  if (typeof value !== 'object' || value === null) {
    return false;
  }

  const candidate = value as { id?: unknown };
  return typeof candidate.id === 'number';
}

function getErrorName(error: unknown): string | undefined {
  if (typeof error === 'object' && error !== null && 'name' in error) {
    const name = (error as { name?: unknown }).name;
    return typeof name === 'string' ? name : undefined;
  }

  return undefined;
}

function isCameraBlockedByPolicy(): boolean {
  if (typeof document === 'undefined') {
    return false;
  }

  const policy = (document as { permissionsPolicy?: { allowsFeature?: (feature: string) => boolean } })
    .permissionsPolicy;

  if (!policy?.allowsFeature) {
    return false;
  }

  return !policy.allowsFeature('camera');
}

const DEFAULT_PREFS: CameraPreferences = {
  facingMode: 'environment',
  countdownSeconds: 3,
  countdownEnabled: true,
  gridEnabled: true,
  mirrorFrontPreview: true,
  flashPreferred: false,
};

const LIMIT_CARD_STYLES: Record<LimitSummaryCard['tone'], { card: string; badge: string; bar: string }> = {
  neutral: {
    card: 'border-slate-200 bg-white/90 text-slate-900 dark:border-white/15 dark:bg-white/10 dark:text-white',
    badge: 'bg-slate-900/10 text-slate-900 dark:bg-white/20 dark:text-white',
    bar: 'bg-emerald-500',
  },
  warning: {
    card: 'border-amber-200 bg-amber-50 text-amber-900 dark:border-amber-400/40 dark:bg-amber-500/15 dark:text-amber-50',
    badge: 'bg-white/70 text-amber-900 dark:bg-amber-400/25 dark:text-amber-50',
    bar: 'bg-amber-500',
  },
  danger: {
    card: 'border-rose-200 bg-rose-50 text-rose-900 dark:border-rose-400/50 dark:bg-rose-500/15 dark:text-rose-50',
    badge: 'bg-white/70 text-rose-900 dark:bg-rose-400/20 dark:text-rose-50',
    bar: 'bg-rose-500',
  },
};


export default function UploadPage() {
  const { token } = useParams<{ token: string }>();
  const eventKey = token ?? '';
  const navigate = useNavigate();
  const [searchParams] = useSearchParams();
  const { markCompleted } = useGuestTaskProgress(token);
  const identity = useGuestIdentity();
  const { event } = useEventData();
  const tasksEnabled = isTaskModeEnabled(event);
  const { t, locale } = useTranslation();
  const stats = useEventStats();
  const { branding } = useEventBranding();
  const radius = branding.buttons?.radius ?? 12;
  const buttonStyle = branding.buttons?.style ?? 'filled';
  const linkColor = branding.buttons?.linkColor ?? branding.secondaryColor;
  const bodyFont = branding.typography?.body ?? branding.fontFamily ?? undefined;
  const uploadsRequireApproval =
    (event?.guest_upload_visibility as 'immediate' | 'review' | undefined) !== 'immediate';
  const demoReadOnly = Boolean(event?.demo_read_only);
  const liveShowModeration = event?.live_show?.moderation_mode ?? 'manual';
  const motionEnabled = !prefersReducedMotion();
  const overlayMotion = motionEnabled ? { initial: 'hidden', animate: 'show', variants: FADE_SCALE } : {};
  const fadeUpMotion = motionEnabled ? { initial: 'hidden', animate: 'show', variants: FADE_UP } : {};

  const taskIdParam = searchParams.get('task');
  const emotionSlug = searchParams.get('emotion') || '';

  const primerStorageKey = eventKey ? `guestCameraPrimerDismissed_${eventKey}` : 'guestCameraPrimerDismissed';
  const prefsStorageKey = eventKey ? `guestCameraPrefs_${eventKey}` : 'guestCameraPrefs';

  const supportsCamera = typeof navigator !== 'undefined' && !!navigator.mediaDevices?.getUserMedia;

  const [task, setTask] = useState<Task | null>(null);
  const [loadingTask, setLoadingTask] = useState(true);

  const [permissionState, setPermissionState] = useState<PermissionState>('idle');
  const [permissionMessage, setPermissionMessage] = useState<string | null>(null);

  const [preferences, setPreferences] = useState<CameraPreferences>(DEFAULT_PREFS);
  const [mode, setMode] = useState<CameraMode>('preview');
  const [countdownValue, setCountdownValue] = useState(DEFAULT_PREFS.countdownSeconds);
  const [statusMessage, setStatusMessage] = useState<string>('');

  const [reviewPhoto, setReviewPhoto] = useState<{ dataUrl: string; file: File } | null>(null);
const [uploadProgress, setUploadProgress] = useState(0);
const [uploadError, setUploadError] = useState<string | null>(null);
const [uploadWarning, setUploadWarning] = useState<string | null>(null);
const [immersiveMode, setImmersiveMode] = useState(true);
const [showCelebration, setShowCelebration] = useState(false);
const [showHeroOverlay, setShowHeroOverlay] = useState(true);
const kpiChipsRef = useRef<HTMLDivElement | null>(null);
const navSentinelRef = useRef<HTMLDivElement | null>(null);

  const [errorDialog, setErrorDialog] = useState<UploadErrorDialog | null>(null);
  const [taskDetailsExpanded, setTaskDetailsExpanded] = useState(false);

const [eventPackage, setEventPackage] = useState<EventPackage | null>(null);
const [canUpload, setCanUpload] = useState(true);
const [submitToLive, setSubmitToLive] = useState(true);

  const limitCards = useMemo<LimitSummaryCard[]>(
    () => buildLimitSummaries(eventPackage?.limits ?? null, t),
    [eventPackage?.limits, t]
  );

  useEffect(() => {
    if (typeof document === 'undefined') return undefined;
    const className = 'guest-immersive';
    document.body.classList.add(className);

    return () => {
      document.body.classList.remove(className);
      document.body.classList.remove('guest-nav-visible');
    };
  }, []);

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }

    const root = document.documentElement;
    const updateViewportVar = () => {
      const viewport = window.visualViewport?.height ?? window.innerHeight;
      root.style.setProperty('--guest-viewport-height', `${viewport}px`);
    };

    updateViewportVar();
    window.visualViewport?.addEventListener('resize', updateViewportVar);
    window.visualViewport?.addEventListener('scroll', updateViewportVar);
    window.addEventListener('resize', updateViewportVar);

    return () => {
      window.visualViewport?.removeEventListener('resize', updateViewportVar);
      window.visualViewport?.removeEventListener('scroll', updateViewportVar);
      window.removeEventListener('resize', updateViewportVar);
    };
  }, []);

  useEffect(() => {
    if (!event) return;
    setSubmitToLive(true);
  }, [event?.slug]);

  const updateNavVisibility = useCallback(() => {
    if (typeof document === 'undefined') {
      return;
    }
    const shouldShow = typeof window !== 'undefined' && window.scrollY > 24;
    document.body.classList.toggle('guest-nav-visible', shouldShow);
  }, []);

  useEffect(() => {
    if (typeof window === 'undefined') {
      return;
    }

    updateNavVisibility();
    window.addEventListener('scroll', updateNavVisibility, { passive: true });

    return () => {
      document.body.classList.remove('guest-nav-visible');
      window.removeEventListener('scroll', updateNavVisibility);
    };
  }, [updateNavVisibility]);

  const [showPrimer, setShowPrimer] = useState<boolean>(() => {
    if (typeof window === 'undefined') return false;
    return window.localStorage.getItem(primerStorageKey) !== '1';
  });

  const videoRef = useRef<HTMLVideoElement | null>(null);
  const canvasRef = useRef<HTMLCanvasElement | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const liveRegionRef = useRef<HTMLDivElement | null>(null);
  const cameraViewportRef = useRef<HTMLDivElement | null>(null);
  const cameraShellRef = useRef<HTMLElement | null>(null);

  const streamRef = useRef<MediaStream | null>(null);
  const countdownTimerRef = useRef<number | null>(null);
  const uploadProgressTimerRef = useRef<number | null>(null);

  const taskId = useMemo(() => {
    if (!taskIdParam) return null;
    const parsed = parseInt(taskIdParam, 10);
    return Number.isFinite(parsed) ? parsed : null;
  }, [taskIdParam]);

  const tasksUrl = useMemo(() => {
    if (!eventKey) return '/tasks';
    return `/e/${encodeURIComponent(eventKey)}/tasks`;
  }, [eventKey]);

  // Load preferences from storage
  useEffect(() => {
    if (typeof window === 'undefined') return;
    try {
      const stored = window.localStorage.getItem(prefsStorageKey);
      if (stored) {
        const parsed = JSON.parse(stored) as Partial<CameraPreferences>;
        setPreferences((prev) => ({ ...prev, ...parsed }));
      }
    } catch (error) {
      console.warn('Failed to parse camera preferences', error);
    }
  }, [prefsStorageKey]);

  // Persist preferences when they change
  useEffect(() => {
    if (typeof window === 'undefined') return;
    try {
      window.localStorage.setItem(prefsStorageKey, JSON.stringify(preferences));
    } catch (error) {
      console.warn('Failed to persist camera preferences', error);
    }
  }, [preferences, prefsStorageKey]);

  // Load task metadata
  useEffect(() => {
    if (!token || taskId === null || !tasksEnabled) {
      setLoadingTask(false);
      return;
    }

    let active = true;

    async function loadTask() {
      if (taskId === null) return;

      const currentTaskId = Number(taskId);
      const fallbackTitle = t('upload.taskInfo.fallbackTitle').replace('{id}', `${currentTaskId}`);
      const fallbackDescription = t('upload.taskInfo.fallbackDescription');
      const fallbackInstructions = t('upload.taskInfo.fallbackInstructions');

      try {
      setLoadingTask(true);

        const res = await fetch(
          `/api/v1/events/${encodeURIComponent(eventKey)}/tasks?locale=${encodeURIComponent(locale)}`,
          {
            headers: {
              Accept: 'application/json',
              'X-Locale': locale,
              'X-Device-Id': getDeviceId(),
            },
          }
        );
        if (!res.ok) throw new Error('Tasks konnten nicht geladen werden');
        const payload = (await res.json()) as unknown;
        const entries = Array.isArray(payload)
          ? payload.filter(isTaskPayload)
          : Array.isArray((payload as any)?.data)
            ? (payload as any).data.filter(isTaskPayload)
            : Array.isArray((payload as any)?.tasks)
              ? (payload as any).tasks.filter(isTaskPayload)
              : [];
        const found = entries.find((entry) => entry.id === currentTaskId) ?? null;

        if (!active) return;

        if (found) {
          setTask({
            id: found.id,
            title: found.title || fallbackTitle,
            description: found.description || fallbackDescription,
            instructions: found.instructions ?? fallbackInstructions,
            duration: found.duration || 2,
            emotion: found.emotion,
            difficulty: found.difficulty ?? 'medium',
          });
        } else {
          setTask({
            id: currentTaskId,
            title: fallbackTitle,
            description: fallbackDescription,
            instructions: fallbackInstructions,
            duration: 2,
            emotion: emotionSlug
              ? { slug: emotionSlug, name: emotionSlug.replace('-', ' ').replace(/\b\w/g, (l) => l.toUpperCase()) }
              : undefined,
            difficulty: 'medium',
          });
        }
      } catch (error) {
        console.error('Failed to fetch task', error);
        if (active) {
          setTask({
            id: currentTaskId,
            title: fallbackTitle,
            description: fallbackDescription,
            instructions: fallbackInstructions,
            duration: 2,
            emotion: emotionSlug
              ? { slug: emotionSlug, name: emotionSlug.replace('-', ' ').replace(/\b\w/g, (l) => l.toUpperCase()) }
              : undefined,
            difficulty: 'medium',
          });
        }
      } finally {
        if (active) setLoadingTask(false);
      }
    }

    loadTask();
    return () => {
      active = false;
    };
  }, [eventKey, taskId, emotionSlug, t, token, locale]);

  // Check upload limits
  useEffect(() => {
    if (!eventKey) return;

    const checkLimits = async () => {
      if (demoReadOnly) {
        setCanUpload(false);
        setUploadError(t('upload.demoReadOnly', 'Uploads sind in der Demo deaktiviert.'));
        setUploadWarning(null);
        return;
      }

      try {
        const pkg = await getEventPackage(eventKey);
        setEventPackage(pkg);
        if (!pkg) {
          setCanUpload(true);
          setUploadError(null);
          setUploadWarning(null);
          return;
        }

        const photoLimits = pkg.limits?.photos ?? null;
        const galleryLimits = pkg.limits?.gallery ?? null;

        let canUploadCurrent = pkg.limits?.can_upload_photos ?? true;
        let errorMessage: string | null = null;

        if (photoLimits?.state === 'limit_reached') {
          canUploadCurrent = false;
          if (typeof photoLimits.limit === 'number') {
            errorMessage = t('upload.limitReached')
              .replace('{used}', `${photoLimits.used}`)
              .replace('{max}', `${photoLimits.limit}`);
          } else {
            errorMessage = t('upload.errors.photoLimit');
          }
        }

        if (galleryLimits?.state === 'expired') {
          canUploadCurrent = false;
          errorMessage = t('upload.errors.galleryExpired');
        }

        setCanUpload(canUploadCurrent);
        setUploadError(errorMessage);
        setUploadWarning(null);
      } catch (err) {
        console.error('Failed to check package limits', err);
        setCanUpload(false);
        setUploadError(t('upload.limitCheckError'));
        setUploadWarning(null);
      }
    };

    checkLimits();
  }, [demoReadOnly, eventKey, t]);

  const stopStream = useCallback(() => {
    if (streamRef.current) {
      streamRef.current.getTracks().forEach((track) => track.stop());
      streamRef.current = null;
    }
  }, []);

  const attachStreamToVideo = useCallback((stream: MediaStream) => {
    if (!videoRef.current) return;
    videoRef.current.srcObject = stream;
    videoRef.current
      .play()
      .then(() => {
        if (videoRef.current) {
          videoRef.current.muted = true;
        }
      })
      .catch((error) => console.error('Video play error', error));
  }, []);

  const createConstraint = useCallback(
    (mode: 'user' | 'environment'): MediaStreamConstraints => ({
      video: {
        width: { ideal: 1920 },
        height: { ideal: 1080 },
        facingMode: { ideal: mode },
      },
      audio: false,
    }),
    []
  );

  const startCamera = useCallback(async () => {
    if (!supportsCamera) {
      setPermissionState('unsupported');
      setPermissionMessage(t('upload.cameraUnsupported.message'));
      return;
    }

    if (mode === 'uploading') return;

    try {
      if (isCameraBlockedByPolicy()) {
        setPermissionState('blocked');
        setPermissionMessage(t('upload.cameraBlocked.message'));
        return;
      }

      setPermissionState('prompt');
      setPermissionMessage(null);

      const stream = await navigator.mediaDevices.getUserMedia(createConstraint(preferences.facingMode));
      stopStream();
      streamRef.current = stream;
      attachStreamToVideo(stream);
      setPermissionState('granted');
    } catch (error: unknown) {
      console.error('Camera access error', error);
      stopStream();

      const errorName = getErrorName(error);
      if (errorName === 'NotAllowedError') {
        setPermissionState('denied');
        setPermissionMessage(t('upload.cameraDenied.explanation'));
      } else if (errorName === 'NotFoundError') {
        setPermissionState('error');
        setPermissionMessage(t('upload.cameraUnsupported.message'));
      } else {
        setPermissionState('error');
        setPermissionMessage(t('upload.cameraError.explanation'));
      }
    }
  }, [attachStreamToVideo, createConstraint, mode, preferences.facingMode, stopStream, supportsCamera, t]);

  const handleRecheckCamera = useCallback(() => {
    if (isCameraBlockedByPolicy()) {
      setPermissionState('blocked');
      setPermissionMessage(t('upload.cameraBlocked.message'));
      return;
    }

    setPermissionState('idle');
    setPermissionMessage(null);
    void startCamera();
  }, [startCamera, t]);

  useEffect(() => {
    if (loadingTask) return;
    startCamera();
    return () => {
      stopStream();
    };
  }, [loadingTask, startCamera, stopStream, preferences.facingMode]);

  // Countdown live region updates
  useEffect(() => {
    if (!liveRegionRef.current) return;
    if (mode === 'countdown') {
      liveRegionRef.current.textContent = t('upload.countdown.ready').replace('{count}', `${countdownValue}`);
    } else if (mode === 'review') {
      liveRegionRef.current.textContent = t('upload.review.readyAnnouncement');
    } else if (mode === 'uploading') {
      liveRegionRef.current.textContent = t('upload.status.uploading');
    } else {
      liveRegionRef.current.textContent = '';
    }
  }, [mode, countdownValue, t]);

  const dismissPrimer = useCallback(() => {
    setShowPrimer(false);
    if (typeof window !== 'undefined') {
      window.localStorage.setItem(primerStorageKey, '1');
    }
  }, [primerStorageKey]);

  const handleToggleGrid = useCallback(() => {
    setPreferences((prev) => ({ ...prev, gridEnabled: !prev.gridEnabled }));
  }, []);

  const handleToggleMirror = useCallback(() => {
    setPreferences((prev) => ({ ...prev, mirrorFrontPreview: !prev.mirrorFrontPreview }));
  }, []);

  const handleToggleCountdown = useCallback(() => {
    setPreferences((prev) => ({ ...prev, countdownEnabled: !prev.countdownEnabled }));
  }, []);

  const handleSwitchCamera = useCallback(() => {
    setPreferences((prev) => ({
      ...prev,
      facingMode: prev.facingMode === 'user' ? 'environment' : 'user',
    }));
  }, []);

  const handleToggleFlashPreference = useCallback(() => {
    setPreferences((prev) => ({ ...prev, flashPreferred: !prev.flashPreferred }));
  }, []);

  const handleToggleImmersive = useCallback(async () => {
    setImmersiveMode((prev) => !prev);
    const shell = cameraShellRef.current;
    if (!shell) return;
    const prefersReducedMotion = typeof window !== 'undefined'
      ? window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches
      : false;
    if (prefersReducedMotion) return;
    try {
      if (!document.fullscreenElement) {
        await shell.requestFullscreen?.();
      } else {
        await document.exitFullscreen?.();
      }
    } catch (error) {
      console.warn('Fullscreen toggle failed', error);
    }
  }, []);

  const triggerConfetti = useCallback(async () => {
    if (typeof window === 'undefined') return;
    const prefersReducedMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)')?.matches;
    if (prefersReducedMotion) return;

    try {
      const { default: confetti } = await import('canvas-confetti');
      confetti({
        particleCount: 70,
        spread: 65,
        origin: { x: 0.5, y: 0.35 },
        ticks: 160,
        scalar: 0.9,
      });
    } catch (error) {
      console.warn('Confetti could not start', error);
    }
  }, []);

  const resetCountdownTimer = useCallback(() => {
    if (countdownTimerRef.current) {
      window.clearInterval(countdownTimerRef.current);
      countdownTimerRef.current = null;
    }
  }, []);

  const performCapture = useCallback(() => {
    if (!videoRef.current || !canvasRef.current) {
      setUploadError(t('upload.captureError'));
      setMode('preview');
      return;
    }

    const video = videoRef.current;
    const canvas = canvasRef.current;
    const width = video.videoWidth;
    const height = video.videoHeight;

    if (!width || !height) {
      setUploadError(t('upload.feedError'));
      setMode('preview');
      startCamera();
      return;
    }

    canvas.width = width;
    canvas.height = height;
    const context = canvas.getContext('2d');
    if (!context) {
      setUploadError(t('upload.canvasError'));
      setMode('preview');
      return;
    }

    context.save();
    const shouldMirror = preferences.facingMode === 'user' && preferences.mirrorFrontPreview;
    if (shouldMirror) {
      context.scale(-1, 1);
      context.drawImage(video, -width, 0, width, height);
    } else {
      context.drawImage(video, 0, 0, width, height);
    }
    context.restore();

    canvas.toBlob(
      (blob) => {
        if (!blob) {
          setUploadError(t('upload.captureError'));
          setMode('preview');
          return;
        }
        const timestamp = Date.now();
        const fileName = `photo-${timestamp}.jpg`;
        const file = new File([blob], fileName, { type: 'image/jpeg', lastModified: timestamp });
        const dataUrl = canvas.toDataURL('image/jpeg', 0.92);
        setReviewPhoto({ dataUrl, file });
        setMode('review');
      },
      'image/jpeg',
      0.92
    );
  }, [preferences.facingMode, preferences.mirrorFrontPreview, startCamera, t]);

  const beginCapture = useCallback(() => {
    setUploadError(null);
    if (preferences.countdownEnabled && preferences.countdownSeconds > 0) {
      setMode('countdown');
      setCountdownValue(preferences.countdownSeconds);
      resetCountdownTimer();
      countdownTimerRef.current = window.setInterval(() => {
        setCountdownValue((prev) => {
          if (prev <= 1) {
            resetCountdownTimer();
            performCapture();
            return preferences.countdownSeconds;
          }
          return prev - 1;
        });
      }, 1000);
    } else {
      performCapture();
    }
  }, [performCapture, preferences.countdownEnabled, preferences.countdownSeconds, resetCountdownTimer]);

  const handleRetake = useCallback(() => {
    setReviewPhoto(null);
    setUploadProgress(0);
    setUploadError(null);
    setMode('preview');
  }, []);

  const navigateAfterUpload = useCallback(
    (photoId: number | undefined) => {
      if (!eventKey) return;
      const params = new URLSearchParams();
      params.set('uploaded', 'true');
      if (task?.id) params.set('task', String(task.id));
      if (photoId) params.set('photo', String(photoId));
      if (emotionSlug) params.set('emotion', emotionSlug);
      const target = uploadsRequireApproval ? 'queue' : 'gallery';
      navigate(`/e/${encodeURIComponent(eventKey)}/${target}?${params.toString()}`);
    },
    [emotionSlug, navigate, eventKey, task?.id, uploadsRequireApproval]
  );

  const handleUsePhoto = useCallback(async () => {
    if (!eventKey || !reviewPhoto || !canUpload) return;
    setMode('uploading');
    setUploadProgress(2);
    setUploadError(null);
    setUploadWarning(null);
    setStatusMessage(t('upload.status.preparing'));

    if (uploadProgressTimerRef.current) {
      window.clearInterval(uploadProgressTimerRef.current);
      uploadProgressTimerRef.current = null;
    }

    const maxEdge = 2400;
    const targetBytes = 4_000_000;
    let fileForUpload = reviewPhoto.file;

    try {
      setStatusMessage(t('upload.status.optimizing', 'Foto wird optimiert…'));
      const optimized = await compressPhoto(reviewPhoto.file, {
        maxEdge,
        targetBytes,
        qualityStart: 0.82,
      });

      fileForUpload = optimized;
      setUploadProgress(10);

      if (optimized.size < reviewPhoto.file.size - 50_000) {
        const saved = formatBytes(reviewPhoto.file.size - optimized.size);
        setUploadWarning(
          t('upload.optimizedNotice', 'Wir haben dein Foto verkleinert, damit der Upload schneller klappt. Eingespart: {saved}')
            .replace('{saved}', saved)
        );
      }
    } catch (e) {
      console.warn('Image optimization failed, uploading original', e);
      setUploadWarning(t('upload.optimizedFallback', 'Optimierung nicht möglich – wir laden das Original hoch.'));
    }

    try {
      const photoId = await uploadPhoto(eventKey, fileForUpload, task?.id, emotionSlug || undefined, {
        maxRetries: 2,
        guestName: identity.name || undefined,
        liveShowOptIn: submitToLive,
        onProgress: (percent) => {
          setUploadProgress(Math.max(15, Math.min(98, percent)));
          setStatusMessage(t('upload.status.uploading'));
        },
        onRetry: (attempt) => {
          setUploadWarning(
            t('upload.retrying', 'Verbindung holperig – neuer Versuch ({attempt}).')
              .replace('{attempt}', `${attempt}`)
          );
        },
      });
      setUploadProgress(100);
      setStatusMessage(t('upload.status.completed'));
      if (task?.id) {
        markCompleted(task.id);
      }
      setShowCelebration(true);
      if (typeof window !== 'undefined') {
        window.setTimeout(() => setShowCelebration(false), 1800);
      }
      void triggerConfetti();
      try {
        const raw = localStorage.getItem('my-photo-ids');
        const arr: number[] = raw ? JSON.parse(raw) : [];
        if (photoId && !arr.includes(photoId)) {
          localStorage.setItem('my-photo-ids', JSON.stringify([photoId, ...arr]));
        }
      } catch (error) {
        console.warn('Failed to persist my-photo-ids', error);
      }
      await new Promise((resolve) => {
        window.setTimeout(resolve, 420);
      });
      stopStream();
      navigateAfterUpload(photoId);
    } catch (error: unknown) {
      console.error('Upload failed', error);
      const uploadErr = error as UploadError;
      setUploadWarning(null);
      const meta = uploadErr.meta as Record<string, unknown> | undefined;
      const dialog = resolveUploadErrorDialog(uploadErr.code, meta, t);
      setErrorDialog(dialog);
      setUploadError(dialog.description);

      if (uploadErr.status === 422 || uploadErr.code === 'validation_error') {
        setUploadWarning(
          t('upload.errors.tooLargeHint', 'Das Foto war zu groß. Bitte erneut versuchen – wir verkleinern es automatisch.')
        );
      }

      if (
        uploadErr.code === 'photo_limit_exceeded'
        || uploadErr.code === 'upload_device_limit'
        || uploadErr.code === 'event_package_missing'
        || uploadErr.code === 'event_not_found'
        || uploadErr.code === 'gallery_expired'
      ) {
        setCanUpload(false);
      }

      setMode('review');
    } finally {
      setStatusMessage('');
    }
  }, [emotionSlug, markCompleted, navigateAfterUpload, reviewPhoto, eventKey, stopStream, task, canUpload, t, identity.name, triggerConfetti, submitToLive]);

  const handleGalleryPick = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
    if (!canUpload) return;
    const file = event.target.files?.[0];
    if (!file) return;
    setUploadError(null);
    setUploadWarning(null);
    setStatusMessage(t('upload.status.optimizing', 'Foto wird optimiert…'));

    let prepared = file;
    try {
      prepared = await compressPhoto(file, {
        maxEdge: 2400,
        targetBytes: 4_000_000,
        qualityStart: 0.82,
      });
      if (prepared.size < file.size - 50_000) {
        const saved = formatBytes(file.size - prepared.size);
        setUploadWarning(
          t('upload.optimizedNotice', 'Wir haben dein Foto verkleinert, damit der Upload schneller klappt. Eingespart: {saved}')
            .replace('{saved}', saved)
        );
      }
    } catch (error) {
      console.warn('Gallery image optimization failed, falling back to original', error);
      setUploadWarning(t('upload.optimizedFallback', 'Optimierung nicht möglich – wir laden das Original hoch.'));
    }

    if (prepared.size > 12_000_000) {
      setStatusMessage('');
      setUploadError(
        t('upload.errors.tooLargeHint', 'Das Foto war zu groß. Bitte erneut versuchen – wir verkleinern es automatisch.')
      );
      event.target.value = '';
      return;
    }

    const dataUrl = await readAsDataUrl(prepared);
    setReviewPhoto({ dataUrl, file: prepared });
    setMode('review');
    setStatusMessage('');
    event.target.value = '';
  }, [canUpload, t]);

  const emotionLabel = useMemo(() => {
    if (task?.emotion?.name) return task.emotion.name;
    if (emotionSlug) {
      return emotionSlug.replace('-', ' ').replace(/\b\w/g, (letter) => letter.toUpperCase());
    }
    return t('upload.hud.moodFallback');
  }, [emotionSlug, t, task?.emotion?.name]);

  const difficultyBadgeClass = useMemo(() => {
    if (!task) return 'text-white';
    switch (task.difficulty) {
      case 'easy':
        return 'text-emerald-400';
      case 'hard':
        return 'text-rose-400';
      default:
        return 'text-amber-300';
    }
  }, [task]);

  const isCameraActive = permissionState === 'granted' && mode !== 'uploading';
  const showTaskOverlay = task && mode !== 'uploading';

  const relativeLastUpload = useMemo(
    () => formatRelativeTimeLabel(stats.latestPhotoAt, t),
    [stats.latestPhotoAt, t],
  );

  const socialChips = useMemo(
    () => [
      {
        id: 'online',
        label: t('upload.hud.cards.online'),
        value: stats.onlineGuests > 0 ? `${stats.onlineGuests}` : '0',
      },
      {
        id: 'emotion',
        label: t('upload.taskInfo.emotion').replace('{value}', emotionLabel),
        value: t('upload.hud.moodLabel').replace('{mood}', emotionLabel),
      },
      {
        id: 'last-upload',
        label: t('upload.hud.cards.lastUpload'),
        value: relativeLastUpload,
      },
    ],
    [emotionLabel, relativeLastUpload, stats.onlineGuests, t],
  );

  useEffect(() => () => {
    resetCountdownTimer();
    if (uploadProgressTimerRef.current) {
      window.clearInterval(uploadProgressTimerRef.current);
    }
  }, [resetCountdownTimer]);

  useEffect(() => {
    setTaskDetailsExpanded(false);
  }, [task?.id]);

  useEffect(() => {
    if (task) {
      setShowHeroOverlay(false);
    } else {
      setShowHeroOverlay(true);
    }
  }, [task]);

  const handlePrimaryAction = useCallback(() => {
    setShowHeroOverlay(false);
    if (!isCameraActive) {
      startCamera();
      return;
    }
    beginCapture();
  }, [beginCapture, isCameraActive, startCamera]);

  const taskFloatingCard = showTaskOverlay && task ? (
    <motion.button
      type="button"
      onClick={() => setTaskDetailsExpanded((prev) => !prev)}
      className="absolute left-4 right-4 top-6 z-30 rounded-3xl border border-white/40 bg-black/60 p-4 text-left text-white shadow-2xl backdrop-blur transition hover:bg-black/70 focus:outline-none focus:ring-2 focus:ring-white/60 sm:left-6 sm:right-6 sm:top-8"
      {...overlayMotion}
    >
      <div className="flex items-center gap-3">
        <Badge variant="secondary" className="flex items-center gap-2 rounded-full text-[11px]">
          <Sparkles className="h-3.5 w-3.5" />
          {t('upload.taskInfo.badge').replace('{id}', `${task.id}`)}
        </Badge>
        <span className={cn('text-xs font-semibold uppercase tracking-wide', difficultyBadgeClass)}>
          {t(`upload.taskInfo.difficulty.${task.difficulty ?? 'medium'}`)}
        </span>
        <span className="ml-auto flex items-center text-xs uppercase tracking-wide text-white/70">
          {emotionLabel}
          <ChevronDown
            className={cn('ml-1 h-3.5 w-3.5 transition', taskDetailsExpanded ? 'rotate-180' : 'rotate-0')}
          />
        </span>
      </div>
      <p className="mt-3 text-sm font-semibold leading-snug">{task.title}</p>
      {taskDetailsExpanded ? (
        <div className="mt-2 space-y-2 text-xs text-white/80">
          <p>{task.description}</p>
          <div className="flex flex-wrap items-center gap-2 text-[11px]">
            {task.instructions && (
              <span>
                {t('upload.taskInfo.instructionsPrefix')}: {task.instructions}
              </span>
            )}
            {preferences.countdownEnabled && (
              <span className="rounded-full border border-white/20 px-2 py-0.5">
                {t('upload.countdownLabel').replace('{seconds}', `${preferences.countdownSeconds}`)}
              </span>
            )}
            {emotionLabel && (
              <span className="rounded-full border border-white/20 px-2 py-0.5">
                {t('upload.taskInfo.emotion').replace('{value}', emotionLabel)}
              </span>
            )}
          </div>
        </div>
      ) : null}
    </motion.button>
  ) : null;

  const heroOverlay = !task && showHeroOverlay && mode !== 'uploading' ? (
    <motion.div className="absolute left-4 right-4 top-4 z-30 rounded-2xl border border-white/25 bg-black/60 px-4 py-3 text-white shadow-2xl backdrop-blur sm:left-6 sm:right-6 sm:top-5" {...fadeUpMotion}>
      <div className="flex items-center justify-between gap-2">
        <div className="space-y-1">
          <p className="text-[11px] font-semibold uppercase tracking-[0.18em] text-white/70">Bereit für dein Foto?</p>
          <p className="text-base font-semibold leading-tight">Teile den Moment mit allen Gästen.</p>
        </div>
        <Badge variant="secondary" className="rounded-full bg-white/15 px-3 py-1 text-[10px] font-semibold uppercase tracking-wide text-white/90">
          Live
        </Badge>
      </div>
    </motion.div>
  ) : null;

  const dialogToneIconClass: Record<Exclude<UploadErrorDialog['tone'], undefined>, string> = {
    danger: 'text-rose-500',
    warning: 'text-amber-500',
    info: 'text-sky-500',
  };

  const errorDialogNode = (
    <Dialog open={Boolean(errorDialog)} onOpenChange={(open) => { if (!open) setErrorDialog(null); }}>
      <DialogContent>
        <DialogHeader className="space-y-3">
          <div className="flex items-center gap-3">
            {errorDialog?.tone === 'info' ? (
              <Info className={cn('h-5 w-5', dialogToneIconClass.info)} />
            ) : (
              <AlertTriangle className={cn('h-5 w-5', dialogToneIconClass[errorDialog?.tone ?? 'danger'])} />
            )}
            <DialogTitle>{errorDialog?.title ?? ''}</DialogTitle>
          </div>
          <DialogDescription>{errorDialog?.description ?? ''}</DialogDescription>
          {errorDialog?.hint ? (
            <p className="text-sm text-muted-foreground">{errorDialog.hint}</p>
          ) : null}
        </DialogHeader>
        <DialogFooter>
          <Button onClick={() => setErrorDialog(null)}>{t('upload.dialogs.close')}</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );

const renderWithDialog = (content: ReactNode, wrapperClassName = 'space-y-6 pb-[120px]') => (
  <>
    <div className={wrapperClassName}>{content}</div>
    {errorDialogNode}
  </>
);

  if (loadingTask) {
    return renderWithDialog(
      <div className="flex flex-col items-center justify-center gap-4 text-center">
        <Loader2 className="h-10 w-10 animate-spin text-pink-500" />
        <p className="text-sm text-muted-foreground">{t('upload.preparing')}</p>
      </div>
    );
  }

  if (!canUpload) {
    return renderWithDialog(
      <Alert variant="destructive">
        <AlertTriangle className="h-4 w-4" />
        <AlertDescription>
          {t('upload.limitReached')
            .replace('{used}', `${eventPackage?.used_photos || 0}`)
            .replace('{max}', `${eventPackage?.package?.max_photos || 0}`)}
        </AlertDescription>
      </Alert>
    );
  }

  const renderPrimer = () => (
    showPrimer && (
      <motion.div
        className="rounded-[28px] border border-pink-200/60 bg-white/90 p-4 text-sm text-pink-900 shadow-lg dark:border-pink-500/40 dark:bg-pink-500/10 dark:text-pink-50"
        {...fadeUpMotion}
      >
        <div className="flex items-start gap-3">
          <Info className="mt-0.5 h-5 w-5 flex-shrink-0" />
          <div className="text-left">
            <p className="font-semibold">{t('upload.primer.title')}</p>
            <p className="mt-1">
              {t('upload.primer.body.part1')}{' '}
              {t('upload.primer.body.part2')}
            </p>
          </div>
          <Button variant="ghost" size="sm" onClick={dismissPrimer}>
            {t('upload.primer.dismiss')}
          </Button>
        </div>
      </motion.div>
    )
  );

  const renderPermissionNotice = () => {
    if (permissionState === 'granted') return null;

    const titles: Record<PermissionState, string> = {
      idle: t('upload.cameraDenied.title'),
      prompt: t('upload.cameraDenied.title'),
      granted: '',
      denied: t('upload.cameraDenied.title'),
      error: t('upload.cameraError.title'),
      unsupported: t('upload.cameraUnsupported.title'),
      blocked: t('upload.cameraBlocked.title'),
    };

    const fallbackMessages: Record<PermissionState, string> = {
      idle: t('upload.cameraDenied.prompt'),
      prompt: t('upload.cameraDenied.prompt'),
      granted: '',
      denied: t('upload.cameraDenied.explanation'),
      error: t('upload.cameraError.explanation'),
      unsupported: t('upload.cameraUnsupported.message'),
      blocked: t('upload.cameraBlocked.message'),
    };

    const title = titles[permissionState];
    const description = permissionMessage ?? fallbackMessages[permissionState];
    const canRetryCamera = permissionState !== 'unsupported' && permissionState !== 'blocked';
    const canRecheckCamera = permissionState === 'blocked';
    const helpText = permissionState === 'blocked'
      ? t('upload.cameraBlocked.hint')
      : permissionState === 'denied'
        ? t('upload.cameraDenied.hint')
        : permissionState === 'error'
          ? t('upload.cameraError.hint')
          : null;

    return (
      <motion.div
        className="rounded-[32px] border border-white/15 bg-white/85 p-5 text-slate-900 shadow-lg dark:border-white/10 dark:bg-white/5 dark:text-white"
        style={{ borderRadius: radius, fontFamily: bodyFont }}
        {...fadeUpMotion}
      >
        <div className="flex items-center gap-3">
          <div className="flex h-12 w-12 items-center justify-center rounded-2xl bg-slate-900/10 dark:bg-white/10">
            <Camera className="h-6 w-6" />
          </div>
          <div>
            <p className="text-sm font-semibold">{title}</p>
            <p className="text-xs text-slate-600 dark:text-white/70">{description}</p>
          </div>
        </div>
        {helpText ? (
          <p className="mt-3 text-xs text-slate-600 dark:text-white/70">{helpText}</p>
        ) : null}
        <div className="mt-4 flex flex-wrap gap-3">
          {canRetryCamera && (
            <Button
              onClick={startCamera}
              size="sm"
              style={buttonStyle === 'outline' ? { borderRadius: radius, background: 'transparent', color: linkColor, border: `1px solid ${linkColor}` } : { borderRadius: radius }}
            >
              {t('upload.buttons.startCamera')}
            </Button>
          )}
          {canRecheckCamera && (
            <Button
              onClick={handleRecheckCamera}
              size="sm"
              style={buttonStyle === 'outline'
                ? { borderRadius: radius, background: 'transparent', color: linkColor, border: `1px solid ${linkColor}` }
                : { borderRadius: radius }}
            >
              {t('upload.buttons.recheckCamera')}
            </Button>
          )}
          <Button
            variant="secondary"
            size="sm"
            onClick={() => fileInputRef.current?.click()}
            style={buttonStyle === 'outline' ? { borderRadius: radius, background: 'transparent', color: linkColor, border: `1px solid ${linkColor}` } : { borderRadius: radius }}
          >
            {t('upload.galleryButton')}
          </Button>
        </div>
      </motion.div>
    );
  };

  const isCountdownActive = mode === 'countdown';
  const countdownProgress = preferences.countdownEnabled && preferences.countdownSeconds > 0
    ? Math.max(0, Math.min(1, countdownValue / preferences.countdownSeconds))
    : 0;
  const countdownDegrees = Math.round(countdownProgress * 360);
  const controlIconButtonBase =
    'flex h-10 w-10 items-center justify-center rounded-full border border-white/25 bg-white/10 text-white shadow-sm backdrop-blur transition hover:border-white/40 hover:bg-white/15 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/60';
  const cameraControlsInset = 'calc(env(safe-area-inset-bottom, 0px) + 72px)';

  return renderWithDialog(
    <>
      <div
        ref={cameraShellRef as unknown as React.RefObject<HTMLDivElement>}
        className="relative flex min-h-screen flex-col gap-4 pb-[calc(env(safe-area-inset-bottom,0px)+72px)] pt-3"
        style={bodyFont ? { fontFamily: bodyFont } : undefined}
      >
        {taskFloatingCard}
        {heroOverlay}
        <section
          className="relative flex flex-col overflow-hidden border border-white/10 bg-black text-white shadow-2xl"
          style={{ borderRadius: radius }}
        >
        <div
          ref={cameraViewportRef}
          className="relative w-full"
          style={{
            height: `clamp(60vh, calc(var(--guest-viewport-height, 100dvh) - 220px - ${cameraControlsInset}), 82vh)`,
            minHeight: '60vh',
            maxHeight: '88vh',
          }}
        >
            <video
              ref={videoRef}
              className={cn(
                'absolute inset-0 h-full w-full object-cover transition-transform duration-200',
                preferences.facingMode === 'user' && preferences.mirrorFrontPreview ? '-scale-x-100' : 'scale-x-100',
                !isCameraActive && 'opacity-30'
              )}
              playsInline
              muted
            />

            {preferences.gridEnabled && (
              <div
                className="pointer-events-none absolute inset-0 z-10"
                style={{
                  backgroundImage:
                    'linear-gradient(90deg, rgba(255,255,255,0.25) 1px, transparent 1px), linear-gradient(0deg, rgba(255,255,255,0.25) 1px, transparent 1px)',
                  backgroundSize: '33.333% 100%, 100% 33.333%',
                }}
              />
            )}

            {!isCameraActive && (
              <div className="absolute left-4 top-4 z-20 flex items-center gap-2 rounded-full bg-black/70 px-3 py-1 text-xs font-semibold uppercase tracking-wide text-white">
                <Camera className="h-4 w-4 text-pink-400" />
                <span>
                  {permissionState === 'unsupported'
                    ? t('upload.cameraUnsupported.title')
                    : permissionState === 'blocked'
                      ? t('upload.cameraBlocked.title')
                    : t('upload.cameraDenied.title')}
                </span>
              </div>
            )}

            {permissionState !== 'granted' && (
              <div className="absolute inset-x-4 top-16 z-30 sm:top-20">
                {renderPermissionNotice()}
              </div>
            )}

            {mode === 'countdown' && (
              <div className="absolute inset-0 z-40 flex flex-col items-center justify-center bg-black/60 text-white">
                <div className="text-6xl font-bold">{countdownValue}</div>
                <p className="mt-2 text-sm text-white/70">{t('upload.countdownReady')}</p>
              </div>
            )}

            {mode === 'review' && reviewPhoto && (
              <div className="absolute inset-0 z-40 flex flex-col bg-black">
                <img src={reviewPhoto.dataUrl} alt="Aufgenommenes Foto" className="h-full w-full object-contain" />
              </div>
            )}

            <div className="pointer-events-none absolute inset-x-0 bottom-2 z-30 flex justify-center">
              <div
                className="pointer-events-auto flex items-center gap-2 rounded-full border border-white/20 bg-black/40 px-3 py-2 backdrop-blur"
                style={{ marginBottom: 'env(safe-area-inset-bottom, 0px)' }}
              >
                <Button
                  size="icon"
                  variant="ghost"
                  className={cn(
                    controlIconButtonBase,
                    preferences.gridEnabled && 'border-white bg-white text-black'
                  )}
                  onClick={handleToggleGrid}
                  title={t('upload.controls.toggleGrid')}
                  aria-pressed={preferences.gridEnabled}
                >
                  <Grid3X3 className="h-4 w-4" />
                  <span className="sr-only">{t('upload.controls.toggleGrid')}</span>
                </Button>

                <Button
                  size="icon"
                  variant="ghost"
                  className={cn(
                    controlIconButtonBase,
                    preferences.countdownEnabled && 'border-white bg-white text-black'
                  )}
                  onClick={handleToggleCountdown}
                  title={t('upload.countdownLabel').replace('{seconds}', `${preferences.countdownSeconds}`)}
                  aria-pressed={preferences.countdownEnabled}
                >
                  <Timer className="h-4 w-4" />
                  <span className="sr-only">
                    {t('upload.countdownLabel').replace('{seconds}', `${preferences.countdownSeconds}`)}
                  </span>
                </Button>

                {preferences.facingMode === 'user' && (
                  <Button
                    size="icon"
                    variant="ghost"
                    className={cn(
                      controlIconButtonBase,
                      preferences.mirrorFrontPreview && 'border-white bg-white text-black'
                    )}
                    onClick={handleToggleMirror}
                    title={t('upload.controls.toggleMirror')}
                    aria-pressed={preferences.mirrorFrontPreview}
                  >
                    <FlipHorizontal className="h-4 w-4" />
                    <span className="sr-only">{t('upload.controls.toggleMirror')}</span>
                  </Button>
                )}

                <Button
                  size="icon"
                  variant="ghost"
                  className={cn(
                    controlIconButtonBase,
                    preferences.flashPreferred && 'border-white bg-white text-black'
                  )}
                  onClick={handleToggleFlashPreference}
                  disabled={preferences.facingMode !== 'environment'}
                  title={t('upload.controls.toggleFlash')}
                  aria-pressed={preferences.flashPreferred}
                >
                  {preferences.flashPreferred ? <Zap className="h-4 w-4 text-yellow-300" /> : <ZapOff className="h-4 w-4" />}
                  <span className="sr-only">{t('upload.controls.toggleFlash')}</span>
                </Button>

                <Button
                  size="icon"
                  variant="ghost"
                  className={cn(
                    controlIconButtonBase,
                    immersiveMode && 'border-white bg-white text-black'
                  )}
                  onClick={handleToggleImmersive}
                  title={
                    immersiveMode
                      ? t('upload.controls.exitFullscreen', 'Menü einblenden')
                      : t('upload.controls.enterFullscreen', 'Vollbild')
                  }
                  aria-pressed={immersiveMode}
                >
                  <Menu className="h-4 w-4" />
                  <span className="sr-only">
                    {immersiveMode
                      ? t('upload.controls.exitFullscreen', 'Menü einblenden')
                      : t('upload.controls.enterFullscreen', 'Vollbild')}
                  </span>
                </Button>
              </div>
            </div>

            {mode === 'uploading' && (
              <div className="absolute inset-0 z-40 flex flex-col items-center justify-center gap-4 bg-black/80 text-white">
                <Loader2 className="h-10 w-10 animate-spin" />
                <div className="w-1/2 min-w-[200px] max-w-sm">
                  <div className="h-2 rounded-full bg-white/20">
                    <div
                      className="h-2 rounded-full bg-gradient-to-r from-pink-500 to-purple-500 transition-all"
                      style={{ width: `${uploadProgress}%` }}
                    />
                  </div>
                  {statusMessage && <p className="mt-2 text-center text-xs text-white/80">{statusMessage}</p>}
                </div>
              </div>
            )}
          </div>

          <div
            className="relative z-30 flex flex-col gap-4 bg-gradient-to-t from-black via-black/80 to-transparent p-4"
            style={{ fontFamily: bodyFont }}
          >
            {uploadWarning && (
              <Alert className="border-yellow-400/20 bg-yellow-500/10 text-white">
                <AlertDescription className="text-xs">
                  {uploadWarning}
                </AlertDescription>
              </Alert>
            )}
            {uploadError && (
              <Alert variant="destructive" className="bg-red-500/10 text-white">
                <AlertDescription className="flex items-center gap-2 text-xs">
                  <AlertTriangle className="h-4 w-4" />
                  {uploadError}
                </AlertDescription>
              </Alert>
            )}

            {showCelebration && (
              <div className="flex flex-wrap items-center justify-between gap-3 rounded-2xl border border-white/20 bg-white/10 px-4 py-3 text-sm text-white shadow-lg backdrop-blur">
                <div className="flex items-center gap-2">
                  <Sparkles className="h-4 w-4 text-amber-200" />
                  <p className="font-semibold">
                    {t('upload.taskInfo.completed', 'Aufgabe gelöst!')}
                  </p>
                </div>
                <Button
                  size="sm"
                  variant="secondary"
                  className="rounded-full border border-white/30 bg-white/80 text-slate-900 hover:bg-white"
                  onClick={() => navigate(tasksUrl)}
                >
                  {t('upload.taskInfo.nextPrompt', 'Gleich noch eine Aufgabe?')}
                </Button>
              </div>
            )}

            <div className="flex items-center justify-center gap-8">
              <Button
                variant="ghost"
                className="flex h-14 w-14 items-center justify-center rounded-full border border-white/25 bg-white/10 text-white shadow-sm backdrop-blur hover:border-white/40 hover:bg-white/15"
                onClick={() => fileInputRef.current?.click()}
              >
                <ImagePlus className="h-6 w-6" />
                <span className="sr-only">{t('upload.galleryButton')}</span>
              </Button>

              {mode === 'review' && reviewPhoto ? (
                <div className="flex w-full max-w-md flex-col gap-3">
                  {uploadsRequireApproval ? (
                    <div className="rounded-xl border border-amber-300/70 bg-amber-50/80 p-3 text-amber-900 shadow-sm backdrop-blur dark:border-amber-400/40 dark:bg-amber-500/10 dark:text-amber-50">
                      <p className="text-sm font-semibold">{t('upload.review.noticeTitle', 'Uploads werden geprüft')}</p>
                      <p className="text-xs">{t('upload.review.noticeBody', 'Dein Foto erscheint, sobald es freigegeben wurde.')}</p>
                    </div>
                  ) : null}
                  <div className="rounded-xl border border-white/20 bg-white/10 p-3 text-white shadow-sm backdrop-blur">
                    <div className="flex items-start justify-between gap-3">
                      <div>
                        <p className="text-sm font-semibold">{t('upload.liveShow.title', 'Live-Show')}</p>
                        <p className="text-xs text-white/70">
                          {t('upload.liveShow.description', 'Zeige dieses Foto direkt auf der Live-Show.')}
                        </p>
                      </div>
                      <Switch
                        checked={submitToLive}
                        onCheckedChange={(checked) => setSubmitToLive(checked)}
                        aria-label={t('upload.liveShow.toggle', 'Live-Show aktivieren')}
                      />
                    </div>
                    <p className="mt-2 text-[11px] text-white/70">
                      {liveShowModeration === 'off'
                        ? t('upload.liveShow.immediate', 'Erscheint sofort auf der Leinwand.')
                        : t('upload.liveShow.reviewed', 'Wird nach Freigabe für die Live-Show angezeigt.')}
                    </p>
                  </div>
                  <div className="flex flex-col gap-3 sm:flex-row">
                    <Button variant="secondary" className="flex-1" onClick={handleRetake}>
                      {t('upload.review.retake')}
                    </Button>
                    <Button
                      className="flex-1 animate-pulse bg-pink-500 text-white shadow-lg hover:bg-pink-600 focus-visible:ring-pink-300"
                      onClick={handleUsePhoto}
                    >
                      {t('upload.review.keep')}
                    </Button>
                  </div>
                </div>
              ) : (
                <div className="relative flex h-24 w-24 items-center justify-center">
                  {!isCountdownActive && mode !== 'uploading' && (
                    <span className="pointer-events-none absolute inset-0 rounded-full border border-white/30 opacity-60 animate-ping" />
                  )}
                  {isCountdownActive && (
                    <div
                      className="absolute inset-1 rounded-full"
                      style={{
                        background: `conic-gradient(#fff ${countdownDegrees}deg, rgba(255,255,255,0.12) ${countdownDegrees}deg)`,
                      }}
                    />
                  )}
                  <div className="absolute inset-2 rounded-full bg-black/70 shadow-[0_10px_40px_rgba(0,0,0,0.45)] backdrop-blur" />
                  <Button
                    size="lg"
                    className="relative z-10 flex h-20 w-20 items-center justify-center rounded-full border-4 border-white/40 text-white shadow-2xl"
                    onClick={handlePrimaryAction}
                    disabled={mode === 'uploading' || isCountdownActive}
                    style={{
                      background: `radial-gradient(circle at 20% 20%, ${branding.secondaryColor}, ${branding.primaryColor})`,
                      boxShadow: `0 18px 36px ${branding.primaryColor}55`,
                    }}
                  >
                    {isCountdownActive ? (
                      <span className="text-3xl font-bold leading-none">{countdownValue}</span>
                    ) : mode === 'uploading' ? (
                      <Loader2 className="h-9 w-9 animate-spin" />
                    ) : (
                      <Camera className="h-8 w-8 sm:h-10 sm:w-10" style={{ height: '32px', width: '32px' }} />
                    )}
                    <span className="sr-only">
                      {isCameraActive ? t('upload.captureButton') : t('upload.buttons.startCamera')}
                    </span>
                  </Button>
                </div>
              )}

              <Button
                variant="ghost"
                className="flex h-14 w-14 items-center justify-center rounded-full border border-white/25 bg-white/10 text-white shadow-sm backdrop-blur hover:border-white/40 hover:bg-white/15"
                onClick={handleSwitchCamera}
              >
                <RotateCcw className="h-6 w-6" />
                <span className="sr-only">{t('upload.switchCamera')}</span>
              </Button>
            </div>
          </div>
        </section>
      </div>

      {socialChips.length > 0 && (
        <>
          <div ref={navSentinelRef} data-testid="nav-visibility-sentinel" className="h-px w-full" />
          <div ref={kpiChipsRef} data-testid="upload-kpi-chips" className="mt-4 flex gap-3 overflow-x-auto pb-2">
            {socialChips.map((chip) => (
              <div
                key={chip.id}
                className="shrink-0 rounded-full border border-white/15 bg-white/80 px-4 py-2 text-xs font-semibold text-slate-800 shadow dark:border-white/10 dark:bg-white/10 dark:text-white"
              >
                <span className="block text-[10px] uppercase tracking-wide opacity-70">{chip.label}</span>
                <span className="text-sm">{chip.value}</span>
              </div>
            ))}
          </div>
        </>
      )}

      {renderPrimer()}

        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          className="hidden"
          onChange={handleGalleryPick}
        />

        <div ref={liveRegionRef} className="sr-only" aria-live="assertive" />

        <canvas ref={canvasRef} className="hidden" />
      </>
    ,
    'space-y-6 pb-[140px]'
  );
}

function readAsDataUrl(file: File): Promise<string> {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = () => reject(reader.error ?? new Error('Failed to read file'));
    reader.readAsDataURL(file);
  });
}

function formatRelativeTimeLabel(value: string | null | undefined, t: TranslateFn): string {
  if (!value) {
    return t('upload.hud.relative.now');
  }
  const timestamp = new Date(value).getTime();
  if (Number.isNaN(timestamp)) {
    return t('upload.hud.relative.now');
  }
  const diffMinutes = Math.max(0, Math.round((Date.now() - timestamp) / 60000));
  if (diffMinutes < 1) {
    return t('upload.hud.relative.now');
  }
  if (diffMinutes < 60) {
    return t('upload.hud.relative.minutes').replace('{count}', `${diffMinutes}`);
  }
  const hours = Math.round(diffMinutes / 60);
  if (hours < 24) {
    return t('upload.hud.relative.hours').replace('{count}', `${hours}`);
  }
  const days = Math.round(hours / 24);
  return t('upload.hud.relative.days').replace('{count}', `${days}`);
}
