import React from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import { AlertCircle, ArrowLeft, CheckCircle2, Circle, Clock3, Loader2, PlugZap, Power, RefreshCw, ShieldCheck, Copy } 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 { AdminLayout } from '../components/AdminLayout';
import {
  PhotoboothStatus,
  TenantEvent,
  type EventToolkit,
  type TenantPhoto,
  disableEventPhotobooth,
  enableEventPhotobooth,
  getEvent,
  getEventPhotoboothStatus,
  getEventToolkit,
  rotateEventPhotobooth,
} from '../api';
import { isAuthError } from '../auth/tokens';
import { getApiErrorMessage } from '../lib/apiError';
import { ADMIN_EVENTS_PATH, ADMIN_EVENT_VIEW_PATH } from '../constants';
import { buildEventTabs } from '../lib/eventTabs';

type State = {
  event: TenantEvent | null;
  status: PhotoboothStatus | null;
  toolkit: EventToolkit | null;
  loading: boolean;
  updating: boolean;
  error: string | null;
};

export default function EventPhotoboothPage() {
  const { slug } = useParams<{ slug: string }>();
  const navigate = useNavigate();
  const { t } = useTranslation(['management', 'common']);

  const [mode, setMode] = React.useState<'ftp' | 'sparkbooth'>('ftp');

  const [state, setState] = React.useState<State>({
    event: null,
    status: null,
    toolkit: null,
    loading: true,
    updating: false,
    error: null,
  });

  const load = React.useCallback(async () => {
    if (!slug) {
      setState((prev) => ({
        ...prev,
        loading: false,
        error: t('management.photobooth.errors.missingSlug', 'Kein Event ausgewählt.'),
      }));
      return;
    }

    setState((prev) => ({ ...prev, loading: true, error: null }));

    try {
      const toolkitPromise = getEventToolkit(slug)
        .then((data) => data)
        .catch((toolkitError) => {
          if (!isAuthError(toolkitError)) {
            console.warn('[Photobooth] Toolkit konnte nicht geladen werden', toolkitError);
          }
          return null;
        });
      const [eventData, statusData, toolkitData] = await Promise.all([getEvent(slug), getEventPhotoboothStatus(slug), toolkitPromise]);
      setState({
        event: eventData,
        status: statusData,
        toolkit: toolkitData,
        loading: false,
        updating: false,
        error: null,
      });
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          loading: false,
          error: getApiErrorMessage(error, t('management.photobooth.errors.loadFailed', 'Photobooth-Link konnte nicht geladen werden.')),
        }));
      } else {
        setState((prev) => ({ ...prev, loading: false }));
      }
    }
  }, [slug, t]);

  React.useEffect(() => {
    void load();
  }, [load]);

  React.useEffect(() => {
    if (state.status?.mode) {
      setMode(state.status.mode);
    }
  }, [state.status?.mode]);

  async function handleEnable(targetMode?: 'ftp' | 'sparkbooth'): Promise<void> {
    if (!slug) return;
    setState((prev) => ({ ...prev, updating: true, error: null }));

    try {
      const selectedMode = targetMode ?? mode;
      const result = await enableEventPhotobooth(slug, { mode: selectedMode });
      setState((prev) => ({
        ...prev,
        status: result,
        updating: false,
      }));
      if (result.mode) {
        setMode(result.mode);
      }
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          updating: false,
          error: getApiErrorMessage(error, t('management.photobooth.errors.enableFailed', 'Zugang konnte nicht aktiviert werden.')),
        }));
      } else {
        setState((prev) => ({ ...prev, updating: false }));
      }
    }
  }

  async function handleRotate(): Promise<void> {
    if (!slug) return;
    setState((prev) => ({ ...prev, updating: true, error: null }));

    try {
      const result = await rotateEventPhotobooth(slug, { mode });
      setState((prev) => ({
        ...prev,
        status: result,
        updating: false,
      }));
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          updating: false,
          error: getApiErrorMessage(error, t('management.photobooth.errors.rotateFailed', 'Zugangsdaten konnten nicht neu generiert werden.')),
        }));
      } else {
        setState((prev) => ({ ...prev, updating: false }));
      }
    }
  }

  async function handleDisable(options?: { skipConfirm?: boolean }): Promise<void> {
    if (!slug) return;
    if (!options?.skipConfirm && !window.confirm(t('management.photobooth.confirm.disable', 'Photobooth-Zugang deaktivieren?'))) {
      return;
    }

    setState((prev) => ({ ...prev, updating: true, error: null }));

    try {
      const result = await disableEventPhotobooth(slug, { mode });
      setState((prev) => ({
        ...prev,
        status: result,
        updating: false,
      }));
    } catch (error) {
      if (!isAuthError(error)) {
        setState((prev) => ({
          ...prev,
          updating: false,
          error: getApiErrorMessage(error, t('management.photobooth.errors.disableFailed', 'Zugang konnte nicht deaktiviert werden.')),
        }));
      } else {
        setState((prev) => ({ ...prev, updating: false }));
      }
    }
  }

  const { event, status, toolkit, loading, updating, error } = state;
  const title = event
    ? t('management.photobooth.titleForEvent', { defaultValue: 'Fotobox-Uploads verwalten', event: resolveEventName(event.name) })
    : t('management.photobooth.title', 'Fotobox-Uploads');
  const subtitle = t(
    'management.photobooth.subtitle',
    'Erstelle einen einfachen Photobooth-Link per FTP oder Sparkbooth-Upload. Rate-Limit: 20 Fotos/Minute.'
  );
  const eventTabs = React.useMemo(() => {
    if (!event || !slug) {
      return [];
    }
    const translateMenu = (key: string, fallback: string) => t(key, { defaultValue: fallback });
    return buildEventTabs(event, translateMenu, {
      photos: event.photo_count ?? event.pending_photo_count ?? undefined,
      tasks: event.tasks_count ?? undefined,
    });
  }, [event, slug, t]);

  const recentPhotos = React.useMemo(() => toolkit?.photos?.recent ?? [], [toolkit?.photos?.recent]);
  const photoboothRecent = React.useMemo(
    () => recentPhotos.filter((photo) => photo.ingest_source === 'photobooth' || photo.ingest_source === 'sparkbooth'),
    [recentPhotos]
  );
  const effectiveRecentPhotos = React.useMemo(
    () => (photoboothRecent.length > 0 ? photoboothRecent : recentPhotos),
    [photoboothRecent, recentPhotos],
  );
  const uploads24h = React.useMemo(
    () => countUploadsInWindow(effectiveRecentPhotos, 24 * 60 * 60 * 1000),
    [effectiveRecentPhotos],
  );
  const recentShare = React.useMemo(() => {
    if (recentPhotos.length === 0) {
      return null;
    }
    const ratio = photoboothRecent.length / recentPhotos.length;
    return Math.round(ratio * 100);
  }, [photoboothRecent.length, recentPhotos.length]);
  const lastUploadAt = React.useMemo(() => {
    const latestPhoto = selectLatestUpload(effectiveRecentPhotos);
    if (latestPhoto?.uploaded_at) {
      return latestPhoto.uploaded_at;
    }
    return status?.metrics?.last_upload_at ?? null;
  }, [effectiveRecentPhotos, status?.metrics?.last_upload_at]);
  const lastUploadSource: 'photobooth' | 'event' | null = photoboothRecent.length > 0
    ? 'photobooth'
    : recentPhotos.length > 0
      ? 'event'
      : null;
  const eventUploadsTotal = toolkit?.metrics.uploads_total ?? event?.photo_count ?? 0;
  const uploadStats = React.useMemo(
    () => ({
      uploads24h,
      shareRecent: recentShare,
      totalEventUploads: eventUploadsTotal ?? 0,
      lastUploadAt,
      source: lastUploadSource,
      sampleSize: recentPhotos.length,
    }),
    [uploads24h, recentShare, eventUploadsTotal, lastUploadAt, lastUploadSource, recentPhotos.length],
  );

  const actions = (
    <div className="flex gap-2">
      {slug ? (
        <Button variant="outline" onClick={() => navigate(ADMIN_EVENT_VIEW_PATH(slug))}>
          <ArrowLeft className="mr-2 h-4 w-4" />
          {t('management.photobooth.actions.backToEvent', 'Zur Detailansicht')}
        </Button>
      ) : null}
      <Button variant="ghost" onClick={() => navigate(ADMIN_EVENTS_PATH)}>
        {t('management.photobooth.actions.allEvents', 'Zur Eventliste')}
      </Button>
    </div>
  );

  return (
    <AdminLayout title={title} subtitle={subtitle} actions={actions} tabs={eventTabs} currentTabKey="photobooth">
      {error ? (
        <Alert variant="destructive" className="mb-4">
          <AlertTitle>{t('common:messages.error', 'Fehler')}</AlertTitle>
          <AlertDescription>{error}</AlertDescription>
        </Alert>
      ) : null}

      {loading ? (
        <PhotoboothSkeleton />
      ) : (
        <div className="space-y-6">
          <div className="rounded-3xl border border-slate-200/80 bg-white/70 p-5 shadow-sm">
            <div className="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
              <div>
                <p className="text-sm font-semibold text-slate-900">
                  {t('management.photobooth.mode.title', 'Photobooth-Typ auswählen')}
                </p>
                <p className="text-xs text-slate-500">
                  {t(
                    'management.photobooth.mode.description',
                    'Wähle zwischen klassischem FTP und Sparkbooth HTTP-Upload. Umschalten generiert neue Zugangsdaten.'
                  )}
                </p>
              </div>
              <div className="flex flex-wrap gap-2">
                <Button
                  variant={mode === 'ftp' ? 'default' : 'outline'}
                  onClick={() => handleEnable('ftp')}
                  disabled={updating || mode === 'ftp'}
                >
                  FTP (Classic)
                </Button>
                <Button
                  variant={mode === 'sparkbooth' ? 'default' : 'outline'}
                  onClick={() => handleEnable('sparkbooth')}
                  disabled={updating || mode === 'sparkbooth'}
                >
                  Sparkbooth (HTTP)
                </Button>
              </div>
            </div>
            <p className="mt-3 text-xs text-slate-500">
              {t('management.photobooth.mode.active', 'Aktuell: {{mode}}', {
                mode: mode === 'sparkbooth' ? 'Sparkbooth / HTTP' : 'FTP',
              })}
            </p>
          </div>
          <div className="grid gap-6 lg:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]">
            <StatusCard status={status} />
            <SetupChecklistCard status={status} />
          </div>
          <div className="grid gap-6 lg:grid-cols-[minmax(0,1.05fr)_minmax(0,0.95fr)]">
            <ModePresetsCard
              status={status}
              updating={updating}
              onEnable={handleEnable}
              onDisable={() => handleDisable({ skipConfirm: true })}
              onRotate={handleRotate}
            />
            <UploadStatsCard stats={uploadStats} />
          </div>
          <CredentialsCard status={status} updating={updating} onEnable={handleEnable} onRotate={handleRotate} onDisable={handleDisable} />
          <div className="grid gap-6 lg:grid-cols-2">
            <StatusTimelineCard status={status} lastUploadAt={lastUploadAt} />
            <RateLimitCard status={status} uploadsLastHour={status?.metrics?.uploads_last_hour ?? null} />
          </div>
        </div>
      )}
    </AdminLayout>
  );
}

