﻿import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { Sparkles, RefreshCw, Smile, Camera, Timer as TimerIcon, Heart, ChevronRight, CheckCircle2 } from 'lucide-react';
import type { LucideIcon } from 'lucide-react';
import { useGuestTaskProgress } from '../hooks/useGuestTaskProgress';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { cn } from '@/lib/utils';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import EmotionPicker from '../components/EmotionPicker';
import { useEventBranding } from '../context/EventBrandingContext';
import { useTranslation, type TranslateFn } from '../i18n/useTranslation';

interface Task {
  id: number;
  title: string;
  description: string;
  instructions: string;
  duration: number; // minutes
  emotion?: {
    slug: string;
    name: string;
  };
  is_completed: boolean;
}

type EmotionOption = {
  slug: string;
  name: string;
};

type EventPhoto = {
  id: number;
  thumbnail_path?: string | null;
  file_path?: string | null;
  likes_count?: number | null;
  task_id?: number | null;
};

const SWIPE_THRESHOLD_PX = 40;
const SIMILAR_PHOTO_LIMIT = 6;
type EmotionTheme = {
  gradientClass: string;
  gradientBackground: string;
  suggestionGradient: string;
  suggestionBorder: string;
};

type EmotionIdentity = {
  slug?: string | null;
  name?: string | null;
};

const themeFreude: EmotionTheme = {
  gradientClass: 'from-amber-300 via-orange-400 to-rose-500',
  gradientBackground: 'linear-gradient(135deg, #fde68a, #fb923c, #fb7185)',
  suggestionGradient: 'from-amber-50 via-white to-orange-50 dark:from-amber-500/20 dark:via-gray-900 dark:to-orange-500/10',
  suggestionBorder: 'border-amber-200/60 dark:border-amber-400/30',
};
const themeLiebe: EmotionTheme = {
  gradientClass: 'from-rose-400 via-fuchsia-500 to-purple-600',
  gradientBackground: 'linear-gradient(135deg, #fb7185, #ec4899, #9333ea)',
  suggestionGradient: 'from-rose-50 via-white to-fuchsia-50 dark:from-rose-500/20 dark:via-gray-900 dark:to-fuchsia-500/10',
  suggestionBorder: 'border-rose-200/60 dark:border-rose-400/30',
};
const themeEkstase: EmotionTheme = {
  gradientClass: 'from-fuchsia-400 via-purple-500 to-indigo-500',
  gradientBackground: 'linear-gradient(135deg, #f472b6, #a855f7, #6366f1)',
  suggestionGradient: 'from-fuchsia-50 via-white to-indigo-50 dark:from-fuchsia-500/20 dark:via-gray-900 dark:to-indigo-500/10',
  suggestionBorder: 'border-fuchsia-200/60 dark:border-fuchsia-400/30',
};
const themeEntspannt: EmotionTheme = {
  gradientClass: 'from-teal-300 via-emerald-400 to-cyan-500',
  gradientBackground: 'linear-gradient(135deg, #5eead4, #34d399, #22d3ee)',
  suggestionGradient: 'from-teal-50 via-white to-emerald-50 dark:from-teal-500/20 dark:via-gray-900 dark:to-emerald-500/10',
  suggestionBorder: 'border-emerald-200/60 dark:border-emerald-400/30',
};
const themeBesinnlich: EmotionTheme = {
  gradientClass: 'from-slate-500 via-blue-500 to-indigo-600',
  gradientBackground: 'linear-gradient(135deg, #64748b, #3b82f6, #4f46e5)',
  suggestionGradient: 'from-slate-50 via-white to-blue-50 dark:from-slate-600/20 dark:via-gray-900 dark:to-blue-500/10',
  suggestionBorder: 'border-slate-200/60 dark:border-slate-500/30',
};
const themeUeberraschung: EmotionTheme = {
  gradientClass: 'from-indigo-300 via-violet-500 to-rose-500',
  gradientBackground: 'linear-gradient(135deg, #a5b4fc, #a855f7, #fb7185)',
  suggestionGradient: 'from-indigo-50 via-white to-violet-50 dark:from-indigo-500/20 dark:via-gray-900 dark:to-violet-500/10',
  suggestionBorder: 'border-indigo-200/60 dark:border-indigo-400/30',
};
const themeDefault: EmotionTheme = {
  gradientClass: 'from-pink-500 via-purple-500 to-indigo-600',
  gradientBackground: 'linear-gradient(135deg, #ec4899, #a855f7, #4f46e5)',
  suggestionGradient: 'from-pink-50 via-white to-indigo-50 dark:from-pink-500/20 dark:via-gray-900 dark:to-indigo-500/10',
  suggestionBorder: 'border-pink-200/60 dark:border-pink-400/30',
};

