// @ts-nocheck
import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ArrowLeft, Layers, Loader2, PlusCircle, Search, Sparkles, Pencil, Check, X, CircleOff } from 'lucide-react';
import { useTranslation } from 'react-i18next';
import toast from 'react-hot-toast';

import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Switch } from '@/components/ui/switch';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Checkbox } from '@/components/ui/checkbox';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import {
  DndContext,
  closestCenter,
  PointerSensor,
  useSensor,
  useSensors,
  DragEndEvent,
  DragOverlay,
  useDraggable,
  useDroppable,
} from '@dnd-kit/core';
import {
  CSS,
} from '@dnd-kit/utilities';

import { AdminLayout } from '../components/AdminLayout';
import {
  assignTasksToEvent,
  detachTasksFromEvent,
  getEvent,
  getEventTasks,
  createTask,
  getTasks,
  getTaskCollections,
  importTaskCollection,
  getEmotions,
  updateEvent,
  updateTask,
  TenantEvent,
  TenantTask,
  TenantTaskCollection,
  TenantEmotion,
} from '../api';
import { EmotionsSection } from './EmotionsPage';
import { isAuthError } from '../auth/tokens';
import { ADMIN_EVENTS_PATH, buildEngagementTabPath } from '../constants';
import { filterEmotionsByEventType } from '../lib/emotions';
import { buildEventTabs } from '../lib/eventTabs';
import { Trash2 } from 'lucide-react';