function resolveEventName(name: TenantEvent['name']): string {
  if (typeof name === 'string') {
    return name;
  }
  if (name && typeof name === 'object') {
    return Object.values(name)[0] ?? 'Event';
  }
  return 'Event';
}

function PhotoboothSkeleton() {
  return (
    <div className="space-y-4">
      {Array.from({ length: 3 }).map((_, idx) => (
        <div key={idx} className="rounded-3xl border border-slate-200/80 bg-white/70 p-6 shadow-sm">
          <div className="h-4 w-32 animate-pulse rounded bg-slate-200/80" />
          <div className="mt-4 h-3 w-full animate-pulse rounded bg-slate-100" />
          <div className="mt-2 h-3 w-3/4 animate-pulse rounded bg-slate-100" />
        </div>
      ))}
    </div>
  );
}

type ModePresetsCardProps = {
  status: PhotoboothStatus | null;
  updating: boolean;
  onEnable: () => Promise<void>;
  onDisable: () => Promise<void>;
  onRotate: () => Promise<void>;
};

function ModePresetsCard({ status, updating, onEnable, onDisable, onRotate }: ModePresetsCardProps) {
  const { t } = useTranslation('management');
  const activePreset: 'plan' | 'live' = status?.enabled ? 'live' : 'plan';
  const [selectedPreset, setSelectedPreset] = React.useState<'plan' | 'live'>(activePreset);

  React.useEffect(() => {
    setSelectedPreset(activePreset);
  }, [activePreset]);

  const presets = React.useMemo(
    () => [
      {
        key: 'plan' as const,
        title: t('photobooth.presets.planTitle', 'Planungsmodus'),
        description: t('photobooth.presets.planDescription', 'Zugang bleibt deaktiviert, um Tests vorzubereiten.'),
        badge: t('photobooth.presets.badgePlan', 'Planung'),
        icon: <Clock3 className="h-5 w-5 text-slate-500" />,
      },
      {
        key: 'live' as const,
        title: t('photobooth.presets.liveTitle', 'Live-Modus'),
        description: t('photobooth.presets.liveDescription', 'Uploads sind aktiv (FTP oder Sparkbooth) und werden direkt verarbeitet.'),
        badge: t('photobooth.presets.badgeLive', 'Live'),
        icon: <PlugZap className="h-5 w-5 text-emerald-500" />,
      },
    ],
    [t],
  );

  const handleApply = React.useCallback(() => {
    if (selectedPreset === activePreset) {
      return;
    }
    if (selectedPreset === 'live') {
      void onEnable();
    } else {
      void onDisable();
    }
  }, [activePreset, onDisable, onEnable, selectedPreset]);

  return (
    <Card className="rounded-3xl border border-slate-200/80 shadow-sm">
      <CardHeader>
        <CardTitle>{t('photobooth.presets.title', 'Modus wählen')}</CardTitle>
        <CardDescription>{t('photobooth.presets.description', 'Passe die Photobooth an Vorbereitung oder Live-Betrieb an.')}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-4">
        <div className="grid gap-3 md:grid-cols-2">
          {presets.map((preset) => {
            const isSelected = selectedPreset === preset.key;
            const isActive = activePreset === preset.key;
            return (
              <button
                key={preset.key}
                type="button"
                onClick={() => setSelectedPreset(preset.key)}
                className={`flex h-full flex-col items-start gap-3 rounded-2xl border p-4 text-left transition ${
                  isSelected ? 'border-emerald-400 bg-emerald-50/70 shadow-inner' : 'border-slate-200 hover:border-slate-300'
                }`}
              >
                <div className="flex items-center gap-3">
                  {preset.icon}
                  <div>
                    <p className="text-sm font-semibold text-slate-900">{preset.title}</p>
                    <p className="text-xs text-slate-500">{preset.description}</p>
                  </div>
                </div>
                <div className="flex flex-wrap items-center gap-2 text-xs text-slate-500">
                  <Badge variant="outline" className="border-slate-200 text-slate-600">
                    {preset.badge}
                  </Badge>
                  {isActive ? (
                    <Badge className="bg-emerald-500/20 text-emerald-700">
                      {t('photobooth.presets.current', 'Aktiv')}
                    </Badge>
                  ) : null}
                </div>
              </button>
            );
          })}
        </div>
        <div className="flex flex-wrap items-center gap-3 border-t border-slate-200 pt-4">
          <Button
            onClick={handleApply}
            disabled={selectedPreset === activePreset || updating}
            className="min-w-[160px]"
          >
            {updating ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <PlugZap className="mr-2 h-4 w-4" />}
            {t('photobooth.presets.actions.apply', 'Modus übernehmen')}
          </Button>
          <Button variant="outline" onClick={onRotate} disabled={updating}>
            <RefreshCw className="mr-2 h-4 w-4" />
            {t('photobooth.presets.actions.rotate', 'Zugang zurücksetzen')}
          </Button>
        </div>
      </CardContent>
    </Card>
  );
}