const EMOTION_THEMES: Record<string, EmotionTheme> = {
  freude: themeFreude,
  happy: themeFreude,
  liebe: themeLiebe,
  romance: themeLiebe,
  romantik: themeLiebe,
  nostalgie: themeEntspannt,
  relaxed: themeEntspannt,
  ruehrung: themeBesinnlich,
  traurigkeit: themeBesinnlich,
  teamgeist: themeFreude,
  gemeinschaft: themeFreude,
  ueberraschung: themeUeberraschung,
  surprise: themeUeberraschung,
  ekstase: themeEkstase,
  excited: themeEkstase,
  besinnlichkeit: themeBesinnlich,
  sad: themeBesinnlich,
  default: themeDefault,
};

const EMOTION_ICONS: Record<string, string> = {
  freude: '😊',
  happy: '😊',
  liebe: '❤️',
  romantik: '💞',
  nostalgie: '📼',
  ruehrung: '🥲',
  teamgeist: '🤝',
  ueberraschung: '😲',
  surprise: '😲',
  ekstase: '🤩',
  besinnlichkeit: '🕯️',
};

function sluggify(value?: string | null): string {
  return (value ?? '')
    .toString()
    .toLowerCase()
    .normalize('NFD')
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9]+/g, '')
    .trim();
}

function resolveEmotionKey(identity?: EmotionIdentity | null): string {
  if (!identity) return 'default';
  const nameKey = sluggify(identity.name);
  if (nameKey && EMOTION_THEMES[nameKey]) {
    return nameKey;
  }
  const slugKey = sluggify(identity.slug);
  if (slugKey && EMOTION_THEMES[slugKey]) {
    return slugKey;
  }
  return 'default';
}

function getEmotionTheme(identity?: EmotionIdentity | null): EmotionTheme {
  const key = resolveEmotionKey(identity);
  return EMOTION_THEMES[key] ?? themeDefault;
}

function getEmotionIcon(identity?: EmotionIdentity | null): string {
  const key = resolveEmotionKey(identity);
  return EMOTION_ICONS[key] ?? '✨';
}

