import React from 'react';
import { useNavigate } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { CheckCircle2, Circle, Loader2, Pencil, Plus, Trash2 } 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 { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Switch } from '@/components/ui/switch';

import { AdminLayout } from '../components/AdminLayout';
import {
  createTask,
  deleteTask,
  getTasks,
  PaginationMeta,
  TenantTask,
  TaskPayload,
  updateTask,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { ADMIN_EVENTS_PATH, ADMIN_TASK_COLLECTIONS_PATH } from '../constants';

type TaskFormState = {
  title: string;
  description: string;
  priority: TaskPayload['priority'];
  due_date: string;
  is_completed: boolean;
};

const INITIAL_FORM: TaskFormState = {
  title: '',
  description: '',
  priority: 'medium',
  due_date: '',
  is_completed: false,
};

export default function TasksPage() {
  const navigate = useNavigate();
  const { t } = useTranslation('common');
  const [tasks, setTasks] = React.useState<TenantTask[]>([]);
  const [meta, setMeta] = React.useState<PaginationMeta | null>(null);
  const [page, setPage] = React.useState(1);
  const [search, setSearch] = React.useState('');
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [dialogOpen, setDialogOpen] = React.useState(false);
  const [editingTask, setEditingTask] = React.useState<TenantTask | null>(null);
  const [form, setForm] = React.useState<TaskFormState>(INITIAL_FORM);
  const [saving, setSaving] = React.useState(false);

  React.useEffect(() => {
    let cancelled = false;
    setLoading(true);
    setError(null);

    getTasks({ page, search: search.trim() || undefined })
      .then((result) => {
        if (cancelled) return;
        setTasks(result.data);
        setMeta(result.meta);
      })
      .catch((err) => {
        if (!isAuthError(err)) {
          setError('Tasks konnten nicht geladen werden.');
        }
      })
      .finally(() => {
        if (!cancelled) {
          setLoading(false);
        }
      });

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

  function openCreate() {
    setEditingTask(null);
    setForm(INITIAL_FORM);
    setDialogOpen(true);
  }

  function openEdit(task: TenantTask) {
    setEditingTask(task);
    setForm({
      title: task.title,
      description: task.description ?? '',
      priority: task.priority ?? 'medium',
      due_date: task.due_date ? task.due_date.slice(0, 10) : '',
      is_completed: task.is_completed,
    });
    setDialogOpen(true);
  }

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!form.title.trim()) {
      setError('Bitte gib einen Titel ein.');
      return;
    }

    setSaving(true);
    setError(null);
    const payload: TaskPayload = {
      title: form.title.trim(),
      description: form.description.trim() || null,
      priority: form.priority ?? undefined,
      due_date: form.due_date || undefined,
      is_completed: form.is_completed,
    };

    try {
      if (editingTask) {
        const updated = await updateTask(editingTask.id, payload);
        setTasks((prev) => prev.map((task) => (task.id === updated.id ? updated : task)));
      } else {
        const created = await createTask(payload);
        setTasks((prev) => [created, ...prev]);
      }
      setDialogOpen(false);
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Task konnte nicht gespeichert werden.');
      }
    } finally {
      setSaving(false);
    }
  }

  async function handleDelete(taskId: number) {
    if (!window.confirm('Task wirklich loeschen?')) {
      return;
    }

    try {
      await deleteTask(taskId);
      setTasks((prev) => prev.filter((task) => task.id !== taskId));
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Task konnte nicht geloescht werden.');
      }
    }
  }

  async function toggleCompletion(task: TenantTask) {
    if (task.tenant_id === null) {
      return;
    }
    try {
      const updated = await updateTask(task.id, { is_completed: !task.is_completed });
      setTasks((prev) => prev.map((entry) => (entry.id === updated.id ? updated : entry)));
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Status konnte nicht aktualisiert werden.');
      }
    }
  }

  return (
    <AdminLayout
      title="Task Bibliothek"
      subtitle="Weise Aufgaben zu und tracke Fortschritt rund um deine Events."
      actions={
        <div className="flex flex-wrap gap-2">
          <Button variant="outline" onClick={() => navigate(ADMIN_TASK_COLLECTIONS_PATH)}>
            {t('navigation.collections')}
          </Button>
          <Button
            className="bg-gradient-to-r from-pink-500 via-fuchsia-500 to-purple-500 text-white shadow-lg shadow-pink-500/20"
            onClick={openCreate}
          >
            <Plus className="h-4 w-4" />
            Neu
          </Button>
        </div>
      }
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>Fehler</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      <Card className="border-0 bg-white/85 shadow-xl shadow-pink-100/60">
        <CardHeader>
          <CardTitle className="text-xl text-slate-900">Tasks verwalten</CardTitle>
          <CardDescription className="text-sm text-slate-600">
            Erstelle Aufgaben und ordne sie deinen Events zu.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
            <Input
              placeholder="Nach Tasks suchen..."
              value={search}
              onChange={(event) => setSearch(event.target.value)}
              className="sm:max-w-sm"
            />
            <Button variant="outline" onClick={() => navigate(ADMIN_EVENTS_PATH)}>
              Events oeffnen
            </Button>
          </div>

          {loading ? (
            <TaskSkeleton />
          ) : tasks.length === 0 ? (
            <EmptyTasksState onCreate={openCreate} />
          ) : (
            <div className="grid gap-4">
              {tasks.map((task) => (
                <TaskRow
                  key={task.id}
                  task={task}
                  onToggle={() => void toggleCompletion(task)}
                  onEdit={() => openEdit(task)}
                  onDelete={() => void handleDelete(task.id)}
                />
              ))}
            </div>
          )}

          {meta && meta.last_page > 1 && (
            <div className="flex items-center justify-between">
              <Button
                variant="outline"
                disabled={page <= 1}
                onClick={() => setPage((prev) => Math.max(prev - 1, 1))}
              >
                Zurueck
              </Button>
              <span className="text-xs text-slate-500">
                Seite {meta.current_page} von {meta.last_page}
              </span>
              <Button
                variant="outline"
                disabled={page >= meta.last_page}
                onClick={() => setPage((prev) => Math.min(prev + 1, meta.last_page))}
              >
                Weiter
              </Button>
            </div>
          )}
        </CardContent>
      </Card>

      <TaskDialog
        open={dialogOpen}
        onOpenChange={setDialogOpen}
        onSubmit={handleSubmit}
        form={form}
        setForm={setForm}
        saving={saving}
        isEditing={Boolean(editingTask)}
      />
    </AdminLayout>
  );
}