type UploadStatsCardProps = {
  stats: {
    uploads24h: number;
    shareRecent: number | null;
    totalEventUploads: number;
    lastUploadAt: string | null;
    source: 'photobooth' | 'event' | null;
    sampleSize: number;
  };
};

function UploadStatsCard({ stats }: UploadStatsCardProps) {
  const { t } = useTranslation('management');
  const lastUploadLabel = stats.lastUploadAt ? formatPhotoboothDate(stats.lastUploadAt) : t('photobooth.stats.none', 'Noch keine Uploads');
  const shareLabel = stats.shareRecent != null ? `${stats.shareRecent}%` : '—';
  const sourceLabel = stats.source === 'photobooth'
    ? t('photobooth.stats.sourcePhotobooth', 'Quelle: Photobooth')
    : stats.source === 'event'
      ? t('photobooth.stats.sourceEvent', 'Quelle: Event')
      : null;

  return (
    <Card className="rounded-3xl border border-slate-200/80 shadow-sm">
      <CardHeader>
        <CardTitle>{t('photobooth.stats.title', 'Upload-Status')}</CardTitle>
        <CardDescription>{t('photobooth.stats.description', 'Fokussiere deine Photobooth-Uploads der letzten Stunden.')}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-4 text-sm">
        <div className="flex items-center justify-between">
          <span className="text-slate-500">{t('photobooth.stats.lastUpload', 'Letzter Upload')}</span>
          <span className="font-semibold text-slate-900">{lastUploadLabel}</span>
        </div>
        {sourceLabel ? <p className="text-xs text-slate-500">{sourceLabel}</p> : null}
        <div className="flex items-center justify-between">
          <span className="text-slate-500">{t('photobooth.stats.uploads24h', 'Uploads (24h)')}</span>
          <span className="font-medium text-slate-900">{stats.uploads24h}</span>
        </div>
        <div className="flex items-center justify-between">
          <span className="text-slate-500">{t('photobooth.stats.share', 'Anteil Photobooth (letzte Uploads)')}</span>
          <span className="font-medium text-slate-900">{shareLabel}</span>
        </div>
        <div className="flex items-center justify-between">
          <span className="text-slate-500">{t('photobooth.stats.totalEvent', 'Uploads gesamt (Event)')}</span>
          <span className="font-medium text-slate-900">{stats.totalEventUploads}</span>
        </div>
        <div className="flex items-center justify-between border-t border-dashed border-slate-200 pt-3 text-xs text-slate-500">
          <span>{t('photobooth.stats.sample', 'Analysierte Uploads')}</span>
          <span>{stats.sampleSize}</span>
        </div>
      </CardContent>
    </Card>
  );
}

