import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ArrowLeft, Loader2, Save, Sparkles } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';

import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Checkbox } from '@/components/ui/checkbox';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';

import { AdminLayout } from '../components/AdminLayout';
import { createEvent, getEvent, updateEvent, getPackages } from '../api';
import { isAuthError } from '../auth/tokens';
import { ADMIN_EVENT_VIEW_PATH, ADMIN_EVENTS_PATH } from '../constants';

interface EventFormState {
  name: string;
  slug: string;
  date: string;
  package_id: number;
  isPublished: boolean;
}

export default function EventFormPage() {
  const params = useParams<{ slug?: string }>();
  const [searchParams] = useSearchParams();
  const slugParam = params.slug ?? searchParams.get('slug') ?? undefined;
  const isEdit = Boolean(slugParam);
  const navigate = useNavigate();

  const [form, setForm] = React.useState<EventFormState>({
    name: '',
    slug: '',
    date: '',
    package_id: 1, // Default Free package
    isPublished: false,
  });
  const [autoSlug, setAutoSlug] = React.useState(true);
  const [originalSlug, setOriginalSlug] = React.useState<string | null>(null);
  const [loading, setLoading] = React.useState(isEdit);
  const [saving, setSaving] = React.useState(false);
  const [error, setError] = React.useState<string | null>(null);

  const { data: packages, isLoading: packagesLoading } = useQuery({
    queryKey: ['packages', 'endcustomer'],
    queryFn: () => getPackages('endcustomer'),
  });

  React.useEffect(() => {
    let cancelled = false;
    if (!isEdit || !slugParam) {
      setLoading(false);
      return () => {
        cancelled = true;
      };
    }

    (async () => {
      try {
        const event = await getEvent(slugParam);
        if (cancelled) return;
        const name = normalizeName(event.name);
        setForm((prev) => ({
          ...prev,
          name,
          slug: event.slug,
          date: event.event_date ? event.event_date.slice(0, 10) : '',
          isPublished: event.status === 'published',
        }));
        setOriginalSlug(event.slug);
        setAutoSlug(false);
      } catch (err) {
        if (!isAuthError(err)) {
          setError('Event konnte nicht geladen werden.');
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    })();

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

  function handleNameChange(value: string) {
    setForm((prev) => ({ ...prev, name: value }));
    if (autoSlug) {
      setForm((prev) => ({ ...prev, slug: slugify(value) }));
    }
  }

  function handleSlugChange(value: string) {
    setAutoSlug(false);
    setForm((prev) => ({ ...prev, slug: slugify(value) }));
  }

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const trimmedName = form.name.trim();
    const trimmedSlug = form.slug.trim();

    if (!trimmedName) {
      setError('Bitte gib einen Eventnamen ein.');
      return;
    }

    if (!trimmedSlug) {
      setError('Bitte waehle einen Slug fuer die Event-URL.');
      return;
    }

    setSaving(true);
    setError(null);

    const status: 'draft' | 'published' | 'archived' = form.isPublished ? 'published' : 'draft';

    const payload = {
      name: trimmedName,
      slug: trimmedSlug,
      package_id: form.package_id,
      date: form.date || undefined,
      status,
    };

    try {
      if (isEdit) {
        const targetSlug = originalSlug ?? slugParam!;
        const updated = await updateEvent(targetSlug, payload);
        setOriginalSlug(updated.slug);
        navigate(ADMIN_EVENT_VIEW_PATH(updated.slug));
      } else {
        const { event: created } = await createEvent(payload);
        navigate(ADMIN_EVENT_VIEW_PATH(created.slug));
      }
    } catch (err) {
      if (!isAuthError(err)) {
        setError('Speichern fehlgeschlagen. Bitte pruefe deine Eingaben.');
      }
    } finally {
      setSaving(false);
    }
  }

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

  return (
    <AdminLayout
      title={isEdit ? 'Event bearbeiten' : 'Neues Event erstellen'}
      subtitle="Fuelle die wichtigsten Angaben aus und teile dein Event mit Gaesten."
      actions={actions}
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>Hinweis</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      <Card className="border-0 bg-white/85 shadow-xl shadow-fuchsia-100/60">
        <CardHeader>
          <CardTitle className="flex items-center gap-2 text-xl text-slate-900">
            <Sparkles className="h-5 w-5 text-pink-500" /> Eventdetails
          </CardTitle>
          <CardDescription className="text-sm text-slate-600">
            Name, URL und Datum bestimmen das Auftreten deines Events im Gaesteportal.
          </CardDescription>
        </CardHeader>
        <CardContent>
          {loading ? (
            <FormSkeleton />
          ) : (
            <form className="space-y-6" onSubmit={handleSubmit}>
              <div className="grid gap-4 sm:grid-cols-2">
                <div className="space-y-2 sm:col-span-2">
                  <Label htmlFor="event-name">Eventname</Label>
                  <Input
                    id="event-name"
                    placeholder="z. B. Sommerfest 2025"
                    value={form.name}
                    onChange={(e) => handleNameChange(e.target.value)}
                    autoFocus
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="event-slug">Slug / interne Kennung</Label>
                  <Input
                    id="event-slug"
                    placeholder="sommerfest-2025"
                    value={form.slug}
                    onChange={(e) => handleSlugChange(e.target.value)}
                  />
                  <p className="text-xs text-slate-500">
                    Diese Kennung wird intern verwendet. Gaeste erhalten Zugriff ausschliesslich ueber Join-Tokens und deren
                    QR-/Layout-Downloads.
                  </p>
                </div>
                <div className="space-y-2">
                  <Label htmlFor="event-date">Datum</Label>
                  <Input
                    id="event-date"
                    type="date"
                    value={form.date}
                    onChange={(e) => setForm((prev) => ({ ...prev, date: e.target.value }))}
                  />
                </div>
                <div className="space-y-2">
                  <Label htmlFor="package_id">Package</Label>
                  <Select
                    value={form.package_id.toString()}
                    onValueChange={(value) => setForm((prev) => ({ ...prev, package_id: parseInt(value, 10) }))}
                    disabled={packagesLoading || !packages?.length}
                  >
                    <SelectTrigger>
                      <SelectValue placeholder={packagesLoading ? 'Pakete werden geladen...' : 'Waehlen Sie ein Package'} />
                    </SelectTrigger>
                    {packages?.length ? (
                      <SelectContent>
                        {packages.map((pkg) => (
                          <SelectItem key={pkg.id} value={pkg.id.toString()}>
                            {pkg.name} - {pkg.price} EUR ({pkg.max_photos} Fotos)
                          </SelectItem>
                        ))}
                      </SelectContent>
                    ) : null}
                  </Select>
                  {packagesLoading ? (
                    <p className="text-xs text-slate-500">Pakete werden geladen...</p>
                  ) : null}
                  {!packagesLoading && (!packages || packages.length === 0) ? (
                    <p className="text-xs text-red-500">Keine Pakete verfuegbar. Bitte pruefen Sie Ihre Einstellungen.</p>
                  ) : null}
                  <Dialog>
                    <DialogTrigger asChild>
                      <Button variant="outline" size="sm">Package-Details</Button>
                    </DialogTrigger>
                    <DialogContent>
                      <DialogHeader>
                        <DialogTitle>Package auswaehlen</DialogTitle>
                        <DialogDescription>Waehlen Sie das Package fuer Ihr Event. Hoehere Packages bieten mehr Limits und Features.</DialogDescription>
                      </DialogHeader>
                      <div className="space-y-2">
                        {packages?.map((pkg) => (
                          <div key={pkg.id} className="p-4 border rounded">
                            <h3 className="font-semibold">{pkg.name}</h3>
                            <p>{pkg.price} EUR</p>
                            <ul className="text-sm">
                              <li>Max Fotos: {pkg.max_photos}</li>
                              <li>Max Gaeste: {pkg.max_guests}</li>
                              <li>Galerie: {pkg.gallery_days} Tage</li>
                              <li>Features: {Object.keys(pkg.features).filter(k => pkg.features[k]).join(', ')}</li>
                            </ul>
                          </div>
                        ))}
                      </div>
                    </DialogContent>
                  </Dialog>
                </div>
              </div>

              <div className="flex items-start gap-3 rounded-xl bg-pink-50/60 p-4">
                <Checkbox
                  id="event-published"
                  checked={form.isPublished}
                  onCheckedChange={(checked) => setForm((prev) => ({ ...prev, isPublished: Boolean(checked) }))}
                />
                <div>
                  <Label htmlFor="event-published" className="text-sm font-medium text-slate-800">
                    Event sofort veroeffentlichen
                  </Label>
                  <p className="text-xs text-slate-600">
                    Aktiviere diese Option, wenn Gaeste das Event direkt sehen sollen. Du kannst den Status spaeter aendern.
                  </p>
                </div>
              </div>

              <div className="flex flex-wrap gap-3">
                <Button
                  type="submit"
                  disabled={saving || !form.name.trim() || !form.slug.trim()}
                  className="bg-gradient-to-r from-pink-500 via-fuchsia-500 to-purple-500 text-white shadow-lg shadow-pink-500/20"
                >
                  {saving ? (
                    <>
                      <Loader2 className="h-4 w-4 animate-spin" /> Speichert
                    </>
                  ) : (
                    <>
                      <Save className="h-4 w-4" /> Speichern
                    </>
                  )}
                </Button>
                <Button variant="ghost" type="button" onClick={() => navigate(-1)}>
                  Abbrechen
                </Button>
              </div>
            </form>
          )}
        </CardContent>
      </Card>
    </AdminLayout>
  );
}

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

function slugify(value: string): string {
  return value
    .normalize('NFKD')
    .toLowerCase()
    .replace(/[\u0300-\u036f]/g, '')
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/(^-|-$)+/g, '')
    .slice(0, 60);
}

function normalizeName(name: string | Record<string, string>): string {
  if (typeof name === 'string') {
    return name;
  }
  return name.de ?? name.en ?? Object.values(name)[0] ?? '';
}