function TaskRow({
  task,
  onToggle,
  onEdit,
  onDelete,
}: {
  task: TenantTask;
  onToggle: () => void;
  onEdit: () => void;
  onDelete: () => void;
}) {
  const assignedCount = task.assigned_events_count ?? task.assigned_events?.length ?? 0;
  const completed = task.is_completed;
  const isGlobal = task.tenant_id === null;

  return (
    <div className="flex flex-col gap-3 rounded-2xl border border-slate-100 bg-white/90 p-4 shadow-sm sm:flex-row sm:items-center sm:justify-between">
      <div className="flex flex-1 items-start gap-3">
        <button
          type="button"
          onClick={isGlobal ? undefined : onToggle}
          aria-disabled={isGlobal}
          className={`rounded-full border border-pink-200 bg-white/80 p-2 text-pink-600 shadow-sm transition ${
            isGlobal ? 'opacity-50 cursor-not-allowed' : 'hover:bg-pink-50'
          }`}
        >
          {completed ? <CheckCircle2 className="h-5 w-5" /> : <Circle className="h-5 w-5" />}
        </button>
        <div className="space-y-1">
          <div className="flex flex-wrap items-center gap-2">
            <p className={`text-sm font-semibold ${completed ? 'text-slate-500 line-through' : 'text-slate-900'}`}>
              {task.title}
            </p>
            <Badge variant="outline" className="border-pink-200 text-pink-600">
              {mapPriority(task.priority)}
            </Badge>
            {isGlobal && (
              <Badge variant="secondary" className="bg-slate-100 text-slate-600">
                Global
              </Badge>
            )}
          </div>
          {task.description && <p className="text-xs text-slate-600">{task.description}</p>}
          <div className="flex flex-wrap items-center gap-3 text-xs text-slate-500">
            {task.due_date && <span>Faellig: {formatDate(task.due_date)}</span>}
            <span>Zugeordnet: {assignedCount}</span>
          </div>
        </div>
      </div>
      <div className="flex flex-wrap items-center gap-2">
        <Button variant="outline" size="sm" onClick={onEdit} disabled={isGlobal} className={isGlobal ? 'opacity-50' : ''}>
          <Pencil className="h-4 w-4" />
        </Button>
        <Button
          variant="outline"
          size="sm"
          onClick={onDelete}
          className={`text-rose-600 ${isGlobal ? 'opacity-50' : ''}`}
          disabled={isGlobal}
        >
          <Trash2 className="h-4 w-4" />
        </Button>
      </div>
    </div>
  );
}