function SetupChecklistCard({ status }: { status: PhotoboothStatus | null }) {
  const { t } = useTranslation('management');
  const steps = [
    {
      key: 'enable',
      label: t('photobooth.checklist.enable', 'Zugang aktivieren'),
      description: t('photobooth.checklist.enableCopy', 'Aktiviere den FTP-Account für eure Photobooth-Software.'),
      done: Boolean(status?.enabled),
    },
    {
      key: 'share',
      label: t('photobooth.checklist.share', 'Zugang teilen'),
      description: t('photobooth.checklist.shareCopy', 'Übergib Host, Benutzer & Passwort an den Betreiber.'),
      done: Boolean(status?.username && status?.password),
    },
    {
      key: 'monitor',
      label: t('photobooth.checklist.monitor', 'Uploads beobachten'),
      description: t('photobooth.checklist.monitorCopy', 'Verfolge Uploads & Limits direkt im Dashboard.'),
      done: Boolean(status?.status === 'active'),
    },
  ];

  return (
    <Card className="rounded-3xl border border-slate-200/80 bg-white shadow-sm">
      <CardHeader>
        <CardTitle>{t('photobooth.checklist.title', 'Setup-Checkliste')}</CardTitle>
        <CardDescription>{t('photobooth.checklist.description', 'Erledige jeden Schritt, bevor Gäste Zugang erhalten.')}</CardDescription>
      </CardHeader>
      <CardContent className="space-y-3">
        {steps.map((step) => (
          <div key={step.key} className="flex items-start gap-3 rounded-2xl border border-slate-200/70 p-3">
            {step.done ? (
              <CheckCircle2 className="mt-0.5 h-4 w-4 text-emerald-500" />
            ) : (
              <Circle className="mt-0.5 h-4 w-4 text-slate-300" />
            )}
            <div>
              <p className={`text-sm font-semibold ${step.done ? 'text-emerald-700' : 'text-slate-800'}`}>{step.label}</p>
              <p className="text-xs text-slate-500">{step.description}</p>
            </div>
          </div>
        ))}
      </CardContent>
    </Card>
  );
}