export default function TaskPickerPage() {
  const { token } = useParams<{ token: string }>();
  const eventKey = token ?? '';
  const navigate = useNavigate();
  const [searchParams, setSearchParams] = useSearchParams();
  const { branding } = useEventBranding();
  const { t, locale } = useTranslation();

  const { completedCount, isCompleted } = useGuestTaskProgress(eventKey);

  const [tasks, setTasks] = React.useState<Task[]>([]);
  const [currentTask, setCurrentTask] = React.useState<Task | null>(null);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [selectedEmotion, setSelectedEmotion] = React.useState<string>('all');
  const [isFetching, setIsFetching] = React.useState(false);
  const [photoPool, setPhotoPool] = React.useState<EventPhoto[]>([]);
  const [photoPoolLoading, setPhotoPoolLoading] = React.useState(false);
  const [photoPoolError, setPhotoPoolError] = React.useState<string | null>(null);
  const [hasSwiped, setHasSwiped] = React.useState(false);
  const [emotionPickerOpen, setEmotionPickerOpen] = React.useState(false);
  const [recentEmotionSlug, setRecentEmotionSlug] = React.useState<string | null>(null);

  const heroCardRef = React.useRef<HTMLDivElement | null>(null);

  const cameraButtonStyle = React.useMemo(() => ({
    background: `radial-gradient(circle at 20% 20%, ${branding.secondaryColor}, ${branding.primaryColor})`,
    boxShadow: `0 18px 30px ${branding.primaryColor}44`,
    color: '#ffffff',
  }), [branding.primaryColor, branding.secondaryColor]);

  const recentTaskIdsRef = React.useRef<number[]>([]);
  const tasksCacheRef = React.useRef<Map<string, { data: Task[]; etag?: string | null }>>(new Map());
  const initialEmotionRef = React.useRef(false);

  const fetchTasks = React.useCallback(async () => {
    if (!eventKey) return;
    const cacheKey = `${eventKey}:${locale}`;
    const cached = tasksCacheRef.current.get(cacheKey);
    setIsFetching(true);
    setLoading(!cached);
    setError(null);

    if (cached) {
      setTasks(cached.data);
    }

    try {
      const headers: HeadersInit = {
        Accept: 'application/json',
        'X-Locale': locale,
      };

      if (cached?.etag) {
        headers['If-None-Match'] = cached.etag;
      }

      const response = await fetch(
        `/api/v1/events/${encodeURIComponent(eventKey)}/tasks?locale=${encodeURIComponent(locale)}`,
        { headers }
      );

      if (response.status === 304 && cached) {
        return;
      }

      if (!response.ok) throw new Error('Aufgaben konnten nicht geladen werden.');
      const payload = await response.json();
      if (Array.isArray(payload)) {
        const entry = { data: payload, etag: response.headers.get('ETag') };
        tasksCacheRef.current.set(cacheKey, entry);
        setTasks(payload);
      } else {
        tasksCacheRef.current.set(cacheKey, { data: [], etag: response.headers.get('ETag') });
        setTasks([]);
      }
    } catch (err) {
      console.error('Failed to load tasks', err);
      setError(err instanceof Error ? err.message : 'Unbekannter Fehler');
      if (!cached) {
        setTasks([]);
      }
    } finally {
      setIsFetching(false);
      setLoading(false);
    }
  }, [eventKey, locale]);

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

  React.useEffect(() => {
    if (initialEmotionRef.current) return;
    const queryEmotion = searchParams.get('emotion');
    if (queryEmotion) {
      setSelectedEmotion(queryEmotion);
    }
    initialEmotionRef.current = true;
  }, [searchParams]);

  const emotionOptions = React.useMemo<EmotionOption[]>(() => {
    const map = new Map<string, string>();
    tasks.forEach((task) => {
      if (task.emotion?.slug) {
        map.set(task.emotion.slug, task.emotion.name);
      }
    });
    return Array.from(map.entries()).map(([slugValue, name]) => ({ slug: slugValue, name }));
  }, [tasks]);

  const emotionCounts = React.useMemo(() => {
    const map = new Map<string, number>();
    tasks.forEach((task) => {
      const slugValue = task.emotion?.slug;
      if (!slugValue) return;
      map.set(slugValue, (map.get(slugValue) ?? 0) + 1);
    });
    return map;
  }, [tasks]);

  const filteredTasks = React.useMemo(() => {
    if (selectedEmotion === 'all') return tasks;
    return tasks.filter((task) => task.emotion?.slug === selectedEmotion);
  }, [tasks, selectedEmotion]);

  const alternativeTasks = React.useMemo(() => {
    return filteredTasks.filter((task) => task.id !== currentTask?.id).slice(0, 6);
  }, [filteredTasks, currentTask]);

  const selectRandomTask = React.useCallback(
    (list: Task[]) => {
      if (!list.length) {
        setCurrentTask(null);
        return;
      }
      const avoidIds = recentTaskIdsRef.current;
      const available = list.filter((task) => !isCompleted(task.id));
      const base = available.length ? available : list;
      let candidates = base.filter((task) => !avoidIds.includes(task.id));
      if (!candidates.length) {
        candidates = base;
      }
      const chosen = candidates[Math.floor(Math.random() * candidates.length)];
      setCurrentTask(chosen);
      recentTaskIdsRef.current = [...avoidIds.filter((id) => id !== chosen.id), chosen.id].slice(-3);
    },
    [isCompleted]
  );

  const handleSelectEmotion = React.useCallback(
    (slugValue: string) => {
      setSelectedEmotion(slugValue);
      const next = new URLSearchParams(searchParams.toString());
      if (slugValue === 'all') {
        next.delete('emotion');
      } else {
        next.set('emotion', slugValue);
        setRecentEmotionSlug(slugValue);
      }
      setSearchParams(next, { replace: true });
    },
    [searchParams, setSearchParams]
  );

  const handleNewTask = React.useCallback(() => {
    selectRandomTask(filteredTasks);
  }, [filteredTasks, selectRandomTask]);

  const handleStartUpload = () => {
    if (!currentTask || !eventKey) return;
    navigate(`/e/${encodeURIComponent(eventKey)}/upload?task=${currentTask.id}&emotion=${currentTask.emotion?.slug || ''}`);
  };

  const handleViewSimilar = React.useCallback(() => {
    if (!currentTask || !eventKey) return;
    navigate(`/e/${encodeURIComponent(eventKey)}/gallery?task=${currentTask.id}`);
  }, [currentTask, eventKey, navigate]);

  const handleSelectTask = React.useCallback((task: Task) => {
    setCurrentTask(task);
  }, []);

  const handleRetryFetch = () => {
    fetchTasks();
  };

  const handlePhotoPreview = React.useCallback(
    (photoId: number) => {
      if (!eventKey) return;
      navigate(`/e/${encodeURIComponent(eventKey)}/gallery?photoId=${photoId}&task=${currentTask?.id ?? ''}`);
    },
    [eventKey, navigate, currentTask?.id]
  );

  React.useEffect(() => {
    if (!filteredTasks.length) {
      setCurrentTask(null);
      return;
    }
    if (!currentTask || !filteredTasks.some((task) => task.id === currentTask.id)) {
      selectRandomTask(filteredTasks);
    }
  }, [filteredTasks, currentTask, selectRandomTask]);

  React.useEffect(() => {
    if (currentTask?.emotion?.slug) {
      setRecentEmotionSlug(currentTask.emotion.slug);
    }
  }, [currentTask?.emotion?.slug]);

  React.useEffect(() => {
    if (!eventKey || photoPool.length) return;
    const controller = new AbortController();
    setPhotoPoolLoading(true);
    setPhotoPoolError(null);
    fetch(`/api/v1/events/${encodeURIComponent(eventKey)}/photos?locale=${encodeURIComponent(locale)}`, {
      signal: controller.signal,
      headers: {
        Accept: 'application/json',
        'X-Locale': locale,
      },
    })
      .then((res) => {
        if (!res.ok) {
          throw new Error(t('tasks.page.inspirationError'));
        }
        return res.json();
      })
      .then((payload) => {
        const data = Array.isArray(payload?.data) ? (payload.data as EventPhoto[]) : [];
        setPhotoPool(data);
      })
      .catch((err) => {
        if (controller.signal.aborted) return;
        console.error('Failed to load photos', err);
        setPhotoPoolError(t('tasks.page.inspirationError'));
      })
      .finally(() => {
        if (!controller.signal.aborted) {
          setPhotoPoolLoading(false);
        }
      });

    return () => controller.abort();
  }, [eventKey, photoPool.length, t, locale]);

  const similarPhotos = React.useMemo(() => {
    if (!currentTask) return [];
    const matches = photoPool.filter((photo) => photo.task_id === currentTask.id);
    return matches.slice(0, SIMILAR_PHOTO_LIMIT);
  }, [photoPool, currentTask]);

  React.useEffect(() => {
    const card = heroCardRef.current;
    if (!card) return;
    let startX: number | null = null;
    let startY: number | null = null;

    const onTouchStart = (event: TouchEvent) => {
      const touch = event.touches[0];
      startX = touch.clientX;
      startY = touch.clientY;
    };

    const onTouchEnd = (event: TouchEvent) => {
      if (startX === null || startY === null) return;
      const touch = event.changedTouches[0];
      const deltaX = touch.clientX - startX;
      const deltaY = touch.clientY - startY;
      if (Math.abs(deltaX) > SWIPE_THRESHOLD_PX && Math.abs(deltaY) < 60) {
        if (deltaX < 0) {
          handleNewTask();
        } else {
          handleViewSimilar();
        }
        setHasSwiped(true);
      }
      startX = null;
      startY = null;
    };

    card.addEventListener('touchstart', onTouchStart, { passive: true });
    card.addEventListener('touchend', onTouchEnd);
    return () => {
      card.removeEventListener('touchstart', onTouchStart);
      card.removeEventListener('touchend', onTouchEnd);
    };
  }, [handleNewTask, handleViewSimilar]);

  const emptyState = !loading && (!filteredTasks.length || !currentTask);
  const heroTheme = React.useMemo(() => getEmotionTheme(currentTask?.emotion ?? null), [currentTask?.emotion]);
  const heroEmotionIcon = getEmotionIcon(currentTask?.emotion ?? null);
  const recentEmotionOption = React.useMemo(
    () => emotionOptions.find((option) => option.slug === recentEmotionSlug) ?? null,
    [emotionOptions, recentEmotionSlug]
  );
  const toggleValue = selectedEmotion === 'all' ? 'none' : 'recent';

  const handleToggleChange = React.useCallback(
    (value: string) => {
      if (!value) return;
      if (value === 'picker') {
        setEmotionPickerOpen(true);
        return;
      }
      if (value === 'none') {
        handleSelectEmotion('all');
        return;
      }
      if (value === 'recent') {
        if (recentEmotionSlug) {
          handleSelectEmotion(recentEmotionSlug);
        } else {
          setEmotionPickerOpen(true);
        }
      }
    },
    [handleSelectEmotion, recentEmotionSlug]
  );

  return (
    <>
      <div className="space-y-6">
      <header className="space-y-4">
        <div className="space-y-1">
          <p className="text-[11px] uppercase tracking-[0.4em] text-muted-foreground">{t('tasks.page.eyebrow')}</p>
          <h1 className="text-2xl font-semibold text-foreground">{t('tasks.page.title')}</h1>
          <p className="text-sm text-muted-foreground">{t('tasks.page.subtitle')}</p>
        </div>
        {emotionOptions.length > 0 && (
          <div className="overflow-x-auto pb-1 [-ms-overflow-style:none] [scrollbar-width:none]">
            <ToggleGroup
              type="single"
              aria-label="Stimmung filtern"
              value={toggleValue}
              onValueChange={handleToggleChange}
              className="inline-flex gap-1 rounded-full bg-muted/60 p-1"
              variant="outline"
              size="sm"
            >
              <ToggleGroupItem
                value="none"
                className="rounded-full !rounded-full px-4 py-2 text-sm font-medium first:!rounded-full last:!rounded-full"
              >
                <span className="mr-2">🎲</span>
                {t('tasks.page.filters.none')}
              </ToggleGroupItem>
              <ToggleGroupItem
                value="recent"
                disabled={!recentEmotionOption}
                className="rounded-full !rounded-full px-4 py-2 text-sm font-medium first:!rounded-full last:!rounded-full"
              >
                <span className="mr-2">{getEmotionIcon(recentEmotionOption)}</span>
                {recentEmotionOption?.name ?? t('tasks.page.filters.recentFallback')}
              </ToggleGroupItem>
              <ToggleGroupItem
                value="picker"
                className="rounded-full !rounded-full px-4 py-2 text-sm font-medium first:!rounded-full last:!rounded-full"
              >
                <span className="mr-2">🗂️</span>
                {t('tasks.page.filters.showAll')}
              </ToggleGroupItem>
            </ToggleGroup>
          </div>
        )}
      </header>

      {loading && (
        <div className="space-y-4">
          <SkeletonBlock />
          <SkeletonBlock />
        </div>
      )}

      {error && !loading && (
        <Alert variant="destructive">
          <AlertDescription className="flex items-center justify-between gap-3">
            <span>{error}</span>
            <Button variant="outline" size="sm" onClick={handleRetryFetch} disabled={isFetching}>
              Erneut versuchen
            </Button>
          </AlertDescription>
        </Alert>
      )}

      {emptyState && (
        <EmptyState
          hasTasks={Boolean(tasks.length)}
          onRetry={handleRetryFetch}
          emotionOptions={emotionOptions}
          onEmotionSelect={handleSelectEmotion}
          t={t}
        />
      )}

      {!emptyState && currentTask && (
        <div className="space-y-8">
          <section
            ref={heroCardRef}
            className={cn(
              'relative overflow-hidden rounded-3xl p-5 text-white shadow-lg transition-[background] duration-700',
              'bg-gradient-to-br',
              heroTheme.gradientClass
            )}
            style={{ background: heroTheme.gradientBackground }}
          >
            <div className="relative space-y-5">
              <div className="flex flex-wrap items-center justify-between gap-3 text-xs font-semibold uppercase tracking-[0.25em] text-white/70">
                <span className="flex items-center gap-2 tracking-[0.3em]">
                  <Sparkles className="h-4 w-4" />
                  {heroEmotionIcon} {currentTask.emotion?.name ?? 'Neue Mission'}
                </span>
                <span className="flex items-center gap-1 text-white tracking-normal">
                  <TimerIcon className="h-4 w-4" />
                  {currentTask.duration} Min
                </span>
              </div>

              <div className="space-y-3">
                <h2 className="text-3xl font-semibold leading-tight drop-shadow-sm">{currentTask.title}</h2>
                <p className="text-sm leading-relaxed text-white/80">{currentTask.description}</p>
              </div>

              {!hasSwiped && (
                <p className="text-[11px] uppercase tracking-[0.4em] text-white/70">
                  {t('tasks.page.swipeHint')}
                </p>
              )}

              {currentTask.instructions && (
                <div className="rounded-2xl bg-white/15 p-3 text-sm font-medium text-white/90">
                  {currentTask.instructions}
                </div>
              )}

              <div className="flex flex-wrap gap-2 text-sm text-white/80">
                {isCompleted(currentTask.id) && (
                  <span className="rounded-full border border-white/30 px-3 py-1">
                    <CheckCircle2 className="mr-1 inline h-4 w-4" />
                    {t('tasks.page.completedLabel')}
                  </span>
                )}
              </div>

              <div className="grid grid-cols-3 gap-3">
                <Button
                  onClick={handleStartUpload}
                  className="col-span-2 flex h-14 items-center justify-center gap-2 rounded-2xl text-base font-semibold text-white shadow-lg shadow-black/10 transition hover:scale-[1.01]"
                  style={cameraButtonStyle}
                >
                  <Camera className="h-6 w-6" />
                  {t('tasks.page.ctaStart')}
                </Button>
                <HeroActionButton
                  icon={RefreshCw}
                  label={t('tasks.page.shuffleCta')}
                  onClick={handleNewTask}
                  className="h-12 justify-center px-3 py-2"
                />
              </div>

              {(photoPoolLoading || photoPoolError || similarPhotos.length > 0) && (
                <div className="space-y-2 rounded-2xl border border-white/25 bg-white/10 p-3">
                  <div className="flex items-center justify-between text-xs font-semibold uppercase tracking-[0.3em] text-white/70">
                    <span>{t('tasks.page.inspirationTitle')}</span>
                    {photoPoolLoading && <span className="text-[10px] text-white/70">{t('tasks.page.inspirationLoading')}</span>}
                  </div>
                  {photoPoolError && similarPhotos.length === 0 ? (
                    <p className="text-xs text-white/80">{photoPoolError}</p>
                  ) : similarPhotos.length > 0 ? (
                    <div className="flex gap-3 overflow-x-auto pb-2 [-ms-overflow-style:none] [scrollbar-width:none]">
                      {similarPhotos.map((photo) => (
                        <SimilarPhotoChip key={photo.id} photo={photo} onOpen={handlePhotoPreview} />
                      ))}
                      <button
                        type="button"
                        onClick={handleViewSimilar}
                        className="flex h-16 min-w-[64px] flex-col items-center justify-center rounded-2xl border border-dashed border-white/40 px-3 text-center text-[11px] font-semibold uppercase tracking-[0.3em] text-white/80"
                      >
                        {t('tasks.page.inspirationMore')}
                      </button>
                    </div>
                  ) : (
                    <button
                      type="button"
                      onClick={handleStartUpload}
                      className="flex items-center justify-between rounded-2xl border border-white/30 bg-white/10 px-4 py-3 text-sm text-white/80 transition hover:bg-white/20"
                    >
                      <div className="text-left">
                        <p className="font-semibold">{t('tasks.page.inspirationEmptyTitle')}</p>
                        <p className="text-xs text-white/70">{t('tasks.page.inspirationEmptyDescription')}</p>
                      </div>
                      <Camera className="h-4 w-4" />
                    </button>
                  )}
                </div>
              )}
            </div>
          </section>

          {alternativeTasks.length > 0 && (
            <section className="space-y-3">
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm uppercase tracking-[0.2em] text-muted-foreground">{t('tasks.page.suggestionsEyebrow')}</p>
                  <h2 className="text-lg font-semibold text-foreground">{t('tasks.page.suggestionsTitle')}</h2>
                </div>
                <Button variant="outline" size="sm" onClick={handleNewTask} className="shrink-0">
                  {t('tasks.page.shuffleButton')}
                </Button>
              </div>
              <div className="flex gap-3 overflow-x-auto pb-2 [-ms-overflow-style:none] [scrollbar-width:none]">
                {alternativeTasks.map((task) => (
                  <TaskSuggestionCard key={task.id} task={task} onSelect={handleSelectTask} />
                ))}
              </div>
            </section>
          )}
        </div>
      )}

      {!loading && !tasks.length && !error && (
        <Alert>
          <AlertDescription>{t('tasks.page.noTasksAlert')}</AlertDescription>
        </Alert>
      )}
      </div>
      <Dialog open={emotionPickerOpen} onOpenChange={setEmotionPickerOpen}>
        <DialogContent className="max-h-[90vh] overflow-y-auto" hideClose>
          <DialogHeader>
            <DialogTitle>{t('tasks.page.filters.dialogTitle')}</DialogTitle>
          </DialogHeader>
          {emotionOptions.length ? (
            <div className="grid gap-3 sm:grid-cols-2">
              {emotionOptions.map((emotion) => {
                const count = emotionCounts.get(emotion.slug) ?? 0;
                return (
                  <button
                    key={emotion.slug}
                    type="button"
                    onClick={() => {
                      handleSelectEmotion(emotion.slug);
                      setEmotionPickerOpen(false);
                    }}
                    className="flex items-center gap-3 rounded-2xl border border-muted/50 px-4 py-3 text-left transition hover:border-pink-300"
                  >
                    <span className="text-2xl" aria-hidden>
                      {getEmotionIcon(emotion)}
                    </span>
                    <div>
                      <p className="font-semibold text-foreground">{emotion.name}</p>
                      <p className="text-xs text-muted-foreground">
                        {count === 1
                          ? t('tasks.page.filters.countOne', { count })
                          : t('tasks.page.filters.countMany', { count })}
                      </p>
                    </div>
                  </button>
                );
              })}
            </div>
          ) : (
            <p className="text-sm text-muted-foreground">{t('tasks.page.filters.empty')}</p>
          )}
        </DialogContent>
      </Dialog>
    </>
  );
}

