import React from 'react';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ArrowLeft, Loader2, Mail, Sparkles, Trash2, Users } from 'lucide-react';
import { useTranslation } from 'react-i18next';

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 { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';

import { AdminLayout } from '../components/AdminLayout';
import {
  EventMember,
  getEvent,
  getEventMembers,
  inviteEventMember,
  removeEventMember,
  TenantEvent,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { ADMIN_EVENTS_PATH } from '../constants';

type InviteForm = {
  email: string;
  name: string;
  role: EventMember['role'];
};

const emptyInvite: InviteForm = {
  email: '',
  name: '',
  role: 'member',
};

export default function EventMembersPage() {
  const { t, i18n } = useTranslation(['management', 'dashboard']);
  const locale = React.useMemo(
    () => (i18n.language?.startsWith('en') ? 'en-GB' : 'de-DE'),
    [i18n.language]
  );
  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 [members, setMembers] = React.useState<EventMember[]>([]);
  const [loading, setLoading] = React.useState(true);
  const [error, setError] = React.useState<string | null>(null);
  const [invite, setInvite] = React.useState<InviteForm>(emptyInvite);
  const [inviting, setInviting] = React.useState(false);
  const [membersUnavailable, setMembersUnavailable] = React.useState(false);

  const formatDate = React.useCallback(
    (value: string | null | undefined) => {
      if (!value) return '--';
      const date = new Date(value);
      if (Number.isNaN(date.getTime())) return '--';
      return date.toLocaleDateString(locale, { day: '2-digit', month: 'short', year: 'numeric' });
    },
    [locale]
  );

  const roleLabels = React.useMemo(
    () => ({
      tenant_admin: t('management.members.roles.tenantAdmin', 'Tenant-Admin'),
      member: t('management.members.roles.member', 'Mitglied'),
    }),
    [t]
  );

  const statusLabels = React.useMemo(
    () => ({
      published: t('management.members.statuses.published', 'Veröffentlicht'),
      draft: t('management.members.statuses.draft', 'Entwurf'),
      active: t('management.members.statuses.active', 'Aktiv'),
    }),
    [t]
  );

  const resolveRole = React.useCallback(
    (role: string) => roleLabels[role as keyof typeof roleLabels] ?? role,
    [roleLabels]
  );

  const resolveMemberStatus = React.useCallback(
    (status?: string | null) => {
      if (!status) {
        return statusLabels.active;
      }
      return statusLabels[status as keyof typeof statusLabels] ?? status;
    },
    [statusLabels]
  );

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

    let cancelled = false;
    (async () => {
      try {
        setLoading(true);
        const eventData = await getEvent(slug);
        if (cancelled) return;
        setEvent(eventData);

        const response = await getEventMembers(slug);
        if (cancelled) return;
        setMembers(response.data);
        setMembersUnavailable(false);
      } catch (err) {
        if (err instanceof Error && err.message.includes('Mitgliederverwaltung')) {
          setMembersUnavailable(true);
        } else if (!isAuthError(err)) {
          setError(t('management.members.errors.load', 'Mitglieder konnten nicht geladen werden.'));
        }
      } finally {
        if (!cancelled) {
          setLoading(false);
        }
      }
    })();

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

  async function handleInvite(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (!slug) return;
    if (!invite.email.trim()) {
      setError(t('management.members.errors.emailRequired', 'Bitte gib eine E-Mail-Adresse ein.'));
      return;
    }
    setInviting(true);
    try {
      const member = await inviteEventMember(slug, {
        email: invite.email.trim(),
        name: invite.name.trim() || undefined,
        role: invite.role,
      });
      setMembers((prev) => [member, ...prev]);
      setInvite(emptyInvite);
      setMembersUnavailable(false);
    } catch (err) {
      if (err instanceof Error && err.message.includes('Mitgliederverwaltung')) {
        setMembersUnavailable(true);
      } else if (!isAuthError(err)) {
        setError(t('management.members.errors.invite', 'Einladung konnte nicht verschickt werden.'));
      }
    } finally {
      setInviting(false);
    }
  }

  async function handleRemove(member: EventMember) {
    if (!slug) return;
    if (!window.confirm(`${member.name} wirklich entfernen?`)) return;
    try {
      await removeEventMember(slug, member.id);
      setMembers((prev) => prev.filter((entry) => entry.id !== member.id));
    } catch (err) {
      if (!isAuthError(err)) {
        setError(t('management.members.errors.remove', 'Mitglied konnte nicht entfernt werden.'));
      }
    }
  }

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

  return (
    <AdminLayout
      title={t('management.members.title', 'Event-Mitglieder')}
      subtitle={t('management.members.subtitle', 'Verwalte Moderatoren, Admins und Helfer für dieses Event.')}
      actions={actions}
    >
      {error && (
        <Alert variant="destructive">
          <AlertTitle>{t('dashboard.alerts.errorTitle', 'Fehler')}</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      )}

      {loading ? (
        <MembersSkeleton />
      ) : !event ? (
        <Alert variant="destructive">
          <AlertTitle>{t('management.members.alerts.notFoundTitle', 'Event nicht gefunden')}</AlertTitle>
          <AlertDescription>{t('management.members.alerts.notFoundDescription', 'Bitte kehre zur Eventliste zurück.')}</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, t)}</CardTitle>
              <CardDescription className="text-sm text-slate-600">
                {t('management.members.eventStatus', {
                  status: event.status === 'published' ? statusLabels.published : statusLabels.draft,
                })}
              </CardDescription>
            </CardHeader>
            <CardContent className="grid gap-6 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" />
                  {t('management.members.sections.list.title', 'Mitglieder')}
                </h3>
                {membersUnavailable ? (
                  <Alert>
                    <AlertTitle>{t('management.members.alerts.lockedTitle', 'Feature noch nicht aktiviert')}</AlertTitle>
                    <AlertDescription>
                      {t(
                        'management.members.alerts.lockedDescription',
                        'Die Mitgliederverwaltung ist für dieses Event noch nicht verfügbar. Bitte kontaktiere den Support, um das Feature freizuschalten.'
                      )}
                    </AlertDescription>
                  </Alert>
                ) : members.length === 0 ? (
                  <EmptyState message={t('management.members.sections.list.empty', 'Noch keine Mitglieder eingeladen.')} />
                ) : (
                  <div className="space-y-2">
                    {members.map((member) => (
                      <div
                        key={member.id}
                        className="flex flex-col gap-3 rounded-2xl border border-slate-100 bg-white/90 p-3 shadow-sm sm:flex-row sm:items-center sm:justify-between"
                      >
                        <div>
                          <p className="text-sm font-semibold text-slate-900">{member.name}</p>
                          <p className="text-xs text-slate-600">{member.email}</p>
                          <div className="mt-1 flex flex-wrap items-center gap-2 text-xs text-slate-500">
                            <span>
                              {t('management.members.labels.status', {
                                status: resolveMemberStatus(member.status),
                              })}
                            </span>
                            {member.joined_at && (
                              <span>
                                {t('management.members.labels.joined', {
                                  date: formatDate(member.joined_at),
                                })}
                              </span>
                            )}
                          </div>
                        </div>
                        <div className="flex items-center gap-2">
                          <Badge variant="outline" className="border-pink-200 text-pink-600">
                            {resolveRole(member.role)}
                          </Badge>
                          <Button variant="outline" size="sm" onClick={() => void handleRemove(member)}>
                            <Trash2 className="h-4 w-4" />
                          </Button>
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </section>

              <section className="space-y-3">
                <h3 className="flex items-center gap-2 text-sm font-semibold text-slate-900">
                  <Users className="h-4 w-4 text-emerald-500" />
                  {t('management.members.sections.invite.title', 'Neues Mitglied einladen')}
                </h3>
                <p className="text-xs text-slate-500">
                  {t(
                    'management.members.sections.invite.helper',
                    'Mitglieder erhalten Zugriff auf Fotomoderation, Aufgaben und QR-Einladungen. Admins steuern zusätzlich Pakete, Abrechnung und Events.'
                  )}
                </p>
                <form className="space-y-3 rounded-2xl border border-emerald-100 bg-white/90 p-4 shadow-sm" onSubmit={handleInvite}>
                  <div className="space-y-2">
                    <Label htmlFor="invite-email">{t('management.members.form.emailLabel', 'E-Mail')}</Label>
                    <Input
                      id="invite-email"
                      type="email"
                      placeholder={t('management.members.form.emailPlaceholder', 'person@example.com')}
                      value={invite.email}
                      onChange={(event) => setInvite((prev) => ({ ...prev, email: event.target.value }))}
                      required
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="invite-name">{t('management.members.form.nameLabel', 'Name (optional)')}</Label>
                    <Input
                      id="invite-name"
                      placeholder={t('management.members.form.namePlaceholder', 'Name')}
                      value={invite.name}
                      onChange={(event) => setInvite((prev) => ({ ...prev, name: event.target.value }))}
                    />
                  </div>
                  <div className="space-y-2">
                    <Label htmlFor="invite-role">{t('management.members.form.roleLabel', 'Rolle')}</Label>
                    <Select
                      value={invite.role}
                      onValueChange={(value) => setInvite((prev) => ({ ...prev, role: value as InviteForm['role'] }))}
                    >
                      <SelectTrigger id="invite-role">
                        <SelectValue placeholder={t('management.members.form.rolePlaceholder', 'Rolle wählen')} />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="tenant_admin">{roleLabels.tenant_admin}</SelectItem>
                        <SelectItem value="member">{roleLabels.member}</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>
                  <Button type="submit" className="w-full" disabled={inviting}>
                    {inviting ? <Loader2 className="h-4 w-4 animate-spin" /> : <Mail className="h-4 w-4" />}
                    {' '}{t('management.members.form.submit', 'Einladung senden')}
                  </Button>
                </form>
              </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 MembersSkeleton() {
  return (
    <div className="space-y-4">
      {Array.from({ length: 3 }).map((_, index) => (
        <div key={index} className="h-40 animate-pulse rounded-2xl bg-gradient-to-r from-white/40 via-white/60 to-white/40" />
      ))}
    </div>
  );
}

function renderName(name: TenantEvent['name'], translate: (key: string, defaultValue: string) => string): string {
  if (typeof name === 'string') {
    return name;
  }
  return name?.de ?? name?.en ?? Object.values(name ?? {})[0] ?? translate('management.members.events.untitled', 'Unbenanntes Event');
}