function StatusCard({ status }: { status: PhotoboothStatus | null }) {
  const { t } = useTranslation('management');
  const isActive = Boolean(status?.enabled);
  const badgeColor = isActive ? 'bg-emerald-600 text-white' : 'bg-slate-300 text-slate-800';
  const icon = isActive ? <PlugZap className="h-5 w-5 text-emerald-500" /> : <Power className="h-5 w-5 text-slate-400" />;
  const modeLabel = status?.mode === 'sparkbooth' ? 'Sparkbooth / HTTP' : 'FTP';

  return (
    <Card className="rounded-3xl border border-slate-200/80 shadow-sm">
      <CardHeader className="flex flex-row items-center justify-between gap-3">
        <div>
          <CardTitle>{t('photobooth.status.heading', 'Status')}</CardTitle>
          <CardDescription>
            {isActive
              ? t('photobooth.status.active', 'Photobooth-Link ist aktiv.')
              : t('photobooth.status.inactive', 'Noch keine Photobooth-Uploads angebunden.')}
          </CardDescription>
        </div>
        <div className="flex items-center gap-3">
          {icon}
          <Badge className={badgeColor}>
            {isActive ? t('photobooth.status.badgeActive', 'AKTIV') : t('photobooth.status.badgeInactive', 'INAKTIV')}
          </Badge>
        </div>
      </CardHeader>
      <CardContent className="space-y-1 text-sm text-slate-600">
        <p className="text-xs uppercase tracking-wide text-slate-500">
          {t('photobooth.status.mode', 'Modus')}: {modeLabel}
        </p>
        {status?.expires_at ? (
          <p>
            {t('photobooth.status.expiresAt', 'Automatisches Abschalten am {{date}}', {
              date: new Date(status.expires_at).toLocaleString(),
            })}
          </p>
        ) : null}
      </CardContent>
    </Card>
  );
}

