import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ArrowLeft, Loader2, PlusCircle, Sparkles } from 'lucide-react';

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 { Checkbox } from '@/components/ui/checkbox';

import { AdminLayout } from '../components/AdminLayout';
import {
  assignTasksToEvent,
  getEvent,
  getEventTasks,
  getTasks,
  TenantEvent,
  TenantTask,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { ADMIN_EVENTS_PATH } from '../constants';

export default function EventTasksPage() {
  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 [selected, setSelected] = React.useState<number[]>([]);
  const [loading, setLoading] = React.useState(true);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  React.useEffect(() => {
    if (!slug) {
      setError('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: 50 }),
        ]);
        if (cancelled) return;
        setEvent(eventData);
        const assignedIds = new Set(eventTasksResponse.data.map((task) => task.id));
        setAssignedTasks(eventTasksResponse.data);
        setAvailableTasks(libraryTasks.data.filter((task) => !assignedIds.has(task.id)));
        setError(null);
      } catch (err) {
        if (!isAuthError(err)) {
          setError('Event-Tasks konnten nicht geladen werden.');
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    })();

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

  async function handleAssign() {
    if (!event || selected.length === 0) return;
    setSaving(true);
    try {
      await assignTasksToEvent(event.id, selected);
      const refreshed = await getEventTasks(event.id, 1);
      const assignedIds = new Set(refreshed.data.map((task) => task.id));
      setAssignedTasks(refreshed.data);
      setAvailableTasks((prev) => prev.filter((task) => !assignedIds.has(task.id)));
      setSelected([]);
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Tasks konnten nicht zugewiesen werden.');
      }
    } finally {
      setSaving(false);
    }
  }

  const actions = (
    <Button variant="outline" onClick={() => navigate(ADMIN_EVENTS_PATH)} className="border-pink-200 text-pink-600">
      <ArrowLeft className="h-4 w-4" />
      Zurueck zur Uebersicht
    </Button>
  );

  return (
    <AdminLayout
      title="Event Tasks"
      subtitle="Verwalte Aufgaben, die diesem Event zugeordnet sind."
      actions={actions}
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>Hinweis</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {loading ? (
        <TaskSkeleton />
      ) : !event ? (
        <Alert variant="destructive">
          <AlertTitle>Event nicht gefunden</AlertTitle>
          <AlertDescription>Bitte kehre zur Eventliste zurueck.</AlertDescription>
        </Alert>
      ) : (
        <>
          <Card className="border-0 bg-white/85 shadow-xl shadow-pink-100/60">
            <CardHeader>
              <CardTitle className="text-xl text-slate-900">{renderName(event.name)}</CardTitle>
              <CardDescription className="text-sm text-slate-600">
                Status: {event.status === 'published' ? 'Veroeffentlicht' : 'Entwurf'}
              </CardDescription>
            </CardHeader>
            <CardContent className="grid gap-4 lg:grid-cols-2">
              <section className="space-y-3">
                <h3 className="flex items-center gap-2 text-sm font-semibold text-slate-900">
                  <Sparkles className="h-4 w-4 text-pink-500" />
                  Zugeordnete Tasks
                </h3>
                {assignedTasks.length === 0 ? (
                  <EmptyState message="Noch keine Tasks zugewiesen." />
                ) : (
                  <div className="space-y-2">
                    {assignedTasks.map((task) => (
                      <div key={task.id} className="rounded-2xl border border-slate-100 bg-white/90 p-3 shadow-sm">
                        <div className="flex items-center justify-between">
                          <p className="text-sm font-medium text-slate-900">{task.title}</p>
                          <Badge variant="outline" className="border-pink-200 text-pink-600">
                            {mapPriority(task.priority)}
                          </Badge>
                        </div>
                        {task.description && <p className="mt-1 text-xs text-slate-600">{task.description}</p>}
                      </div>
                    ))}
                  </div>
                )}
              </section>

              <section className="space-y-3">
                <h3 className="flex items-center gap-2 text-sm font-semibold text-slate-900">
                  <PlusCircle className="h-4 w-4 text-emerald-500" />
                  Tasks aus Bibliothek hinzufuegen
                </h3>
                <div className="space-y-2 rounded-2xl border border-emerald-100 bg-white/90 p-3 shadow-sm max-h-72 overflow-y-auto">
                  {availableTasks.length === 0 ? (
                    <EmptyState message="Keine Tasks in der Bibliothek gefunden." />
                  ) : (
                    availableTasks.map((task) => (
                      <label key={task.id} className="flex items-start gap-3 rounded-xl border border-transparent p-2 transition hover:border-emerald-200">
                        <Checkbox
                          checked={selected.includes(task.id)}
                          onCheckedChange={(checked) =>
                            setSelected((prev) =>
                              checked ? [...prev, task.id] : prev.filter((id) => id !== task.id)
                            )
                          }
                        />
                        <div>
                          <p className="text-sm font-medium text-slate-900">{task.title}</p>
                          {task.description && <p className="text-xs text-slate-600">{task.description}</p>}
                        </div>
                      </label>
                    ))
                  )}
                </div>
                <Button onClick={() => void handleAssign()} disabled={saving || selected.length === 0}>
                  {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Ausgewaehlte Tasks zuweisen'}
                </Button>
              </section>
            </CardContent>
          </Card>
        </>
      )}
    </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 mapPriority(priority: TenantTask['priority']): string {
  switch (priority) {
    case 'low':
      return 'Niedrig';
    case 'high':
      return 'Hoch';
    case 'urgent':
      return 'Dringend';
    default:
      return 'Mittel';
  }
}

function renderName(name: TenantEvent['name']): string {
  if (typeof name === 'string') {
    return name;
  }
  return name?.de ?? name?.en ?? Object.values(name ?? {})[0] ?? 'Unbenanntes Event';
}