function SkeletonBlock() {
  return <div className="h-24 animate-pulse rounded-xl bg-muted/60" />;
}

function EmptyState({
  hasTasks,
  onRetry,
  emotionOptions,
  onEmotionSelect,
  t,
}: {
  hasTasks: boolean;
  onRetry: () => void;
  emotionOptions: EmotionOption[];
  onEmotionSelect: (slug: string) => void;
  t: TranslateFn;
}) {
  return (
    <div className="flex flex-col items-center justify-center gap-4 rounded-2xl border border-dashed border-muted-foreground/30 bg-muted/20 p-8 text-center">
      <Smile className="h-12 w-12 text-pink-500" aria-hidden />
      <div className="space-y-2">
        <h2 className="text-xl font-semibold">{t('tasks.page.emptyTitle')}</h2>
        <p className="text-sm text-muted-foreground">
          {hasTasks ? t('tasks.page.emptyDescriptionWithTasks') : t('tasks.page.emptyDescriptionNoTasks')}
        </p>
      </div>
      {hasTasks && emotionOptions.length > 0 && (
        <div className="grid w-full max-w-md grid-cols-2 gap-2 sm:grid-cols-3">
          {emotionOptions.map((emotion) => (
            <button
              key={emotion.slug}
              type="button"
              onClick={() => onEmotionSelect(emotion.slug)}
              className="rounded-full border border-border px-4 py-1 text-sm text-muted-foreground transition hover:border-pink-400 hover:text-foreground"
            >
              {emotion.name}
            </button>
          ))}
        </div>
      )}
      <Button onClick={onRetry} variant="outline" className="mt-2">
        {t('tasks.page.reloadButton')}
      </Button>
    </div>
  );
}