type CredentialCardProps = {
  status: PhotoboothStatus | null;
  updating: boolean;
  onEnable: () => Promise<void>;
  onRotate: () => Promise<void>;
  onDisable: () => Promise<void>;
};

function CredentialsCard({ status, updating, onEnable, onRotate, onDisable }: CredentialCardProps) {
  const { t } = useTranslation('management');
  const isActive = Boolean(status?.enabled);
  const isSparkbooth = status?.mode === 'sparkbooth';

  return (
    <Card className="rounded-3xl border border-rose-100/80 shadow-lg shadow-rose-100/40">
      <CardHeader>
        <CardTitle>
          {isSparkbooth ? t('photobooth.credentials.sparkboothTitle', 'Sparkbooth-Upload (HTTP)') : t('photobooth.credentials.heading', 'FTP-Zugangsdaten')}
        </CardTitle>
        <CardDescription>
          {isSparkbooth
            ? t(
              'photobooth.credentials.sparkboothDescription',
              'Trage URL, Benutzername und Passwort in Sparkbooth ein. Antworten erfolgen als JSON (optional XML).'
            )
            : t(
              'photobooth.credentials.description',
              'Teile die Zugangsdaten mit der Photobooth-Software. Passwörter werden max. 8 Zeichen lang generiert.'
            )}
        </CardDescription>
      </CardHeader>
      <CardContent className="space-y-6">
        {isSparkbooth ? (
          <div className="grid gap-4 md:grid-cols-2">
            <Field label={t('photobooth.credentials.username', 'Benutzername')} value={status?.username ?? '—'} copyable />
            <Field label={t('photobooth.credentials.password', 'Passwort')} value={status?.password ?? '—'} copyable sensitive />
            <Field label={t('photobooth.credentials.postUrl', 'Upload-URL')} value={status?.upload_url ?? '—'} copyable className="md:col-span-2" />
            <Field
              label={t('photobooth.credentials.responseFormat', 'Antwort-Format')}
              value={status?.sparkbooth?.response_format === 'xml' ? 'XML' : 'JSON'}
              className="md:col-span-2"
            />
          </div>
        ) : (
          <div className="grid gap-4 md:grid-cols-2">
            <Field label={t('photobooth.credentials.host', 'Host')} value={status?.ftp.host ?? '—'} />
            <Field label={t('photobooth.credentials.port', 'Port')} value={String(status?.ftp.port ?? 2121)} />
            <Field label={t('photobooth.credentials.username', 'Benutzername')} value={status?.username ?? '—'} copyable />
            <Field label={t('photobooth.credentials.password', 'Passwort')} value={status?.password ?? '—'} copyable sensitive />
            <Field label={t('photobooth.credentials.path', 'Upload-Pfad')} value={status?.path ?? '/photobooth/...'} copyable />
            <Field label="FTP-Link" value={status?.ftp_url ?? '—'} copyable className="md:col-span-2" />
          </div>
        )}

        <div className="flex flex-wrap gap-3">
          {isActive ? (
            <>
              <Button onClick={onRotate} disabled={updating} className="bg-rose-600 text-white hover:bg-rose-500">
                {updating ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <RefreshCw className="mr-2 h-4 w-4" />}
                {t('photobooth.actions.rotate', 'Zugang neu generieren')}
              </Button>
              <Button variant="outline" onClick={onDisable} disabled={updating}>
                <Power className="mr-2 h-4 w-4" />
                {t('photobooth.actions.disable', 'Deaktivieren')}
              </Button>
            </>
          ) : (
            <Button onClick={onEnable} disabled={updating} className="bg-rose-600 text-white hover:bg-rose-500">
              {updating ? <Loader2 className="mr-2 h-4 w-4 animate-spin" /> : <PlugZap className="mr-2 h-4 w-4" />}
              {t('photobooth.actions.enable', 'Photobooth aktivieren')}
            </Button>
          )}
        </div>
      </CardContent>
    </Card>
  );
}