export default function EventTasksPage() {
  const { t } = useTranslation('management', { keyPrefix: 'eventTasks' });
  const { t: tDashboard } = useTranslation('dashboard');
  const params = useParams<{ slug?: string }>();
  const [searchParams] = useSearchParams();
  const slug = params.slug ?? searchParams.get('slug') ?? null;
  const navigate = useNavigate();

  const [event, setEvent] = React.useState<TenantEvent | null>(null);
  const [assignedTasks, setAssignedTasks] = React.useState<TenantTask[]>([]);
  const [availableTasks, setAvailableTasks] = React.useState<TenantTask[]>([]);
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [modeSaving, setModeSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);
  const [tab, setTab] = React.useState<'tasks' | 'packs' | 'emotions'>('packs');
  const [taskSearch, setTaskSearch] = React.useState('');
  const [debouncedTaskSearch, setDebouncedTaskSearch] = React.useState('');
  const [difficultyFilter, setDifficultyFilter] = React.useState<TenantTask['difficulty'] | ''>('');
  const [collections, setCollections] = React.useState<TenantTaskCollection[]>([]);
  const [collectionsLoading, setCollectionsLoading] = React.useState(false);
  const [collectionsError, setCollectionsError] = React.useState<string | null>(null);
  const [importingCollectionId, setImportingCollectionId] = React.useState<number | null>(null);
  const [emotions, setEmotions] = React.useState<TenantEmotion[]>([]);
  const [emotionsLoading, setEmotionsLoading] = React.useState(false);
  const [emotionsError, setEmotionsError] = React.useState<string | null>(null);
  const [emotionFilter, setEmotionFilter] = React.useState<number[]>([]);
  const [emotionsModalOpen, setEmotionsModalOpen] = React.useState(false);
  const [newTaskTitle, setNewTaskTitle] = React.useState('');
  const [newTaskDescription, setNewTaskDescription] = React.useState('');
  const [newTaskEmotionId, setNewTaskEmotionId] = React.useState<number | null>(null);
  const [newTaskDifficulty, setNewTaskDifficulty] = React.useState<TenantTask['difficulty'] | ''>('');
  const [creatingTask, setCreatingTask] = React.useState(false);
  const [quickAddOpen, setQuickAddOpen] = React.useState(false);
  const [draggingId, setDraggingId] = React.useState<number | null>(null);
  const [selectedAssignedIds, setSelectedAssignedIds] = React.useState<number[]>([]);
  const [selectedAvailableIds, setSelectedAvailableIds] = React.useState<number[]>([]);
  const [batchSaving, setBatchSaving] = React.useState(false);
  const [inlineSavingId, setInlineSavingId] = React.useState<number | null>(null);
  const [emotionFilterOpen, setEmotionFilterOpen] = React.useState(false);
  const [libraryOpen, setLibraryOpen] = React.useState(false);
  const [librarySearch, setLibrarySearch] = React.useState('');
  React.useEffect(() => {
    const handle = window.setTimeout(() => setDebouncedTaskSearch(taskSearch.trim().toLowerCase()), 180);
    return () => window.clearTimeout(handle);
  }, [taskSearch]);
  const hydrateTasks = React.useCallback(async (targetEvent: TenantEvent) => {
    try {
      const [refreshed, libraryTasks] = await Promise.all([
        getEventTasks(targetEvent.id, 1),
        getTasks({ per_page: 200 }),
      ]);
      const assignedIds = new Set(refreshed.data.map((task) => task.id));
      setAssignedTasks(refreshed.data);
      const eventTypeId = targetEvent.event_type_id ?? null;
      const filteredLibraryTasks = libraryTasks.data.filter((task) => {
        if (assignedIds.has(task.id)) {
          return false;
        }
        if (eventTypeId && task.event_type_id && task.event_type_id !== eventTypeId) {
          return false;
        }
        return true;
      });
      setAvailableTasks(filteredLibraryTasks);
    } catch (err) {
      if (!isAuthError(err)) {
        setError(t('errors.assign', 'Tasks konnten nicht geladen werden.'));
      }
    }
  }, [t]);

  const relevantEmotions = React.useMemo(() => {
    const filtered = filterEmotionsByEventType(emotions, event?.event_type_id ?? event?.event_type?.id ?? null);
    return filtered.length > 0 ? filtered : emotions;
  }, [emotions, event?.event_type_id, event?.event_type?.id]);
  const emotionChips = React.useMemo(() => {
    const map: Record<number, TenantEmotion> = {};
    assignedTasks.forEach((task) => {
      if (task.emotion) {
        map[task.emotion.id] = {
          ...task.emotion,
          name_translations: task.emotion.name_translations ?? {},
          description: null,
          description_translations: {},
          sort_order: 0,
          is_active: true,
          tenant_id: null,
          is_global: false,
          event_types: [],
          created_at: null,
          updated_at: null,
        } as TenantEmotion;
      }
    });
    return Object.values(map);
  }, [assignedTasks]);

  React.useEffect(() => {
    if (!slug) {
      setError(t('errors.missingSlug', 'Kein Event-Slug angegeben.'));
      setLoading(false);
      return;
    }

    let cancelled = false;
    (async () => {
      try {
        setLoading(true);
        const eventData = await getEvent(slug);
        const [eventTasksResponse, libraryTasks] = await Promise.all([
          getEventTasks(eventData.id, 1),
          getTasks({ per_page: 200 }),
        ]);
        if (cancelled) return;
        setEvent(eventData);
        const assignedIds = new Set(eventTasksResponse.data.map((task) => task.id));
        setAssignedTasks(eventTasksResponse.data);
        const eventTypeId = eventData.event_type_id ?? null;
        const filteredLibraryTasks = libraryTasks.data.filter((task) => {
          if (assignedIds.has(task.id)) {
            return false;
          }
          if (eventTypeId && task.event_type_id && task.event_type_id !== eventTypeId) {
            return false;
          }
          return true;
        });
        setAvailableTasks(filteredLibraryTasks);
        setError(null);
      } catch (err) {
        if (!isAuthError(err)) {
          setError(t('errors.load', 'Event-Tasks konnten nicht geladen werden.'));
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    })();

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

  const filteredAssignedTasks = React.useMemo(() => {
    let list = assignedTasks;
    if (emotionFilter.length > 0) {
      const set = new Set(emotionFilter);
      list = list.filter((task) => (task.emotion_id ? set.has(task.emotion_id) : false));
    }
    if (difficultyFilter) {
      list = list.filter((task) => task.difficulty === difficultyFilter);
    }
    if (!debouncedTaskSearch) {
      return list;
    }
    return list.filter((task) => `${task.title ?? ''} ${task.description ?? ''}`.toLowerCase().includes(debouncedTaskSearch));
  }, [assignedTasks, debouncedTaskSearch, emotionFilter, difficultyFilter]);

  React.useEffect(() => {
    setSelectedAssignedIds((prev) => prev.filter((id) => assignedTasks.some((task) => task.id === id)));
  }, [assignedTasks]);

  React.useEffect(() => {
    setSelectedAvailableIds((prev) => prev.filter((id) => availableTasks.some((task) => task.id === id)));
  }, [availableTasks]);

  const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }));

  const handleAssignSingle = React.useCallback(
    async (taskId: number) => {
      if (!event) return;
      const task = availableTasks.find((t) => t.id === taskId);
      if (task) {
        setAvailableTasks((prev) => prev.filter((t) => t.id !== taskId));
        setAssignedTasks((prev) => [...prev, task]);
      }
      setSaving(true);
      try {
        await assignTasksToEvent(event.id, [taskId]);
        toast.success(t('actions.assignedToast', 'Tasks wurden zugewiesen.'));
      } catch (err) {
        if (!isAuthError(err)) {
          toast.error(t('errors.assign', 'Tasks konnten nicht zugewiesen werden.'));
        }
        // revert optimistic change
        if (task) {
          setAssignedTasks((prev) => prev.filter((t) => t.id !== taskId));
          setAvailableTasks((prev) => [...prev, task]);
        }
      } finally {
        setSaving(false);
      }
    },
    [availableTasks, event, t],
  );

  const handleDetachSingle = React.useCallback(
    async (taskId: number) => {
      if (!event) return;
      const task = assignedTasks.find((t) => t.id === taskId);
      if (task) {
        setAssignedTasks((prev) => prev.filter((t) => t.id !== taskId));
        setAvailableTasks((prev) => [...prev, task]);
      }
      setSaving(true);
      try {
        await detachTasksFromEvent(event.id, [taskId]);
        toast.success(t('actions.removedToast', 'Tasks wurden entfernt.'));
      } catch (err) {
        if (!isAuthError(err)) {
          toast.error(t('errors.remove', 'Tasks konnten nicht entfernt werden.'));
        }
        // revert optimistic change
        if (task) {
          setAvailableTasks((prev) => prev.filter((t) => t.id !== taskId));
          setAssignedTasks((prev) => [...prev, task]);
        }
      } finally {
        setSaving(false);
      }
    },
    [assignedTasks, event, t],
  );

  const handleDragEnd = (event: DragEndEvent) => {
    const { active, over } = event;
    if (!over || !active?.data?.current) {
      setDraggingId(null);
      return;
    }

    const originList = active.data.current.list as 'assigned' | 'library';
    const overList = (over.data?.current?.list as 'assigned' | 'library' | undefined) ?? null;
    const targetList =
      overList ??
      (over.id === 'assigned-dropzone'
        ? 'assigned'
        : over.id === 'library-dropzone'
          ? 'library'
          : null);

    setDraggingId(null);
    if (!targetList || targetList === originList) {
      return;
    }

    const taskId = Number(active.id);
    if (Number.isNaN(taskId)) {
      return;
    }

    if (targetList === 'assigned') {
      void handleAssignSingle(taskId);
    } else {
      void handleDetachSingle(taskId);
    }
  };

  const handleCreateQuickTask = React.useCallback(async () => {
    if (!event || !newTaskTitle.trim()) return;
    setCreatingTask(true);
    const emotion = emotions.find((e) => e.id === newTaskEmotionId) ?? null;
    try {
      const created = await createTask({
        title: newTaskTitle.trim(),
        description: newTaskDescription.trim() || null,
        emotion_id: newTaskEmotionId ?? undefined,
        event_type_id: event.event_type_id ?? undefined,
        difficulty: newTaskDifficulty || undefined,
      });
      setAssignedTasks((prev) => [...prev, { ...created, emotion: emotion ?? created.emotion ?? null }]);
      setAvailableTasks((prev) => prev.filter((task) => task.id !== created.id));
      await assignTasksToEvent(event.id, [created.id]);
      toast.success(t('actions.created', 'Aufgabe erstellt und zugewiesen.'));
      setNewTaskTitle('');
      setNewTaskDescription('');
      setNewTaskEmotionId(null);
      setNewTaskDifficulty('');
      setQuickAddOpen(false);
      await hydrateTasks(event);
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('errors.create', 'Aufgabe konnte nicht erstellt werden.'));
      }
    } finally {
      setCreatingTask(false);
    }
  }, [event, newTaskDescription, newTaskEmotionId, newTaskTitle, newTaskDifficulty, emotions, hydrateTasks, t]);

  const eventTabs = React.useMemo(() => {
    if (!event) {
      return [];
    }
    const translateMenu = (key: string, fallback: string) => t(key, { defaultValue: fallback });
    const taskBadge = loading ? undefined : assignedTasks.length;
    return buildEventTabs(event, translateMenu, {
      photos: event.photo_count ?? undefined,
      tasks: taskBadge,
    });
  }, [event, assignedTasks.length, t, loading]);

  React.useEffect(() => {
    let cancelled = false;
    setCollectionsLoading(true);
    setCollectionsError(null);
    const eventTypeSlug = event?.event_type?.slug ?? null;
    const query = eventTypeSlug
      ? { top_picks: true, limit: 6, event_type: eventTypeSlug }
      : { top_picks: true, limit: 6 };

    getTaskCollections(query)
      .then((result) => {
        if (cancelled) return;
        setCollections(result.data);
      })
      .catch((err) => {
        if (cancelled) return;
        if (!isAuthError(err)) {
          setCollectionsError(t('collections.error', 'Kollektionen konnten nicht geladen werden.'));
        }
      })
      .finally(() => {
        if (!cancelled) {
          setCollectionsLoading(false);
        }
      });

    return () => {
      cancelled = true;
    };
  }, [event?.event_type?.slug, t]);

  React.useEffect(() => {
    let cancelled = false;
    setEmotionsLoading(true);
    setEmotionsError(null);
    getEmotions()
      .then((list) => {
        if (!cancelled) {
          setEmotions(list);
        }
      })
      .catch((err) => {
        if (cancelled) {
          return;
        }
        if (!isAuthError(err)) {
          setEmotionsError(t('tasks.emotions.error', 'Emotionen konnten nicht geladen werden.'));
        }
      })
      .finally(() => {
        if (!cancelled) {
          setEmotionsLoading(false);
        }
      });

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

  const handleImportCollection = React.useCallback(async (collection: TenantTaskCollection) => {
    if (!slug || !event) {
      return;
    }
    setImportingCollectionId(collection.id);
    try {
      await importTaskCollection(collection.id, slug);
      toast.success(
        t('collections.imported', {
          defaultValue: 'Aufgaben-Set "{{name}}" importiert.',
          name: collection.name,
        }),
      );
      setTab('tasks');
      await hydrateTasks(event);
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('collections.importFailed', 'Aufgaben-Set konnte nicht importiert werden.'));
      }
    } finally {
      setImportingCollectionId(null);
    }
  }, [event, hydrateTasks, slug, t]);

  const tasksEnabled = React.useMemo(() => {
    const settingsMode =
      event?.settings && typeof event.settings === 'object' && 'engagement_mode' in (event.settings as Record<string, unknown>)
        ? (event.settings as { engagement_mode?: string }).engagement_mode
        : undefined;
    const mode = event?.engagement_mode ?? settingsMode;
    return mode !== 'photo_only';
  }, [event?.engagement_mode, event?.settings]);

  const hasSelection = selectedAssignedIds.length > 0;
  const tasksFirst = assignedTasks.length > 0;
  const tabOrder: Array<'tasks' | 'packs' | 'emotions'> = tasksFirst ? ['tasks', 'packs', 'emotions'] : ['packs', 'tasks', 'emotions'];
  const prevAssignedRef = React.useRef(assignedTasks.length);

  React.useEffect(() => {
    if (prevAssignedRef.current === 0 && assignedTasks.length > 0) {
      setTab('tasks');
    }
    prevAssignedRef.current = assignedTasks.length;
  }, [assignedTasks.length, setTab]);

  async function handleModeChange(checked: boolean) {
    if (!event || !slug) return;

    setModeSaving(true);
    setError(null);

    try {
      const nextMode = checked ? 'tasks' : 'photo_only';
      const payload = {
        name: event.name,
        slug: event.slug,
        event_type_id: event.event_type_id ?? event.event_type?.id,
        event_date: event.event_date ?? undefined,
        settings: {
          ...(event.settings ?? {}),
          engagement_mode: nextMode,
        },
      };
      const updated = await updateEvent(slug, {
        ...payload,
      });
      setEvent((prev) => ({
        ...(prev ?? updated),
        ...(updated ?? {}),
        engagement_mode: updated?.engagement_mode ?? nextMode,
        settings: {
          ...(prev?.settings ?? {}),
          ...(updated?.settings ?? {}),
          engagement_mode: nextMode,
        },
      }));
    } catch (err) {
      if (!isAuthError(err)) {
        setError(
          checked
            ? t('errors.photoOnlyEnable', 'Foto-Modus konnte nicht aktiviert werden.')
            : t('errors.photoOnlyDisable', 'Foto-Modus konnte nicht deaktiviert werden.'),
        );
      }
    } finally {
      setModeSaving(false);
    }
  }

  const handleAssignSelected = React.useCallback(async () => {
    if (!event || selectedAvailableIds.length === 0) return;
    const ids = selectedAvailableIds;
    const move = availableTasks.filter((task) => ids.includes(task.id));
    if (!move.length) return;

    const nextAvailableSet = new Set(ids);
    const prevAssigned = assignedTasks;
    const prevAvailable = availableTasks;

    setAssignedTasks((prev) => [...prev, ...move]);
    setAvailableTasks((prev) => prev.filter((task) => !nextAvailableSet.has(task.id)));
    setSelectedAvailableIds([]);
    setLibraryOpen(false);
    setBatchSaving(true);
    try {
      await assignTasksToEvent(event.id, ids);
      toast.success(t('actions.assignedToast', 'Tasks wurden zugewiesen.'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('errors.assign', 'Tasks konnten nicht zugewiesen werden.'));
      }
      setAssignedTasks(prevAssigned);
      setAvailableTasks(prevAvailable);
    } finally {
      setBatchSaving(false);
    }
  }, [event, selectedAvailableIds, availableTasks, assignedTasks, t]);

  const handleDetachSelected = React.useCallback(async () => {
    if (!event || selectedAssignedIds.length === 0) return;
    const ids = selectedAssignedIds;
    const move = assignedTasks.filter((task) => ids.includes(task.id));
    if (!move.length) return;

    const nextAssignedSet = new Set(ids);
    const prevAssigned = assignedTasks;
    const prevAvailable = availableTasks;

    setAssignedTasks((prev) => prev.filter((task) => !nextAssignedSet.has(task.id)));
    setAvailableTasks((prev) => [...prev, ...move]);
    setSelectedAssignedIds([]);
    setBatchSaving(true);
    try {
      await detachTasksFromEvent(event.id, ids);
      toast.success(t('actions.removedToast', 'Tasks wurden entfernt.'));
    } catch (err) {
      if (!isAuthError(err)) {
        toast.error(t('errors.remove', 'Tasks konnten nicht entfernt werden.'));
      }
      setAssignedTasks(prevAssigned);
      setAvailableTasks(prevAvailable);
    } finally {
      setBatchSaving(false);
    }
  }, [event, selectedAssignedIds, assignedTasks, availableTasks, t]);

  const handleInlineUpdate = React.useCallback(
    async (taskId: number, payload: { title?: string; difficulty?: TenantTask['difficulty'] | ''; emotion_id?: number | null }) => {
      if (!event) return;

      const prevAssigned = assignedTasks;
      const prevAvailable = availableTasks;
      const existingAssigned = assignedTasks.find((task) => task.id === taskId);
      const existingAvailable = availableTasks.find((task) => task.id === taskId);
      const optimistic = existingAssigned ?? existingAvailable;
      if (!optimistic) {
        return;
      }

      const patch: Partial<TenantTask> = {
        ...payload,
        title: payload.title ?? optimistic.title,
        difficulty: payload.difficulty || null,
        emotion_id: payload.emotion_id ?? optimistic.emotion_id ?? null,
      } as Partial<TenantTask>;

      const nextEmotion =
        typeof payload.emotion_id === 'number'
          ? emotions.find((emotion) => emotion.id === payload.emotion_id) ?? null
          : payload.emotion_id === null
            ? null
            : optimistic.emotion ?? null;

      if (existingAssigned) {
        setAssignedTasks((prev) =>
          prev.map((task) => (task.id === taskId ? { ...task, ...patch, emotion: nextEmotion } : task)),
        );
      }
      if (existingAvailable) {
        setAvailableTasks((prev) =>
          prev.map((task) => (task.id === taskId ? { ...task, ...patch, emotion: nextEmotion } : task)),
        );
      }

      setInlineSavingId(taskId);
      const duplicateAndAssign = async () => {
        const created = await createTask({
          title: patch.title,
          difficulty: patch.difficulty ?? undefined,
          description: optimistic.description ?? null,
          priority: optimistic.priority ?? undefined,
          emotion_id: optimistic.emotion_id ?? undefined,
          event_type_id: optimistic.event_type_id ?? undefined,
        });
        await assignTasksToEvent(event.id, [created.id]);
        setAssignedTasks((prev) => {
          const withoutOld = prev.filter((task) => task.id !== taskId);
          return [...withoutOld, { ...created, emotion: optimistic.emotion ?? created.emotion ?? null }];
        });
        setAvailableTasks((prev) => prev.filter((task) => task.id !== taskId));
        toast.success(t('actions.created', 'Aufgabe erstellt und zugewiesen.'));
      };

      try {
        if (optimistic.tenant_id === null) {
          await duplicateAndAssign();
        } else {
          const updated = await updateTask(taskId, {
            title: patch.title,
            difficulty: payload.difficulty || undefined,
            description: optimistic.description ?? undefined,
            priority: optimistic.priority ?? undefined,
            emotion_id: payload.emotion_id ?? optimistic.emotion_id ?? undefined,
          });

          if (existingAssigned) {
            setAssignedTasks((prev) =>
              prev.map((task) =>
                task.id === taskId ? { ...task, ...updated, emotion: nextEmotion ?? updated.emotion ?? null } : task,
              ),
            );
          }
          if (existingAvailable) {
            setAvailableTasks((prev) =>
              prev.map((task) =>
                task.id === taskId ? { ...task, ...updated, emotion: nextEmotion ?? updated.emotion ?? null } : task,
              ),
            );
          }
          toast.success(t('actions.updated', 'Task aktualisiert.'));
        }
      } catch (err) {
        if (!isAuthError(err)) {
          toast.error(t('errors.update', 'Task konnte nicht aktualisiert werden.'));
        }
        setAssignedTasks(prevAssigned);
        setAvailableTasks(prevAvailable);
      } finally {
        setInlineSavingId(null);
      }
    },
    [event, assignedTasks, availableTasks, t],
  );

  const actions = (
    <Button variant="outline" onClick={() => navigate(ADMIN_EVENTS_PATH)} className="border-pink-200 text-pink-600">
      <ArrowLeft className="h-4 w-4" />
      {t('actions.back', 'Zurück zur Übersicht')}
    </Button>
  );

  return (
    <AdminLayout
      title={t('title', 'Aufgaben & Missionen')}
      subtitle={t('subtitle', 'Stelle Mission Cards und Aufgaben für dieses Event zusammen.')}
      actions={actions}
      tabs={eventTabs}
      currentTabKey="tasks"
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>{tDashboard('alerts.errorTitle', 'Fehler')}</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {loading ? (
        <TaskSkeleton />
      ) : !event ? (
        <Alert variant="destructive">
          <AlertTitle>{t('alerts.notFoundTitle', 'Event nicht gefunden')}</AlertTitle>
          <AlertDescription>{t('alerts.notFoundDescription', 'Bitte kehre zur Eventliste zurück.')}</AlertDescription>
        </Alert>
      ) : (
        <>
          <Tabs value={tab} onValueChange={(value) => setTab(value as 'tasks' | 'packs' | 'emotions')} className="space-y-6">
            <div className="flex flex-col gap-2">
              <div className="flex justify-end">
                <Button
                  variant="outline"
                  className="border-emerald-200 text-emerald-700"
                  onClick={() => navigate(buildEngagementTabPath('tasks'))}
                >
                  {t('library.open', 'Aufgaben-Bibliothek öffnen')}
                </Button>
              </div>
              <div className="overflow-x-auto">
                <TabsList className="inline-flex min-w-fit gap-2 rounded-2xl bg-slate-100/80 p-1">
                  {tabOrder.map((key) => (
                    <TabsTrigger key={key} value={key} className="px-3 py-1.5 text-sm sm:text-base">
                      {key === 'packs'
                        ? t('tabs.packs', 'Aufgaben-Sets')
                        : key === 'tasks'
                          ? t('tabs.tasks', 'Aufgaben')
                          : t('tabs.emotions', 'Emotionen')}
                    </TabsTrigger>
                  ))}
                </TabsList>
              </div>
            </div>
            <TabsContent value="tasks" className="space-y-6">
              <Card className="border-0 bg-white/85 shadow-xl shadow-pink-100/60">
                <CardHeader className="space-y-4">
                  <div className="flex flex-col gap-4 rounded-2xl border border-slate-200 bg-white/70 p-4 text-sm text-slate-700">
                    <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                      <div className="space-y-2">
                        <p className="text-sm font-semibold text-slate-900">
                          {t('modes.title', 'Aufgaben & Foto-Modus')}
                        </p>
                        <p className="text-xs text-slate-600">
                          {tasksEnabled
                            ? t('modes.tasksHint', 'Aufgaben sind aktiv. Gäste sehen Mission Cards in der App.')
                            : t('modes.photoOnlyHint', 'Der Foto-Modus ist aktiv. Gäste können Fotos hochladen, sehen aber keine Aufgaben.')}
                        </p>
                        <div className="flex flex-wrap gap-2">
                          <Badge className="rounded-full bg-slate-900 text-white">
                            {t('summary.assigned', 'Zugeordnete Tasks')} · {assignedTasks.length}
                          </Badge>
                          <Badge className="rounded-full bg-emerald-600/90 text-white">
                            {t('summary.library', 'Bibliothek')} · {availableTasks.length}
                          </Badge>
                          <Badge className="rounded-full bg-pink-500/90 text-white">
                            {t('summary.mode', 'Aktiver Modus')} ·{' '}
                            {tasksEnabled ? t('summary.tasksMode', 'Mission Cards') : t('summary.photoOnly', 'Nur Fotos')}
                          </Badge>
                        </div>
                      </div>
                      <div className="flex flex-col items-start gap-2 lg:items-end">
                        <div className="flex items-center gap-3">
                          <span className="text-xs uppercase tracking-wide text-slate-500">
                            {tasksEnabled ? t('modes.tasks', 'Aufgaben aktiv') : t('modes.photoOnly', 'Foto-Modus')}
                          </span>
                          <Switch
                            checked={tasksEnabled}
                            onCheckedChange={handleModeChange}
                            disabled={modeSaving || (!tasksEnabled && assignedTasks.length === 0)}
                            aria-label={t('modes.switchLabel', 'Aufgaben aktivieren/deaktivieren')}
                          />
                        </div>
                        {modeSaving ? (
                          <div className="flex items-center gap-2 text-xs text-slate-500">
                            <Loader2 className="h-3.5 w-3.5 animate-spin" />
                            {t('modes.updating', 'Einstellung wird gespeichert ...')}
                          </div>
                        ) : null}
                        {!tasksEnabled && assignedTasks.length === 0 ? (
                          <p className="text-[11px] text-slate-500">
                            {t('modes.needTasks', 'Aktiviere Aufgaben, sobald mindestens eine Aufgabe zugewiesen ist.')}
                          </p>
                        ) : null}
                      </div>
                    </div>
                    <div className="flex flex-wrap gap-2">
                      <Button
                        className="bg-emerald-600 text-white hover:bg-emerald-700"
                        onClick={() => setQuickAddOpen(true)}
                      >
                        <PlusCircle className="mr-2 h-4 w-4" />
                        {t('actions.addCustom', 'Eigene Aufgabe hinzufügen')}
                      </Button>
                    </div>
                    {!tasksEnabled ? (
                      <div className="flex flex-col gap-2 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900">
                        <div className="flex items-center gap-3">
                          <CircleOff className="h-5 w-5" />
                          <div>
                            <p className="font-semibold">{t('modes.disabledTitle', 'Aufgabenmodus ist aus')}</p>
                            <p className="text-xs text-amber-800">
                              {t('modes.disabledCopy', 'Gäste sehen keine Mission Cards. Aktivieren, um Aufgaben sichtbar zu machen.')}
                            </p>
                          </div>
                        </div>
                        <div className="flex flex-wrap items-center gap-2">
                          <Button
                            size="sm"
                            className="bg-amber-600 text-white hover:bg-amber-700"
                            onClick={() => void handleModeChange(true)}
                            disabled={modeSaving || assignedTasks.length === 0}
                          >
                            {modeSaving ? <Loader2 className="h-4 w-4 animate-spin" /> : t('modes.enable', 'Aufgaben aktivieren')}
                          </Button>
                          {assignedTasks.length === 0 ? (
                            <p className="text-[11px] text-amber-800">
                              {t('modes.needTasks', 'Aktiviere Aufgaben, sobald mindestens eine Aufgabe zugewiesen ist.')}
                            </p>
                          ) : null}
                        </div>
                      </div>
                    ) : null}
                  </div>
                </CardHeader>
                <DndContext
                  sensors={sensors}
                  collisionDetection={closestCenter}
                  onDragStart={(event) => setDraggingId(Number(event.active.id))}
                  onDragEnd={handleDragEnd}
                >
            <CardContent className="relative grid gap-4">
              {!tasksEnabled ? (
                <div className="absolute inset-0 z-20 flex items-center justify-center rounded-2xl bg-white/80 backdrop-blur-sm">
                  <div className="flex flex-col items-center gap-2 text-center text-sm text-slate-700">
                    <CircleOff className="h-5 w-5 text-amber-700" />
                    <p className="font-semibold">{t('modes.disabledTitle', 'Aufgabenmodus ist aus')}</p>
                    <p className="text-xs text-slate-600">
                      {t('modes.disabledOverlay', 'Aktiviere Aufgaben, um Listen und Aktionen zu nutzen.')}
                    </p>
                    <Button
                      size="sm"
                      className="bg-amber-600 text-white hover:bg-amber-700"
                      onClick={() => void handleModeChange(true)}
                      disabled={modeSaving || assignedTasks.length === 0}
                    >
                      {t('modes.enable', 'Aufgaben aktivieren')}
                    </Button>
                  </div>
                </div>
              ) : null}
              <section className="space-y-3">
                    <div className="flex flex-wrap items-center justify-between gap-3">
                      <div className="flex flex-wrap items-center gap-3">
                        <h3 className="flex items-center gap-2 text-sm font-semibold text-slate-900">
                          <Sparkles className="h-4 w-4 text-pink-500" />
                          {t('sections.assigned.title', 'Zugeordnete Tasks')}
                        </h3>
                        <div className="flex items-center gap-2 rounded-full border border-slate-200 px-3 py-1">
                          <Checkbox
                            checked={
                              filteredAssignedTasks.length > 0 && filteredAssignedTasks.every((task) => selectedAssignedIds.includes(task.id))
                                ? true
                                : selectedAssignedIds.some((id) => filteredAssignedTasks.some((task) => task.id === id))
                                  ? 'indeterminate'
                                  : false
                            }
                            onCheckedChange={(checked) => {
                              if (checked) {
                                setSelectedAssignedIds((prev) => {
                                  const next = new Set(prev);
                                  filteredAssignedTasks.forEach((task) => next.add(task.id));
                                  return Array.from(next);
                                });
                              } else {
                                const visibleIds = new Set(filteredAssignedTasks.map((task) => task.id));
                                setSelectedAssignedIds((prev) => prev.filter((id) => !visibleIds.has(id)));
                              }
                            }}
                            aria-label={t('sections.assigned.selectAll', 'Alle sichtbaren Aufgaben auswählen')}
                          />
                          <span className="text-xs text-slate-600">
                            {t('sections.assigned.selectedCount', {
                              defaultValue: '{{count}} ausgewählt',
                              count: selectedAssignedIds.length,
                            })}
                          </span>
                        </div>
                        <div className="flex items-center gap-2 rounded-full border border-slate-200 px-3 py-1">
                          <Search className="h-4 w-4 text-slate-500" />
                          <Input
                            value={taskSearch}
                            onChange={(event) => setTaskSearch(event.target.value)}
                            placeholder={t('sections.assigned.search', 'Aufgaben suchen...')}
                            className="h-8 border-0 bg-transparent text-sm focus-visible:ring-0"
                          />
                        </div>
                        <div className="flex items-center gap-2 rounded-full border border-slate-200 px-3 py-1 text-xs text-slate-700">
                          <span>{t('sections.assigned.results', { defaultValue: '{{count}} Treffer', count: filteredAssignedTasks.length })}</span>
                        </div>
                        <Button
                          size="sm"
                          variant={difficultyFilter ? 'default' : 'outline'}
                          className="rounded-full"
                          onClick={() => setDifficultyFilter((prev) => (prev ? '' : 'medium'))}
                          aria-expanded={difficultyFilter ? true : false}
                        >
                          {difficultyFilter
                            ? t('sections.assigned.difficulty.active', { defaultValue: 'Schwierigkeit: ' }) +
                              t(
                                difficultyFilter === 'easy'
                                  ? 'sections.assigned.difficulty.easy'
                                  : difficultyFilter === 'medium'
                                    ? 'sections.assigned.difficulty.medium'
                                    : 'sections.assigned.difficulty.hard',
                                difficultyFilter === 'easy' ? 'Leicht' : difficultyFilter === 'medium' ? 'Mittel' : 'Schwer',
                              )
                            : t('sections.assigned.difficulty.filter', 'Nach Schwierigkeit filtern')}
                        </Button>
                        {difficultyFilter ? (
                          <div className="flex flex-wrap gap-2 rounded-xl border border-slate-200 bg-white/80 p-2">
                            {(['', 'easy', 'medium', 'hard'] as Array<TenantTask['difficulty'] | ''>).map((value) => {
                              const active = difficultyFilter === value;
                              const label =
                                value === 'easy'
                                  ? t('sections.assigned.difficulty.easy', 'Leicht')
                                  : value === 'medium'
                                    ? t('sections.assigned.difficulty.medium', 'Mittel')
                                    : value === 'hard'
                                      ? t('sections.assigned.difficulty.hard', 'Schwer')
                                      : t('sections.assigned.difficulty.all', 'Alle Stufen');
                              return (
                                <Button
                                  key={value || 'all'}
                                  size="sm"
                                  variant={active ? 'default' : 'outline'}
                                  className="rounded-full"
                                  onClick={() => setDifficultyFilter(value)}
                                >
                                  {label}
                                </Button>
                              );
                            })}
                          </div>
                        ) : null}
                      </div>
                      <div className="flex flex-wrap items-center gap-2">
                        {emotionChips.length > 0 ? (
                          <Button
                            size="sm"
                            variant={emotionFilterOpen ? 'default' : 'outline'}
                            className="rounded-full"
                            onClick={() => setEmotionFilterOpen((prev) => !prev)}
                          >
                            {emotionFilterOpen
                              ? t('filters.emotionsHide', 'Emotionen ausblenden')
                              : t('filters.emotionsShow', 'Emotionen filtern')}
                          </Button>
                        ) : null}
                        <Button
                          size="sm"
                          className="border-emerald-200 text-emerald-700"
                          variant="outline"
                          onClick={() => setLibraryOpen(true)}
                        >
                          <PlusCircle className="mr-2 h-4 w-4" />
                          {t('actions.openLibrary', 'Aus Bibliothek hinzufügen')}
                        </Button>
                      </div>
                    </div>

                  {emotionChips.length > 0 && emotionFilterOpen ? (
                    <div className="flex flex-wrap gap-2 rounded-xl border border-slate-200 bg-white/80 p-2">
                        <Button
                          size="sm"
                          variant={emotionFilter.length === 0 ? 'default' : 'outline'}
                          onClick={() => setEmotionFilter([])}
                          className="rounded-full"
                        >
                          {t('filters.allEmotions', 'Alle Emotionen')}
                        </Button>
                        {emotionChips.map((emotion) => {
                          const active = emotionFilter.includes(emotion.id);
                          return (
                            <Button
                              key={emotion.id}
                              size="sm"
                              variant={active ? 'default' : 'outline'}
                              onClick={() =>
                                setEmotionFilter((prev) =>
                                  active ? prev.filter((id) => id !== emotion.id) : [...prev, emotion.id]
                                )
                              }
                              className="rounded-full"
                              style={
                                active
                                  ? { backgroundColor: emotion.color ?? '#e0f2fe', color: '#0f172a' }
                                  : { borderColor: emotion.color ?? undefined, color: '#0f172a' }
                              }
                            >
                              {emotion.icon ? <span className="mr-1">{emotion.icon}</span> : null}
                              {emotion.name}
                            </Button>
                          );
                        })}
                      </div>
                    ) : null}

                    <DropZone id="assigned-dropzone">
                      {filteredAssignedTasks.length === 0 ? (
                        <EmptyState
                          message={
                            taskSearch.trim()
                              ? t('sections.assigned.noResults', 'Keine Aufgaben zum Suchbegriff.')
                              : t('sections.assigned.empty', 'Noch keine Tasks zugewiesen.')
                          }
                        />
                      ) : (
                        <div className="space-y-2">
                          {filteredAssignedTasks.map((task) => (
                            <DraggableTaskCard
                              key={task.id}
                              task={task}
                              origin="assigned"
                              onRemove={() => void handleDetachSingle(task.id)}
                              showCheckbox
                              checked={selectedAssignedIds.includes(task.id)}
                              onCheckedChange={(checked) => {
                                setSelectedAssignedIds((prev) => {
                                  if (checked) {
                                    if (prev.includes(task.id)) return prev;
                                    return [...prev, task.id];
                                  }
                                  return prev.filter((id) => id !== task.id);
                                });
                              }}
                              disabled={batchSaving || saving}
                              onInlineUpdate={handleInlineUpdate}
                              inlineSaving={inlineSavingId === task.id}
                              emotions={relevantEmotions}
                            />
                          ))}
                        </div>
                      )}
                    </DropZone>
                  </section>
                  </CardContent>
                  <DragOverlay>
                    {draggingId ? (
                      <div className="rounded-2xl border border-dashed border-slate-200 bg-white/90 px-4 py-3 shadow-sm opacity-80">
                        {filteredAssignedTasks.find((t) => t.id === draggingId)?.title ??
                          availableTasks.find((t) => t.id === draggingId)?.title}
                      </div>
                    ) : null}
                  </DragOverlay>
                </DndContext>
              </Card>
              {hasSelection ? (
                <div className="fixed inset-x-0 bottom-4 z-30 flex justify-center px-4">
                  <div className="pointer-events-auto flex w-full max-w-4xl flex-wrap items-center gap-3 rounded-2xl border border-slate-200 bg-white/95 p-3 shadow-2xl">
                    <div className="flex flex-1 flex-wrap items-center gap-2 text-sm text-slate-700">
                      <Badge variant="outline" className="border-slate-200 text-slate-700">
                        {t('sections.bulk.assignedSelected', {
                          defaultValue: '{{count}} ausgewählt (Zugeordnet)',
                          count: selectedAssignedIds.length,
                        })}
                      </Badge>
                    </div>
                    <div className="flex flex-wrap items-center gap-2">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => void handleDetachSelected()}
                        disabled={selectedAssignedIds.length === 0 || batchSaving || saving}
                      >
                        {t('actions.removeSelected', 'Ausgewählte Aufgaben entfernen')}
                      </Button>
                      <Button
                        size="sm"
                        variant="ghost"
                        onClick={() => {
                          setSelectedAssignedIds([]);
                        }}
                      >
                        {t('sections.bulk.clear', 'Auswahl aufheben')}
                      </Button>
                    </div>
                  </div>
                </div>
              ) : null}
            </TabsContent>
            <TabsContent value="packs">
              <MissionPackGrid
                collections={collections}
                loading={collectionsLoading}
                error={collectionsError}
                onImport={handleImportCollection}
                importingId={importingCollectionId}
                onViewAll={() => navigate(buildEngagementTabPath('collections'))}
              />
            </TabsContent>
            <TabsContent value="emotions">
              <EmotionsCard
                emotions={relevantEmotions}
                emotionsLoading={emotionsLoading}
                emotionsError={emotionsError}
                onOpenEmotions={() => setEmotionsModalOpen(true)}
              />
            </TabsContent>
          </Tabs>
        </>
      )}

          <Dialog open={quickAddOpen} onOpenChange={setQuickAddOpen}>
            <DialogContent className="max-w-xl">
              <DialogHeader>
                <DialogTitle>{t('sections.library.quickCreate', 'Eigene Aufgabe hinzufügen')}</DialogTitle>
              </DialogHeader>
          <div className="space-y-3">
            <p className="text-xs text-slate-600">
              {t('sections.library.quickHelper', 'Titel eingeben, optional beschreiben und sofort zum Event zuweisen.')}
            </p>
            <Input
              value={newTaskTitle}
              onChange={(e) => setNewTaskTitle(e.target.value)}
              placeholder={t('sections.library.quickTitle', 'Titel der Aufgabe')}
              disabled={!tasksEnabled || creatingTask}
            />
            <Textarea
              value={newTaskDescription}
              onChange={(e) => setNewTaskDescription(e.target.value)}
              placeholder={t('sections.library.quickDescription', 'Beschreibung (optional)')}
              disabled={!tasksEnabled || creatingTask}
              className="min-h-[90px]"
            />
            <div className="grid gap-2 sm:grid-cols-2">
              <div className="flex items-center gap-2">
                <label className="text-xs text-slate-700">{t('sections.library.quickEmotion', 'Emotion')}</label>
                <select
                  className="h-9 w-full rounded-lg border border-slate-200 bg-white px-2 text-sm"
                  value={newTaskEmotionId ?? ''}
                  onChange={(e) => setNewTaskEmotionId(e.target.value ? Number(e.target.value) : null)}
                  disabled={!tasksEnabled || creatingTask}
                >
                  <option value="">{t('sections.library.quickEmotionNone', 'Keine')}</option>
                  {relevantEmotions.map((emotion) => (
                    <option key={emotion.id} value={emotion.id}>
                      {emotion.name}
                    </option>
                  ))}
                </select>
              </div>
              <div className="flex items-center gap-2">
                <label className="text-xs text-slate-700">{t('sections.library.quickDifficulty', 'Schwierigkeit')}</label>
                <select
                  className="h-9 w-full rounded-lg border border-slate-200 bg-white px-2 text-sm"
                  disabled={!tasksEnabled || creatingTask}
                  value={newTaskDifficulty}
                  onChange={(e) => setNewTaskDifficulty(e.target.value as TenantTask['difficulty'] | '')}
                >
                  <option value="">{t('sections.library.quickDifficultyNone', 'Keine')}</option>
                  <option value="easy">{t('sections.library.difficulty.easy', 'Leicht')}</option>
                  <option value="medium">{t('sections.library.difficulty.medium', 'Mittel')}</option>
                  <option value="hard">{t('sections.library.difficulty.hard', 'Schwer')}</option>
                </select>
              </div>
            </div>
            <div className="flex justify-end gap-2">
              <Button
                variant="ghost"
                onClick={() => {
                  setQuickAddOpen(false);
                  setNewTaskTitle('');
                  setNewTaskDescription('');
                  setNewTaskEmotionId(null);
                  setNewTaskDifficulty('');
                }}
              >
                {t('actions.cancel', 'Abbrechen')}
              </Button>
              <Button
                onClick={() => void handleCreateQuickTask()}
                disabled={!newTaskTitle.trim() || creatingTask || !tasksEnabled}
              >
                {creatingTask ? <Loader2 className="h-4 w-4 animate-spin" /> : t('sections.library.quickCreateCta', 'Erstellen & zuweisen')}
              </Button>
            </div>
          </div>
        </DialogContent>
          </Dialog>

      <Dialog open={libraryOpen} onOpenChange={(open) => {
        setLibraryOpen(open);
        if (!open) {
          setSelectedAvailableIds([]);
          setLibrarySearch('');
        }
      }}>
        <DialogContent className="max-w-3xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{t('sections.library.title', 'Tasks aus Bibliothek hinzufügen')}</DialogTitle>
          </DialogHeader>
          <div className="space-y-3">
            <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
              <div className="flex w-full items-center gap-2 rounded-xl border border-slate-200 bg-white px-3 py-2">
                <Search className="h-4 w-4 text-slate-500" />
                <Input
                  value={librarySearch}
                  onChange={(e) => setLibrarySearch(e.target.value)}
                  placeholder={t('sections.library.search', 'Aufgaben suchen...')}
                  className="h-8 border-0 bg-transparent p-0 text-sm focus-visible:ring-0"
                />
              </div>
              <div className="flex flex-wrap gap-2 text-xs text-slate-600">
                <Badge variant="outline" className="border-slate-200">
                  {t('sections.library.selectedCount', { defaultValue: '{{count}} ausgewählt', count: selectedAvailableIds.length })}
                </Badge>
                <Badge variant="outline" className="border-slate-200">
                  {t('summary.library', 'Bibliothek')} · {availableTasks.length}
                </Badge>
              </div>
            </div>

            <div className="space-y-2 max-h-[55vh] overflow-y-auto">
              {availableTasks.length === 0 ? (
                <EmptyState message={t('sections.library.empty', 'Keine Tasks in der Bibliothek gefunden.')} />
              ) : (
                availableTasks
                  .filter((task) =>
                    librarySearch.trim()
                      ? `${task.title ?? ''} ${task.description ?? ''}`.toLowerCase().includes(librarySearch.toLowerCase().trim())
                      : true,
                  )
                  .map((task) => (
                    <DraggableTaskCard
                      key={task.id}
                      task={task}
                      origin="library"
                      onAdd={() => void handleAssignSingle(task.id)}
                      disabled={!tasksEnabled || saving || batchSaving}
                      showCheckbox
                      checked={selectedAvailableIds.includes(task.id)}
                      onCheckedChange={(checked) => {
                        setSelectedAvailableIds((prev) => {
                          if (checked) {
                            if (prev.includes(task.id)) return prev;
                            return [...prev, task.id];
                          }
                          return prev.filter((id) => id !== task.id);
                        });
                      }}
                      onInlineUpdate={handleInlineUpdate}
                      inlineSaving={inlineSavingId === task.id}
                      emotions={relevantEmotions}
                    />
                  ))
              )}
            </div>

            {selectedAvailableIds.length > 0 ? (
              <div className="sticky bottom-0 flex flex-wrap items-center gap-2 rounded-2xl border border-slate-200 bg-white/95 p-3 shadow-lg">
                <div className="flex flex-1 flex-wrap items-center gap-2 text-sm text-slate-700">
                  <Badge variant="outline" className="border-slate-200 text-slate-700">
                    {t('sections.library.selectedCount', { defaultValue: '{{count}} ausgewählt', count: selectedAvailableIds.length })}
                  </Badge>
                </div>
                <div className="flex flex-wrap items-center gap-2">
                  <Button
                    size="sm"
                    variant="outline"
                    onClick={() => void handleAssignSelected()}
                    disabled={selectedAvailableIds.length === 0 || !tasksEnabled || batchSaving || saving}
                  >
                    {t('actions.assignSelected', 'Auswahl zuweisen')}
                  </Button>
                  <Button
                    size="sm"
                    variant="ghost"
                    onClick={() => setSelectedAvailableIds([])}
                  >
                    {t('sections.bulk.clear', 'Auswahl aufheben')}
                  </Button>
                </div>
              </div>
            ) : null}
          </div>
        </DialogContent>
      </Dialog>

      <Dialog open={emotionsModalOpen} onOpenChange={setEmotionsModalOpen}>
        <DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto">
          <DialogHeader>
            <DialogTitle>{t('tasks.emotions.manage', 'Emotionen verwalten')}</DialogTitle>
          </DialogHeader>
          <EmotionsSection embedded />
        </DialogContent>
      </Dialog>
    </AdminLayout>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <div className="flex flex-col items-center justify-center gap-2 rounded-2xl border border-dashed border-slate-200 bg-white/70 p-6 text-center">
      <p className="text-xs text-slate-600">{message}</p>
    </div>
  );
}