function HeroActionButton({
  icon: Icon,
  label,
  detail,
  onClick,
  className,
}: {
  icon: LucideIcon;
  label: string;
  detail?: string;
  onClick: () => void;
  className?: string;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      className={cn('flex flex-col rounded-2xl border border-white/30 bg-white/10 px-4 py-3 text-left text-sm font-medium text-white transition hover:bg-white/20', className)}
    >
      <span className="flex items-center gap-2 text-base font-semibold">
        <Icon className="h-4 w-4" />
        {label}
      </span>
      {detail && <span className="mt-1 text-xs text-white/80">{detail}</span>}
    </button>
  );
}

function SimilarPhotoChip({ photo, onOpen }: { photo: EventPhoto; onOpen: (photoId: number) => void }) {
  const cover = photo.thumbnail_path || photo.file_path || '';
  return (
    <button
      type="button"
      onClick={() => onOpen(photo.id)}
      className="relative h-16 w-16 overflow-hidden rounded-2xl border border-white/30 bg-white/10"
    >
      {cover ? (
        <img
          src={cover}
          alt="Eventfoto"
          className="h-full w-full object-cover"
          loading="lazy"
          decoding="async"
        />
      ) : (
        <div className="flex h-full w-full items-center justify-center text-[10px] font-semibold uppercase tracking-[0.3em] text-white/70">
          Foto
        </div>
      )}
      <div className="absolute bottom-1 left-1 flex items-center gap-1 rounded-full bg-black/60 px-1.5 py-0.5 text-[10px] font-semibold text-white">
        <Heart className="h-3 w-3" />
        <span>{photo.likes_count ?? 0}</span>
      </div>
    </button>
  );
}