function StatusTimelineCard({ status, lastUploadAt }: { status: PhotoboothStatus | null; lastUploadAt?: string | null }) {
  const { t } = useTranslation('management');
  const entries = [
    {
      title: t('photobooth.timeline.activation', 'Freischaltung'),
      body: status?.enabled
        ? t('photobooth.timeline.activationReady', 'Zugang ist aktiv.')
        : t('photobooth.timeline.activationPending', 'Noch nicht aktiviert.'),
    },
    {
      title: t('photobooth.timeline.credentials', 'Zugangsdaten'),
      body: status?.username
        ? t('photobooth.timeline.credentialsReady', { defaultValue: 'Benutzer {{username}} ist bereit.', username: status.username })
        : t('photobooth.timeline.credentialsPending', 'Noch keine Logindaten generiert.'),
    },
    {
      title: t('photobooth.timeline.expiry', 'Ablauf'),
      body: status?.expires_at
        ? t('photobooth.timeline.expiryHint', { defaultValue: 'Automatisches Abschalten am {{date}}', date: formatPhotoboothDate(status.expires_at) })
        : t('photobooth.timeline.noExpiry', 'Noch kein Ablaufdatum gesetzt.'),
    },
    {
      title: t('photobooth.timeline.lastUpload', 'Letzter Upload'),
      body: lastUploadAt
        ? t('photobooth.timeline.lastUploadAt', { defaultValue: 'Zuletzt am {{date}}', date: formatPhotoboothDate(lastUploadAt) })
        : t('photobooth.timeline.lastUploadPending', 'Noch keine Uploads registriert.'),
    },
  ];

  return (
    <Card className="rounded-3xl border border-slate-200/80 bg-white shadow-sm">
      <CardHeader>
        <CardTitle>{t('photobooth.timeline.title', 'Status-Timeline')}</CardTitle>
      </CardHeader>
      <CardContent className="space-y-4">
        {entries.map((entry, index) => (
          <div key={entry.title} className="flex gap-3">
            <div className="flex flex-col items-center">
              <Clock3 className="h-4 w-4 text-slate-400" />
              {index < entries.length - 1 ? <span className="mt-1 h-10 w-px bg-slate-200" /> : null}
            </div>
            <div>
              <p className="text-sm font-semibold text-slate-800">{entry.title}</p>
              <p className="text-xs text-slate-500">{entry.body}</p>
            </div>
          </div>
        ))}
      </CardContent>
    </Card>
  );
}