function TaskSkeleton() {
  return (
    <div className="space-y-4">
      {Array.from({ length: 2 }).map((_, index) => (
        <div key={index} className="h-48 animate-pulse rounded-2xl bg-gradient-to-r from-white/40 via-white/60 to-white/40" />
      ))}
    </div>
  );
}

function DropZone({ id, children }: { id: string; children: React.ReactNode }) {
  const zone = id === 'assigned-dropzone' ? 'assigned' : 'library';
  const { setNodeRef, isOver } = useDroppable({ id, data: { list: zone } });

  return (
    <div
      ref={setNodeRef}
      className={`rounded-2xl border border-dashed p-2 ${isOver ? 'border-pink-200 bg-pink-50/70' : 'border-slate-200/70'}`}
    >
      {children}
    </div>
  );
}

function DraggableTaskCard({
  task,
  origin,
  onRemove,
  onAdd,
  disabled,
  showCheckbox,
  checked,
  onCheckedChange,
  onInlineUpdate,
  inlineSaving,
  emotions,
}: {
  task: TenantTask;
  origin: 'assigned' | 'library';
  onRemove?: () => void;
  onAdd?: () => void;
  disabled?: boolean;
  showCheckbox?: boolean;
  checked?: boolean;
  onCheckedChange?: (checked: boolean) => void;
  onInlineUpdate?: (taskId: number, payload: { title?: string; difficulty?: TenantTask['difficulty'] | ''; emotion_id?: number | null }) => void;
  inlineSaving?: boolean;
  emotions?: TenantEmotion[];
}) {
  const { t } = useTranslation('management');

  const [editing, setEditing] = React.useState(false);
  const [titleValue, setTitleValue] = React.useState(task.title ?? '');
  const [difficultyValue, setDifficultyValue] = React.useState<TenantTask['difficulty'] | ''>(task.difficulty ?? '');
  const [emotionIdValue, setEmotionIdValue] = React.useState<number | ''>(task.emotion_id ?? '');

  React.useEffect(() => {
    setTitleValue(task.title ?? '');
    setDifficultyValue(task.difficulty ?? '');
    setEmotionIdValue(task.emotion_id ?? '');
  }, [task.title, task.difficulty, task.emotion_id]);

  return (
    <div
      className="rounded-xl border border-slate-200 bg-white/90 px-3 py-2 shadow-sm"
      onDoubleClick={() => setEditing(true)}
    >
      <div className="flex items-start gap-2">
        <div className="flex min-w-[32px] flex-col items-center gap-1 pt-1">
          {showCheckbox ? (
            <Checkbox
              checked={checked ?? false}
              onCheckedChange={(state) => onCheckedChange?.(Boolean(state))}
              aria-label={t('actions.selectTask', 'Task auswählen')}
            />
          ) : null}
          <div className="flex flex-col items-center gap-1">
            <Button
              size="icon"
              variant="ghost"
              onClick={() => setEditing((prev) => !prev)}
              aria-label={t('actions.edit', 'Bearbeiten')}
              disabled={inlineSaving}
              className="h-8 w-8"
            >
              {editing ? <X className="h-4 w-4" /> : <Pencil className="h-4 w-4 text-slate-500" />}
            </Button>
            {origin === 'assigned' ? (
              <Button
                size="icon"
                variant="ghost"
                onClick={onRemove}
                disabled={disabled}
                aria-label={t('actions.remove', 'Vom Event entfernen')}
                className="h-8 w-8"
              >
                <Trash2 className="h-4 w-4 text-slate-500" />
              </Button>
            ) : (
              <Button
                size="icon"
                variant="ghost"
                onClick={onAdd}
                disabled={disabled}
                aria-label={t('actions.assign', 'Zum Event hinzufügen')}
                className="h-8 w-8"
              >
                <PlusCircle className="h-4 w-4 text-emerald-600" />
              </Button>
            )}
          </div>
        </div>
        <div className="flex-1 space-y-1 min-w-0">
          <div className="space-y-1 min-w-0 max-w-full">
            {editing ? (
              <div className="space-y-2">
                <Textarea
                  value={titleValue}
                  onChange={(e) => setTitleValue(e.target.value)}
                  disabled={inlineSaving}
                  className="min-h-[64px]"
                />
                <select
                  className="h-9 w-full rounded-lg border border-slate-200 bg-white px-2 text-sm"
                  value={difficultyValue}
                  onChange={(e) => setDifficultyValue(e.target.value as TenantTask['difficulty'] | '')}
                  disabled={inlineSaving}
                >
                  <option value="">{t('sections.assigned.difficulty.all', 'Alle Stufen')}</option>
                  <option value="easy">{t('sections.library.difficulty.easy', 'Leicht')}</option>
                  <option value="medium">{t('sections.library.difficulty.medium', 'Mittel')}</option>
                  <option value="hard">{t('sections.library.difficulty.hard', 'Schwer')}</option>
                </select>
                {emotions && emotions.length > 0 ? (
                  <select
                    className="h-9 w-full rounded-lg border border-slate-200 bg-white px-2 text-sm"
                    value={emotionIdValue}
                    onChange={(e) => setEmotionIdValue(e.target.value ? Number(e.target.value) : '')}
                    disabled={inlineSaving}
                  >
                    <option value="">{t('sections.library.quickEmotionNone', 'Keine')}</option>
                    {emotions.map((emotion) => (
                      <option key={emotion.id} value={emotion.id}>
                        {emotion.name}
                      </option>
                    ))}
                  </select>
                ) : null}
                <div className="flex items-center gap-2">
                  <Button
                    size="icon"
                    variant="secondary"
                    className="h-8 w-8"
                    disabled={!titleValue.trim() || inlineSaving}
                    onClick={() => {
                      if (!onInlineUpdate) return;
                      onInlineUpdate(task.id, {
                        title: titleValue.trim(),
                        difficulty: difficultyValue,
                        emotion_id: emotionIdValue === '' ? null : Number(emotionIdValue),
                      });
                      setEditing(false);
                    }}
                  >
                    {inlineSaving ? <Loader2 className="h-4 w-4 animate-spin" /> : <Check className="h-4 w-4" />}
                  </Button>
                  <Button
                    size="icon"
                    variant="ghost"
                    className="h-8 w-8"
                    disabled={inlineSaving}
                    onClick={() => {
                      setTitleValue(task.title ?? '');
                      setDifficultyValue(task.difficulty ?? '');
                      setEditing(false);
                    }}
                  >
                    <X className="h-4 w-4" />
                  </Button>
                </div>
              </div>
            ) : (
              <div className="space-y-1">
                <p className="text-sm font-medium text-slate-900 break-words">{task.title}</p>
                {task.description ? <p className="text-xs text-slate-600 break-words">{task.description}</p> : null}
              </div>
            )}
          </div>
          <div className="flex flex-wrap items-center gap-2 text-xs">
            {!editing && task.emotion ? (
              <Badge
                variant="outline"
                className="border-transparent text-[11px]"
                style={{
                  backgroundColor: `${task.emotion.color ?? '#eef2ff'}20`,
                  color: task.emotion.color ?? '#4338ca',
                }}
              >
                {task.emotion.icon ? <span className="mr-1">{task.emotion.icon}</span> : null}
                {task.emotion.name}
              </Badge>
            ) : null}
            {!editing ? (
              <Badge variant="outline" className="border-pink-200 text-pink-600">
                {mapPriority(task.priority, (key, fallback) => t(key, { defaultValue: fallback }))}
              </Badge>
            ) : null}
            {task.tenant_id !== null ? (
              <Badge variant="outline" className="border-emerald-200 text-emerald-700">
                {t('tasks.customBadge', 'Eigene Aufgabe')}
              </Badge>
            ) : null}
          </div>
        </div>
      </div>
    </div>
  );
}