function TaskSuggestionCard({ task, onSelect }: { task: Task; onSelect: (task: Task) => void }) {
  const theme = getEmotionTheme(task.emotion ?? null);
  const emotionIcon = getEmotionIcon(task.emotion ?? null);
  return (
    <button
      type="button"
      onClick={() => onSelect(task)}
      className={cn(
        'group flex min-w-[220px] flex-col justify-between rounded-2xl border p-4 text-left shadow-sm transition hover:-translate-y-0.5 hover:shadow-md',
        'bg-gradient-to-br text-gray-900 dark:text-white',
        theme.suggestionGradient,
        theme.suggestionBorder
      )}
    >
      <div className="space-y-2">
        <p className="text-xs uppercase tracking-[0.3em] text-gray-500 group-hover:text-gray-700 dark:text-gray-300">
          {emotionIcon} {task.emotion?.name ?? 'Aufgabe'}
        </p>
        <h3 className="text-base font-semibold leading-tight line-clamp-2">{task.title}</h3>
        <p className="text-xs text-gray-600 line-clamp-2 dark:text-gray-200">{task.description}</p>
      </div>
      <div className="mt-3 flex items-center justify-between text-xs font-semibold">
        <span>{task.duration} Min</span>
        <span className="flex items-center gap-1 text-pink-600 dark:text-pink-200">
          Starten
          <ChevronRight className="h-3.5 w-3.5" />
        </span>
      </div>
    </button>
  );
}