function RateLimitCard({ status, uploadsLastHour }: { status: PhotoboothStatus | null; uploadsLastHour: number | null }) {
  const { t } = useTranslation('management');
  const rateLimit = status?.rate_limit_per_minute ?? 20;
  const usage = uploadsLastHour != null ? Math.max(0, uploadsLastHour) : null;
  const usageRatio = usage !== null && rateLimit > 0 ? usage / rateLimit : null;
  const showWarning = usageRatio !== null && usageRatio >= 0.8;

  return (
    <Card className="rounded-3xl border border-slate-200/80 bg-white shadow-sm">
      <CardHeader className="flex flex-row items-center gap-3">
        <ShieldCheck className="h-5 w-5 text-emerald-500" />
        <div>
          <CardTitle>{t('photobooth.rateLimit.heading', 'Sicherheit & Limits')}</CardTitle>
          <CardDescription>
            {t('photobooth.rateLimit.description', 'Uploads werden strikt auf {{count}} Fotos pro Minute begrenzt.', {
              count: rateLimit,
            })}
          </CardDescription>
        </div>
      </CardHeader>
      <CardContent className="text-sm leading-relaxed text-slate-600">
        <p>
          {t(
            'photobooth.rateLimit.body',
            'Bei Überschreitung wird die Verbindung hart geblockt. Nach 60 Sekunden wird der Zugang automatisch wieder freigegeben.'
          )}
        </p>
        <div className="mt-4 rounded-2xl border border-slate-200 bg-slate-50/70 p-3">
          <div className="flex items-center justify-between text-xs font-semibold uppercase tracking-wide text-slate-500">
            <span>{t('photobooth.rateLimit.usage', 'Uploads letzte Stunde')}</span>
            <span className="text-slate-900">{usage !== null ? `${usage}/${rateLimit}` : `≤ ${rateLimit}`}</span>
          </div>
          {showWarning ? (
            <p className="mt-2 text-xs text-amber-600">
              {t('photobooth.rateLimit.warning', 'Kurz vor dem Limit – bitte Upload-Takt reduzieren oder Support informieren.')}
            </p>
          ) : null}
        </div>
        <p className="mt-3 text-xs text-slate-500">
          <AlertCircle className="mr-1 inline h-3.5 w-3.5" />
          {t(
            'photobooth.rateLimit.hint',
            'Ablaufzeit stimmt mit dem Event-Ende überein. Nach Ablauf wird der Account automatisch entfernt.'
          )}
        </p>
      </CardContent>
    </Card>
  );
}

type FieldProps = {
  label: string;
  value: string;
  copyable?: boolean;
  sensitive?: boolean;
  className?: string;
};

function Field({ label, value, copyable, sensitive, className }: FieldProps) {
  const [copied, setCopied] = React.useState(false);
  const showValue = sensitive && value && value !== '—' ? '•'.repeat(Math.min(6, value.length)) : value;

  async function handleCopy() {
    if (!copyable || !value || value === '—') return;
    await navigator.clipboard.writeText(value);
    setCopied(true);
    setTimeout(() => setCopied(false), 1500);
  }

  return (
    <div className={`rounded-2xl border border-slate-200/80 bg-white/70 p-4 shadow-inner ${className ?? ''}`}>
      <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">{label}</p>
      <div className="mt-1 flex items-center justify-between gap-2">
        <span className="truncate text-base font-medium text-slate-900">{showValue}</span>
        {copyable ? (
          <Button variant="ghost" size="icon" onClick={handleCopy} aria-label="Copy" disabled={!value || value === '—'}>
            {copied ? <ShieldCheck className="h-4 w-4 text-emerald-500" /> : <Copy className="h-4 w-4 text-slate-500" />}
          </Button>
        ) : null}
      </div>
    </div>
  );
}

function formatPhotoboothDate(iso: string | null): string {
  if (!iso) {
    return '—';
  }
  const date = new Date(iso);
  if (Number.isNaN(date.getTime())) {
    return '—';
  }
  return date.toLocaleString(undefined, {
    day: '2-digit',
    month: '2-digit',
    year: 'numeric',
    hour: '2-digit',
    minute: '2-digit',
  });
}

function countUploadsInWindow(photos: TenantPhoto[], windowMs: number): number {
  if (!photos.length) {
    return 0;
  }
  const now = Date.now();
  return photos.reduce((total, photo) => {
    if (!photo.uploaded_at) {
      return total;
    }
    const timestamp = Date.parse(photo.uploaded_at);
    if (Number.isNaN(timestamp)) {
      return total;
    }
    return now - timestamp <= windowMs ? total + 1 : total;
  }, 0);
}

function selectLatestUpload(photos: TenantPhoto[]): TenantPhoto | null {
  let latest: TenantPhoto | null = null;
  let bestTime = -Infinity;
  photos.forEach((photo) => {
    if (!photo.uploaded_at) {
      return;
    }
    const timestamp = Date.parse(photo.uploaded_at);
    if (!Number.isNaN(timestamp) && timestamp > bestTime) {
      latest = photo;
      bestTime = timestamp;
    }
  });
  return latest;
}