function MissionPackGrid({
  collections,
  loading,
  error,
  onImport,
  importingId,
  onViewAll,
}: {
  collections: TenantTaskCollection[];
  loading: boolean;
  error: string | null;
  onImport: (collection: TenantTaskCollection) => void;
  importingId: number | null;
  onViewAll: () => void;
}) {
  const { t } = useTranslation('management', { keyPrefix: 'eventTasks.collections' });

  return (
    <Card className="border border-slate-200 bg-white/90">
      <CardHeader className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <CardTitle className="flex items-center gap-2 text-base text-slate-900">
            <Layers className="h-5 w-5 text-pink-500" />
            {t('title', 'Vorlagen / Aufgaben-Bundles')}
          </CardTitle>
          <CardDescription className="text-sm text-slate-600">
            {t('subtitle', 'Importiere Aufgaben-Sets, die zu deinem Event passen.')}
          </CardDescription>
        </div>
        <Button variant="outline" onClick={onViewAll}>
          {t('viewAll', 'Alle Sets ansehen')}
        </Button>
      </CardHeader>
      <CardContent className="space-y-4">
        {error ? (
          <Alert variant="destructive">
            <AlertTitle>{t('errorTitle', 'Kollektionen nicht verfügbar')}</AlertTitle>
            <AlertDescription>{error}</AlertDescription>
          </Alert>
        ) : null}

        {loading ? (
          <div className="space-y-3">
            {Array.from({ length: 3 }).map((_, index) => (
              <div key={index} className="h-24 animate-pulse rounded-2xl bg-slate-100/60" />
            ))}
          </div>
        ) : collections.length === 0 ? (
          <EmptyState message={t('empty', 'Keine empfohlenen Kollektionen gefunden.')} />
        ) : (
          <div className="grid gap-4 md:grid-cols-2">
            {collections.map((collection) => (
              <div key={collection.id} className="flex flex-col rounded-2xl border border-slate-200 bg-white/80 p-4 shadow-sm">
                <div className="flex flex-1 flex-col gap-1">
                  <p className="text-sm font-semibold text-slate-900">{collection.name}</p>
                  {collection.description ? (
                    <p className="text-xs text-slate-500">{collection.description}</p>
                  ) : null}
                  <Badge variant="outline" className="w-fit border-slate-200 text-slate-600">
                    {t('tasksCount', {
                      defaultValue: '{{count}} Aufgaben',
                      count: collection.tasks_count,
                    })}
                  </Badge>
                </div>
                <div className="mt-4 flex justify-between text-xs text-slate-500">
                  <span>{collection.event_type?.name ?? t('genericType', 'Allgemein')}</span>
                  <span>{collection.is_global ? t('global', 'Global') : t('custom', 'Custom')}</span>
                </div>
                <Button
                  className="mt-4 rounded-full bg-brand-rose text-white"
                  disabled={importingId === collection.id}
                  onClick={() => onImport(collection)}
                >
                  {importingId === collection.id ? (
                    <Loader2 className="h-4 w-4 animate-spin" />
                  ) : (
                    t('importCta', 'Aufgaben-Set importieren')
                  )}
                </Button>
              </div>
            ))}
          </div>
        )}
      </CardContent>
    </Card>
  );
}