function TaskDialog({
  open,
  onOpenChange,
  onSubmit,
  form,
  setForm,
  saving,
  isEditing,
}: {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
  form: TaskFormState;
  setForm: React.Dispatch<React.SetStateAction<TaskFormState>>;
  saving: boolean;
  isEditing: boolean;
}) {
  const handleFormSubmit = React.useCallback((event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    onSubmit(event);
  }, [onSubmit]);

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-lg">
        <DialogHeader>
          <DialogTitle>{isEditing ? 'Task bearbeiten' : 'Neuen Task anlegen'}</DialogTitle>
        </DialogHeader>

        <form className="space-y-4" onSubmit={handleFormSubmit}>
          <div className="space-y-2">
            <Label htmlFor="task-title">Titel</Label>
            <Input
              id="task-title"
              value={form.title}
              onChange={(event) => setForm((prev) => ({ ...prev, title: event.target.value }))}
              required
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="task-description">Beschreibung</Label>
            <textarea
              id="task-description"
              value={form.description}
              onChange={(event) => setForm((prev) => ({ ...prev, description: event.target.value }))}
              className="min-h-[80px] w-full rounded-md border border-slate-200 bg-white/80 p-2 text-sm shadow-sm focus:border-pink-300 focus:outline-none focus:ring-2 focus:ring-pink-200"
            />
          </div>

          <div className="grid gap-4 sm:grid-cols-2">
            <div className="space-y-2">
              <Label htmlFor="task-priority">Prioritaet</Label>
              <Select
                value={form.priority ?? 'medium'}
                onValueChange={(value) => setForm((prev) => ({ ...prev, priority: value as TaskPayload['priority'] }))}
              >
                <SelectTrigger id="task-priority">
                  <SelectValue placeholder="Prioritaet waehlen" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="low">Niedrig</SelectItem>
                  <SelectItem value="medium">Mittel</SelectItem>
                  <SelectItem value="high">Hoch</SelectItem>
                  <SelectItem value="urgent">Dringend</SelectItem>
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-2">
              <Label htmlFor="task-due-date">Faellig am</Label>
              <Input
                id="task-due-date"
                type="date"
                value={form.due_date}
                onChange={(event) => setForm((prev) => ({ ...prev, due_date: event.target.value }))}
              />
            </div>
          </div>

          <div className="flex items-center justify-between rounded-lg border border-pink-100 bg-pink-50/60 p-3">
            <div>
              <Label htmlFor="task-completed" className="text-sm font-medium text-slate-800">
                Bereits erledigt
              </Label>
              <p className="text-xs text-slate-500">Markiere Task als abgeschlossen.</p>
            </div>
            <Switch
              id="task-completed"
              checked={form.is_completed}
              onCheckedChange={(checked) => setForm((prev) => ({ ...prev, is_completed: Boolean(checked) }))}
            />
          </div>

          <div className="flex justify-end gap-2">
            <Button type="button" variant="outline" onClick={() => onOpenChange(false)}>
              Abbrechen
            </Button>
            <Button type="submit" disabled={saving}>
              {saving ? <Loader2 className="h-4 w-4 animate-spin" /> : 'Speichern'}
            </Button>
          </div>
        </form>
      </DialogContent>
    </Dialog>
  );
}

function EmptyTasksState({ onCreate }: { onCreate: () => void }) {
  return (
    <div className="flex flex-col items-center justify-center gap-3 rounded-2xl border border-dashed border-slate-200 bg-white/70 p-10 text-center">
      <div className="rounded-full bg-pink-100 p-3 text-pink-600 shadow-inner shadow-pink-200/80">
        <Plus className="h-5 w-5" />
      </div>
      <p className="text-sm text-slate-600">Noch keine Tasks angelegt. Lege deinen ersten Task an.</p>
      <Button onClick={onCreate}>Task erstellen</Button>
    </div>
  );
}

function TaskSkeleton() {
  return (
    <div className="space-y-3">
      {Array.from({ length: 4 }).map((_, index) => (
        <div key={index} className="h-24 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 formatDate(value: string | null | undefined): string {
  if (!value) return '--';
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return '--';
  return date.toLocaleDateString('de-DE', { day: '2-digit', month: 'short', year: 'numeric' });
}