type EmotionsCardProps = {
  emotions: TenantEmotion[];
  emotionsLoading: boolean;
  emotionsError: string | null;
  onOpenEmotions: () => void;
};

function EmotionsCard({ emotions, emotionsLoading, emotionsError, onOpenEmotions }: EmotionsCardProps) {
  const { t } = useTranslation('management');
  const spotlightEmotions = emotions.slice(0, 6);

  return (
    <Card className="border border-rose-100 bg-rose-50/70 shadow-sm">
      <CardHeader>
        <CardTitle className="flex items-center gap-2 text-base text-rose-900">
          <Sparkles className="h-5 w-5 text-rose-500" />
          {t('tasks.story.emotionsTitle', 'Emotionen')}
        </CardTitle>
        <CardDescription className="text-sm text-rose-800">
          {t('tasks.story.description', 'Aktiviere Emotionen, um Aufgaben zu kategorisieren.')}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-3">
        <div className="flex items-center justify-between">
          <Badge variant="outline" className="border-rose-200 text-rose-700">
            {t('tasks.story.emotionsCount', { defaultValue: '{{count}} aktiv', count: emotions.length })}
          </Badge>
          <Button
            size="sm"
            className="bg-rose-600 text-white hover:bg-rose-700"
            onClick={onOpenEmotions}
          >
            {t('tasks.story.emotionsCta', 'Emotionen verwalten')}
          </Button>
        </div>
        {emotionsLoading ? (
          <div className="h-10 animate-pulse rounded-xl bg-white/70" />
        ) : emotionsError ? (
          <p className="text-xs text-rose-900/70">{emotionsError}</p>
        ) : spotlightEmotions.length ? (
          <div className="flex flex-wrap gap-2">
            {spotlightEmotions.map((emotion) => (
              <span
                key={emotion.id}
                className="flex items-center gap-1 rounded-full px-3 py-1 text-xs font-semibold shadow-sm"
                style={{
                  backgroundColor: `${emotion.color ?? '#fecdd3'}33`,
                  color: emotion.color ?? '#be123c',
                }}
              >
                {emotion.icon ? <span>{emotion.icon}</span> : null}
                {emotion.name}
              </span>
            ))}
          </div>
        ) : (
          <p className="text-xs text-rose-900/70">
            {t('tasks.story.emotionsEmpty', 'Aktiviere Emotionen, um Aufgaben zu kategorisieren.')}
          </p>
        )}
      </CardContent>
    </Card>
  );
}

function mapPriority(priority: TenantTask['priority'], translate: (key: string, defaultValue: string) => string): string {
  switch (priority) {
    case 'low':
      return translate('management.eventTasks.priorities.low', 'Niedrig');
    case 'high':
      return translate('management.eventTasks.priorities.high', 'Hoch');
    case 'urgent':
      return translate('management.eventTasks.priorities.urgent', 'Dringend');
    default:
      return translate('management.eventTasks.priorities.medium', 'Mittel');
  }
}
