import React from 'react';
import { TabComponent, TabItemDirective, TabItemsDirective } from '@syncfusion/ej2-react-navigations';
import { NumericTextBoxComponent, TextBoxComponent } from '@syncfusion/ej2-react-inputs';
import { ButtonComponent, CheckBoxComponent } from '@syncfusion/ej2-react-buttons';
import { ToastComponent, MessageComponent } from '@syncfusion/ej2-react-notifications';
import { DialogComponent } from '@syncfusion/ej2-react-popups';
import { listHolidays, uploadHolidaysCsv, createHoliday, updateHoliday, deleteHoliday, type Holiday } from './apiHolidays';
import { getSupplementTableSettings, updateSupplementTableSettings, getHolidayBannerSetting, updateHolidayBannerSetting } from './apiSystemSettings';
import { useAuth } from './useAuth';
import { DropDownListComponent } from '@syncfusion/ej2-react-dropdowns';
import { 
  listAcademicPeriods, 
  setActiveAcademicPeriod,
  createAcademicPeriod,
  updateAcademicPeriod,
  archiveAcademicPeriod,
  restoreAcademicPeriod,
  deleteAcademicPeriod,
  getAcademicPeriodUsage,
  type AcademicPeriod,
  type PeriodUsage
} from './apiAcademicPeriods';
import { formatIsoDateForDisplay } from './dateFormatting';
import { Link } from 'react-router-dom';

// Minimal event type for Syncfusion Tab 'selected' callback
type TabSelectedEvent = { selectedIndex?: number };

const Einstellungen: React.FC = () => {
  // Presentation settings state
  const [presentationInterval, setPresentationInterval] = React.useState(10);
  const [presentationPageProgress, setPresentationPageProgress] = React.useState(true);
  const [presentationAutoProgress, setPresentationAutoProgress] = React.useState(true);
  const [presentationBusy, setPresentationBusy] = React.useState(false);

  // Load settings from backend
  const loadPresentationSettings = React.useCallback(async () => {
    try {
      const keys = [
        'presentation_interval',
        'presentation_page_progress',
        'presentation_auto_progress',
      ];
      const results = await Promise.all(keys.map(k => import('./apiSystemSettings').then(m => m.getSetting(k))));
      setPresentationInterval(Number(results[0].value) || 10);
      setPresentationPageProgress(results[1].value === 'true');
      setPresentationAutoProgress(results[2].value === 'true');
    } catch {
      showToast('Fehler beim Laden der Präsentations-Einstellungen', 'e-toast-danger');
    }
  }, []);

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

  const onSavePresentationSettings = async () => {
    setPresentationBusy(true);
    try {
      const api = await import('./apiSystemSettings');
      await Promise.all([
        api.updateSetting('presentation_interval', String(presentationInterval)),
        api.updateSetting('presentation_page_progress', presentationPageProgress ? 'true' : 'false'),
        api.updateSetting('presentation_auto_progress', presentationAutoProgress ? 'true' : 'false'),
      ]);
      showToast('Präsentations-Einstellungen gespeichert', 'e-toast-success');
    } catch {
      showToast('Fehler beim Speichern der Präsentations-Einstellungen', 'e-toast-danger');
    } finally {
      setPresentationBusy(false);
    }
  };
  const { user } = useAuth();
  const toastRef = React.useRef<ToastComponent>(null);
  const holidayUploadInputRef = React.useRef<HTMLInputElement | null>(null);

  // Holidays state
  const [file, setFile] = React.useState<File | null>(null);
  const [busy, setBusy] = React.useState(false);
  const [message, setMessage] = React.useState<string | null>(null);
  const [messageType, setMessageType] = React.useState<'Success' | 'Warning' | 'Error'>('Success');
  const [importConflictMessages, setImportConflictMessages] = React.useState<string[]>([]);
  const [holidays, setHolidays] = React.useState<Holiday[]>([]);
  const [periods, setPeriods] = React.useState<AcademicPeriod[]>([]);
  const [selectedHolidayPeriodId, setSelectedHolidayPeriodId] = React.useState<number | null>(null);

  // Holiday CRUD state
  const [showHolidayFormDialog, setShowHolidayFormDialog] = React.useState(false);
  const [holidayDialogMode, setHolidayDialogMode] = React.useState<'create' | 'edit'>('create');
  const [editingHoliday, setEditingHoliday] = React.useState<Holiday | null>(null);
  const [holidayForm, setHolidayForm] = React.useState({ name: '', start_date: '', end_date: '', region: '' });
  const [holidayFormBusy, setHolidayFormBusy] = React.useState(false);
  const [showDeleteHolidayDialog, setShowDeleteHolidayDialog] = React.useState(false);
  const [deletingHoliday, setDeletingHoliday] = React.useState<Holiday | null>(null);
  const [deleteHolidayBusy, setDeleteHolidayBusy] = React.useState(false);

  // Supplement table state
  const [supplementUrl, setSupplementUrl] = React.useState('');
  const [supplementEnabled, setSupplementEnabled] = React.useState(false);
  const [supplementBusy, setSupplementBusy] = React.useState(false);

  // Holiday banner state
  const [holidayBannerEnabled, setHolidayBannerEnabled] = React.useState(true);
  const [holidayBannerBusy, setHolidayBannerBusy] = React.useState(false);

  // Video defaults state (Admin+)
  const [videoAutoplay, setVideoAutoplay] = React.useState<boolean>(true);
  const [videoLoop, setVideoLoop] = React.useState<boolean>(true);
  const [videoVolume, setVideoVolume] = React.useState<number>(0.8);
  const [videoMuted, setVideoMuted] = React.useState<boolean>(false);
  const [videoBusy, setVideoBusy] = React.useState<boolean>(false);

  // Organization name state (Superadmin only)
  const [organizationName, setOrganizationName] = React.useState<string>('');
  const [organizationBusy, setOrganizationBusy] = React.useState<boolean>(false);

  // Advanced options: Scheduler refresh interval (Superadmin)
  const [refreshSeconds, setRefreshSeconds] = React.useState<number>(0);
  const [refreshBusy, setRefreshBusy] = React.useState<boolean>(false);

  // Academic Periods Management State
  const [showCreatePeriodDialog, setShowCreatePeriodDialog] = React.useState(false);
  const [showEditPeriodDialog, setShowEditPeriodDialog] = React.useState(false);
  const [showArchiveDialog, setShowArchiveDialog] = React.useState(false);
  const [showRestoreDialog, setShowRestoreDialog] = React.useState(false);
  const [showDeleteDialog, setShowDeleteDialog] = React.useState(false);
  const [showArchiveBlockedDialog, setShowArchiveBlockedDialog] = React.useState(false);
  const [showDeleteBlockedDialog, setShowDeleteBlockedDialog] = React.useState(false);
  const [periodFormData, setPeriodFormData] = React.useState({
    name: '',
    displayName: '',
    startDate: '',
    endDate: '',
    periodType: 'schuljahr' as 'schuljahr' | 'semester' | 'trimester',
  });
  const [selectedPeriodId, setSelectedPeriodId] = React.useState<number | null>(null);
  const [periodUsage, setPeriodUsage] = React.useState<PeriodUsage | null>(null);
  const [periodBusy, setPeriodBusy] = React.useState(false);
  const [showArchivedOnly, setShowArchivedOnly] = React.useState(false);

  const displayedPeriods = showArchivedOnly 
    ? periods.filter(p => p.isArchived)
    : periods.filter(p => !p.isArchived);
  const selectableHolidayPeriods = React.useMemo(
    () => periods.filter(period => !period.isArchived),
    [periods]
  );
  const holidayPeriodOptions = React.useMemo(
    () => selectableHolidayPeriods.map(period => ({
      text: period.displayName || period.name,
      value: period.id,
    })),
    [selectableHolidayPeriods]
  );
  const selectedHolidayPeriod = React.useMemo(
    () => selectableHolidayPeriods.find(period => period.id === selectedHolidayPeriodId) ?? null,
    [selectableHolidayPeriods, selectedHolidayPeriodId]
  );

  const handleEditPeriod = (period: AcademicPeriod) => {
    setSelectedPeriodId(period.id);
    setPeriodFormData({
      name: period.name,
      displayName: period.displayName || '',
      startDate: period.startDate,
      endDate: period.endDate,
      periodType: period.periodType,
    });
    setShowEditPeriodDialog(true);
  };

  const handleSavePeriod = async () => {
    if (!periodFormData.name.trim()) {
      showToast('Name ist erforderlich', 'e-toast-danger');
      return;
    }
    if (!periodFormData.startDate || !periodFormData.endDate) {
      showToast('Start- und Enddatum sind erforderlich', 'e-toast-danger');
      return;
    }
    if (periodFormData.startDate > periodFormData.endDate) {
      showToast('Startdatum muss vor Enddatum liegen', 'e-toast-danger');
      return; 
    }

    setPeriodBusy(true);
    try {
      if (selectedPeriodId) {
        // Update
        await updateAcademicPeriod(selectedPeriodId, {
          name: periodFormData.name.trim(),
          displayName: periodFormData.displayName.trim() || null,
          startDate: periodFormData.startDate,
          endDate: periodFormData.endDate,
          periodType: periodFormData.periodType,
        });
        showToast('Periode aktualisiert', 'e-toast-success');
      } else {
        // Create
        await createAcademicPeriod({
          name: periodFormData.name.trim(),
          displayName: periodFormData.displayName.trim() || undefined,
          startDate: periodFormData.startDate,
          endDate: periodFormData.endDate,
          periodType: periodFormData.periodType,
        });
        showToast('Periode erstellt', 'e-toast-success');
      }
      setShowCreatePeriodDialog(false);
      setShowEditPeriodDialog(false);
      setPeriodFormData({
        name: '',
        displayName: '',
        startDate: '',
        endDate: '',
        periodType: 'schuljahr',
      });
      setSelectedPeriodId(null);
      await loadAcademicPeriods();
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const handleArchivePeriod = async () => {
    if (!selectedPeriodId) return;
    setPeriodBusy(true);
    try {
      await archiveAcademicPeriod(selectedPeriodId);
      showToast('Periode archiviert', 'e-toast-success');
      setShowArchiveDialog(false);
      setSelectedPeriodId(null);
      await loadAcademicPeriods();
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Archivieren';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const handleRestorePeriod = async () => {
    if (!selectedPeriodId) return;
    setPeriodBusy(true);
    try {
      await restoreAcademicPeriod(selectedPeriodId);
      showToast('Periode wiederhergestellt', 'e-toast-success');
      setShowRestoreDialog(false);
      setSelectedPeriodId(null);
      await loadAcademicPeriods();
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Wiederherstellen';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const handleDeletePeriod = async () => {
    if (!selectedPeriodId) return;
    setPeriodBusy(true);
    try {
      await deleteAcademicPeriod(selectedPeriodId);
      showToast('Periode gelöscht', 'e-toast-success');
      setShowDeleteDialog(false);
      setSelectedPeriodId(null);
      await loadAcademicPeriods();
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Löschen';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const openArchiveDialog = async (periodId: number) => {
    setSelectedPeriodId(periodId);
    setPeriodBusy(true);
    try {
      const usage = await getAcademicPeriodUsage(periodId);
      setPeriodUsage(usage);
      if (usage.blockers.length > 0) {
        setShowArchiveBlockedDialog(true);
      } else {
        setShowArchiveDialog(true);
      }
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Nutzungsdaten';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const openDeleteDialog = async (periodId: number) => {
    setSelectedPeriodId(periodId);
    setPeriodBusy(true);
    try {
      const usage = await getAcademicPeriodUsage(periodId);
      setPeriodUsage(usage);
      if (usage.blockers.length > 0) {
        setShowDeleteBlockedDialog(true);
      } else {
        setShowDeleteDialog(true);
      }
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Nutzungsdaten';
      showToast(msg, 'e-toast-danger');
    } finally {
      setPeriodBusy(false);
    }
  };

  const showToast = (content: string, cssClass: string = 'e-toast-success') => {
    if (toastRef.current) {
      toastRef.current.show({
        content,
        cssClass,
        timeOut: 3000,
      });
    }
  };

  const refresh = React.useCallback(async () => {
    if (selectedHolidayPeriodId == null) {
      setHolidays([]);
      return;
    }

    try {
      const data = await listHolidays(undefined, selectedHolidayPeriodId);
      setHolidays(data.holidays);
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Ferien';
      setMessage(msg);
      showToast(msg, 'e-toast-danger');
    }
  }, [selectedHolidayPeriodId]);

  const loadSupplementSettings = React.useCallback(async () => {
    try {
      const data = await getSupplementTableSettings();
      setSupplementUrl(data.url || '');
      setSupplementEnabled(data.enabled || false);
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Vertretungsplan-Einstellungen';
      showToast(msg, 'e-toast-danger');
    }
  }, []);

  const loadHolidayBannerSetting = React.useCallback(async () => {
    try {
      const data = await getHolidayBannerSetting();
      setHolidayBannerEnabled(data.enabled);
    } catch (e) {
      console.error('Fehler beim Laden der Ferienbanner-Einstellung:', e);
    }
  }, []);

  // Load video default settings (with fallbacks)
  const loadVideoSettings = React.useCallback(async () => {
    try {
      const api = await import('./apiSystemSettings');
      const keys = ['video_autoplay', 'video_loop', 'video_volume', 'video_muted'] as const;
      const [autoplay, loop, volume, muted] = await Promise.all(
        keys.map(k => api.getSetting(k).catch(() => ({ value: null } as { value: string | null })))
      );
      setVideoAutoplay(autoplay.value == null ? true : autoplay.value === 'true');
      setVideoLoop(loop.value == null ? true : loop.value === 'true');
      const volParsed = volume.value == null ? 0.8 : parseFloat(String(volume.value));
      setVideoVolume(Number.isFinite(volParsed) ? volParsed : 0.8);
      setVideoMuted(muted.value == null ? false : muted.value === 'true');
    } catch (e) {
      // Fallback to defaults on any error
      setVideoAutoplay(true);
      setVideoLoop(true);
      setVideoVolume(0.8);
      setVideoMuted(false);
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Video-Standards';
      showToast(msg, 'e-toast-warning');
    }
  }, []);

  // Load organization name (superadmin only, but endpoint is public)
  const loadOrganizationName = React.useCallback(async () => {
    try {
      const api = await import('./apiSystemSettings');
      const data = await api.getOrganizationName();
      setOrganizationName(data.name || '');
    } catch (e) {
      console.error('Fehler beim Laden des Organisationsnamens:', e);
    }
  }, []);

  // Load scheduler refresh seconds (superadmin)
  const loadRefreshSeconds = React.useCallback(async () => {
    try {
      const api = await import('./apiSystemSettings');
      const setting = await api.getSetting('refresh_seconds');
      const parsed = Number(setting.value ?? 0);
      setRefreshSeconds(Number.isFinite(parsed) ? parsed : 0);
    } catch {
      // Default to 0 if not present
      setRefreshSeconds(0);
    }
  }, []);

  const loadAcademicPeriods = React.useCallback(async () => {
    try {
      const list = await listAcademicPeriods({ includeArchived: true });
      setPeriods(list);
      setSelectedHolidayPeriodId(prevSelectedPeriodId => {
        if (prevSelectedPeriodId && list.some(period => period.id === prevSelectedPeriodId && !period.isArchived)) {
          return prevSelectedPeriodId;
        }
        const activePeriod = list.find(period => period.isActive && !period.isArchived);
        const firstSelectablePeriod = list.find(period => !period.isArchived);
        return activePeriod?.id ?? firstSelectablePeriod?.id ?? null;
      });
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Laden der Schuljahre/Perioden';
      showToast(msg, 'e-toast-danger');
    }
  }, []);

  React.useEffect(() => {
    loadHolidayBannerSetting(); // Everyone can see this
    if (user) {
      // Academic periods for all users
      loadAcademicPeriods();
      // System settings only for admin/superadmin (will render only if allowed)
      if (['admin', 'superadmin'].includes(user.role)) {
        loadSupplementSettings();
        loadPresentationSettings();
        loadVideoSettings();
      }
      // Organization name only for superadmin
      if (user.role === 'superadmin') {
        loadOrganizationName();
        loadRefreshSeconds();
      }
    }
  }, [loadSupplementSettings, loadAcademicPeriods, loadPresentationSettings, loadVideoSettings, loadHolidayBannerSetting, loadOrganizationName, loadRefreshSeconds, user]);

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

  const onUpload = async () => {
    if (!file || selectedHolidayPeriodId == null) return;
    setBusy(true);
    setMessage(null);
    setImportConflictMessages([]);
    try {
      const res = await uploadHolidaysCsv(file, selectedHolidayPeriodId);
      const merged = res.merged_overlaps || 0;
      const skipped = res.skipped_duplicates || 0;
      const conflicts = res.conflicts || [];
      const parts = [
        `${res.inserted} neu`,
        `${res.updated} aktualisiert`,
      ];
      if (merged > 0) {
        parts.push(`${merged} Überschneidungen zusammengeführt`);
      }
      if (skipped > 0) {
        parts.push(`${skipped} Duplikate übersprungen`);
      }
      if (conflicts.length > 0) {
        parts.push(`${conflicts.length} Konflikte nicht importiert`);
      }
      const msg = `Import abgeschlossen: ${parts.join(', ')}.`;
      setMessage(msg);
      setMessageType(conflicts.length > 0 ? 'Warning' : 'Success');
      setImportConflictMessages(conflicts);
      showToast(msg, conflicts.length > 0 ? 'e-toast-warning' : 'e-toast-success');
      setFile(null);
      if (holidayUploadInputRef.current) {
        holidayUploadInputRef.current.value = '';
      }
      await refresh();
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Import.';
      setMessage(msg);
      setMessageType('Error');
      setImportConflictMessages([]);
      showToast(msg, 'e-toast-danger');
    } finally {
      setBusy(false);
    }
  };

  const onOpenCreateHoliday = () => {
    setHolidayForm({ name: '', start_date: '', end_date: '', region: '' });
    setEditingHoliday(null);
    setHolidayDialogMode('create');
    setShowHolidayFormDialog(true);
  };

  const onOpenEditHoliday = (holiday: Holiday) => {
    setHolidayForm({
      name: holiday.name,
      start_date: holiday.start_date,
      end_date: holiday.end_date,
      region: holiday.region || '',
    });
    setEditingHoliday(holiday);
    setHolidayDialogMode('edit');
    setShowHolidayFormDialog(true);
  };

  const onSaveHoliday = async () => {
    if (selectedHolidayPeriodId == null || !selectedHolidayPeriod) {
      showToast('Bitte wählen Sie zuerst eine akademische Periode aus', 'e-toast-warning');
      return;
    }
    if (!holidayForm.name.trim() || !holidayForm.start_date || !holidayForm.end_date) {
      showToast('Bitte füllen Sie Name, Startdatum und Enddatum aus', 'e-toast-warning');
      return;
    }
    if (holidayForm.end_date < holidayForm.start_date) {
      showToast('Enddatum muss nach oder gleich Startdatum sein', 'e-toast-warning');
      return;
    }
    if (
      holidayForm.start_date < selectedHolidayPeriod.startDate ||
      holidayForm.end_date > selectedHolidayPeriod.endDate
    ) {
      showToast(
        `Die Ferien müssen innerhalb der Periode ${selectedHolidayPeriod.displayName || selectedHolidayPeriod.name} liegen (${formatIsoDateForDisplay(selectedHolidayPeriod.startDate)} bis ${formatIsoDateForDisplay(selectedHolidayPeriod.endDate)})`,
        'e-toast-warning',
      );
      return;
    }
    setHolidayFormBusy(true);
    try {
      const payload = {
        name: holidayForm.name,
        start_date: holidayForm.start_date,
        end_date: holidayForm.end_date,
        region: holidayForm.region || null,
        academic_period_id: selectedHolidayPeriodId,
      };
      const result = holidayDialogMode === 'edit' && editingHoliday
        ? await updateHoliday(editingHoliday.id, payload)
        : await createHoliday(payload);
      const verb = holidayDialogMode === 'edit' ? 'aktualisiert' : 'erstellt';
      const regen = result.regenerated_events;
      const mergedText = result.merged ? ' und mit bestehendem Ferienblock zusammengeführt' : '';
      showToast(
        `Ferien ${verb}${mergedText}${regen > 0 ? ` – ${regen} Termin${regen !== 1 ? 'e' : ''} aktualisiert` : ''}`,
        'e-toast-success',
      );
      setShowHolidayFormDialog(false);
      await refresh();
    } catch (e) {
      showToast(e instanceof Error ? e.message : 'Fehler beim Speichern', 'e-toast-danger');
    } finally {
      setHolidayFormBusy(false);
    }
  };

  const onConfirmDeleteHoliday = async () => {
    if (!deletingHoliday) return;
    setDeleteHolidayBusy(true);
    try {
      const result = await deleteHoliday(deletingHoliday.id);
      const regen = result.regenerated_events;
      showToast(
        `Ferien gelöscht${regen > 0 ? ` – ${regen} Termin${regen !== 1 ? 'e' : ''} aktualisiert` : ''}`,
        'e-toast-success',
      );
      setShowDeleteHolidayDialog(false);
      setDeletingHoliday(null);
      await refresh();
    } catch (e) {
      showToast(e instanceof Error ? e.message : 'Fehler beim Löschen', 'e-toast-danger');
    } finally {
      setDeleteHolidayBusy(false);
    }
  };

  const onSaveSupplementSettings = async () => {
    setSupplementBusy(true);
    try {
      await updateSupplementTableSettings(supplementUrl, supplementEnabled);
      showToast('Vertretungsplan-Einstellungen erfolgreich gespeichert', 'e-toast-success');
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern der Einstellungen';
      showToast(msg, 'e-toast-danger');
    } finally {
      setSupplementBusy(false);
    }
  };

  const onTestSupplementUrl = () => {
    if (supplementUrl) {
      window.open(supplementUrl, '_blank');
    } else {
      showToast('Bitte geben Sie zuerst eine URL ein', 'e-toast-warning');
    }
  };

  const onSaveHolidayBannerSetting = async () => {
    setHolidayBannerBusy(true);
    try {
      await updateHolidayBannerSetting(holidayBannerEnabled);
      showToast('Ferienbanner-Einstellung gespeichert', 'e-toast-success');
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern';
      showToast(msg, 'e-toast-danger');
    } finally {
      setHolidayBannerBusy(false);
    }
  };

  const onSaveVideoSettings = async () => {
    setVideoBusy(true);
    try {
      const api = await import('./apiSystemSettings');
      await Promise.all([
        api.updateSetting('video_autoplay', videoAutoplay ? 'true' : 'false'),
        api.updateSetting('video_loop', videoLoop ? 'true' : 'false'),
        api.updateSetting('video_volume', String(videoVolume)),
        api.updateSetting('video_muted', videoMuted ? 'true' : 'false'),
      ]);
      showToast('Video-Standardeinstellungen gespeichert', 'e-toast-success');
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern der Video-Standards';
      showToast(msg, 'e-toast-danger');
    } finally {
      setVideoBusy(false);
    }
  };

  const onSaveOrganizationName = async () => {
    setOrganizationBusy(true);
    try {
      const api = await import('./apiSystemSettings');
      await api.updateOrganizationName(organizationName);
      showToast('Organisationsname gespeichert', 'e-toast-success');
      // Trigger a custom event to notify App.tsx to refresh the header
      window.dispatchEvent(new Event('organizationNameUpdated'));
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern des Organisationsnamens';
      showToast(msg, 'e-toast-danger');
    } finally {
      setOrganizationBusy(false);
    }
  };

  const onSaveRefreshSeconds = async () => {
    setRefreshBusy(true);
    try {
      const api = await import('./apiSystemSettings');
      await api.updateSetting('refresh_seconds', String(refreshSeconds));
      showToast('Scheduler-Refresh-Intervall gespeichert', 'e-toast-success');
    } catch (e) {
      const msg = e instanceof Error ? e.message : 'Fehler beim Speichern des Intervalls';
      showToast(msg, 'e-toast-danger');
    } finally {
      setRefreshBusy(false);
    }
  };

  // Determine which tabs to show based on role
  const isAdmin = !!(user && ['admin', 'superadmin'].includes(user.role));
  const isSuperadmin = !!(user && user.role === 'superadmin');

  // Preserve selected nested-tab indices to avoid resets on parent re-render
  const [academicTabIndex, setAcademicTabIndex] = React.useState(0);
  const [displayTabIndex, setDisplayTabIndex] = React.useState(0);
  const [mediaTabIndex, setMediaTabIndex] = React.useState(0);
  const [eventsTabIndex, setEventsTabIndex] = React.useState(0);
  const [usersTabIndex, setUsersTabIndex] = React.useState(0);
  const [systemTabIndex, setSystemTabIndex] = React.useState(0);

  // ---------- Leaf content functions (second-level tabs) ----------
  // Academic Calendar
  // (Old separate Import/List tab contents removed in favor of combined tab)

  // Combined Import + List tab content
  const HolidaysImportAndListContent = () => {
    const firstHolidayStart = holidays.length > 0 ? holidays[0].start_date : null;
    const lastHolidayEnd = holidays.reduce<string | null>((latest, holiday) => {
      if (!latest || holiday.end_date > latest) {
        return holiday.end_date;
      }
      return latest;
    }, null);

    return (
      <div style={{ padding: 20 }}>
        <div className="e-card" style={{ marginBottom: 20 }}>
          <div className="e-card-header">
            <div className="e-card-header-caption">
              <div className="e-card-header-title">Akademische Periode auswählen</div>
            </div>
          </div>
          <div className="e-card-content">
            <div style={{ maxWidth: 420, marginBottom: 12 }}>
              <DropDownListComponent
                dataSource={holidayPeriodOptions}
                fields={{ text: 'text', value: 'value' }}
                value={selectedHolidayPeriodId ?? undefined}
                placeholder="Periode für Import und Anzeige wählen"
                change={(e: { value: number | string }) => {
                  const nextValue = typeof e.value === 'number' ? e.value : Number(e.value);
                  setSelectedHolidayPeriodId(Number.isFinite(nextValue) ? nextValue : null);
                  setMessage(null);
                  setImportConflictMessages([]);
                }}
                width="100%"
              />
            </div>
            {selectedHolidayPeriod ? (
              <div style={{ fontSize: '14px', color: '#555', lineHeight: 1.6 }}>
                <div><strong>Zeitraum:</strong> {formatIsoDateForDisplay(selectedHolidayPeriod.startDate)} bis {formatIsoDateForDisplay(selectedHolidayPeriod.endDate)}</div>
                <div><strong>Typ:</strong> {selectedHolidayPeriod.periodType}</div>
                <div><strong>Importierte Ferienzeiträume:</strong> {holidays.length}</div>
                {firstHolidayStart && lastHolidayEnd && (
                  <div><strong>Abgedeckter Ferienbereich:</strong> {formatIsoDateForDisplay(firstHolidayStart)} bis {formatIsoDateForDisplay(lastHolidayEnd)}</div>
                )}
              </div>
            ) : (
              <div style={{ fontSize: '14px', color: '#666' }}>
                Keine aktive oder auswählbare Periode vorhanden.
              </div>
            )}
          </div>
        </div>

        <div className="e-card" style={{ marginBottom: 20 }}>
          <div className="e-card-header">
            <div className="e-card-header-caption">
              <div className="e-card-header-title">Feriendatei importieren</div>
            </div>
          </div>
          <div className="e-card-content">
            <p style={{ marginBottom: 12, fontSize: '14px', color: '#666' }}>
              {selectedHolidayPeriod
                ? <>Der Import wird der Periode <strong>{selectedHolidayPeriod.displayName || selectedHolidayPeriod.name}</strong> zugeordnet.</>
                : 'Wählen Sie zuerst eine akademische Periode aus.'}
            </p>
            <p style={{ marginBottom: 12, fontSize: '14px', color: '#666' }}>
              Unterstützte Formate:
              <br />• CSV mit Kopfzeile: <code>name</code>, <code>start_date</code>, <code>end_date</code>, optional <code>region</code>
              <br />• TXT/CSV ohne Kopfzeile mit Spalten: interner Name, <strong>Name</strong>, <strong>Start (YYYYMMDD)</strong>, <strong>Ende (YYYYMMDD)</strong>, optional interne Info (ignoriert)
            </p>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12, flexWrap: 'wrap' }}>
              <input
                ref={holidayUploadInputRef}
                type="file"
                accept=".csv,text/csv,.txt,text/plain"
                style={{ display: 'none' }}
                onChange={e => setFile(e.target.files?.[0] ?? null)}
              />
              <ButtonComponent
                cssClass="e-outline"
                onClick={() => holidayUploadInputRef.current?.click()}
                disabled={busy}
              >
                Datei auswählen
              </ButtonComponent>
              <div style={{ fontSize: '14px', color: '#6c757d' }}>
                {file ? file.name : 'Keine Datei ausgewählt'}
              </div>
              <ButtonComponent cssClass="e-primary" onClick={onUpload} disabled={!file || busy || selectedHolidayPeriodId == null}>
                {busy ? 'Importiere…' : 'CSV/TXT importieren'}
              </ButtonComponent>
            </div>
            {message && <div style={{ marginTop: 8 }}><MessageComponent severity={messageType} content={message} /></div>}
            {importConflictMessages.length > 0 && (
              <div style={{ marginTop: 12 }}>
                <MessageComponent severity="Warning" content="Nicht importierte Konflikte:" />
                <ul style={{ margin: '8px 0 0 20px', color: '#666', fontSize: '14px' }}>
                  {importConflictMessages.map((conflict, index) => (
                    <li key={`${index}-${conflict}`}>{conflict}</li>
                  ))}
                </ul>
              </div>
            )}
          </div>
        </div>

        <div className="e-card">
          <div className="e-card-header" style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div className="e-card-header-caption">
              <div className="e-card-header-title">
                {selectedHolidayPeriod
                  ? `Ferien für ${selectedHolidayPeriod.displayName || selectedHolidayPeriod.name}`
                  : 'Ferien'}
              </div>
            </div>
            <ButtonComponent
              cssClass="e-success"
              iconCss="e-icons e-plus"
              onClick={onOpenCreateHoliday}
              disabled={selectedHolidayPeriodId == null}
            >
              Ferien hinzufügen
            </ButtonComponent>
          </div>
          <div className="e-card-content">
            {selectedHolidayPeriodId == null ? (
              <div style={{ fontSize: '14px', color: '#666' }}>Wählen Sie eine Periode, um Ferien anzuzeigen.</div>
            ) : holidays.length === 0 ? (
              <div style={{ fontSize: '14px', color: '#666' }}>Für diese Periode sind noch keine Ferien vorhanden.</div>
            ) : (
              <div>
                {holidays.map(h => (
                  <div key={h.id} style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '6px 0', borderBottom: '1px solid #f0f0f0' }}>
                    <div style={{ fontSize: '14px' }}>
                      <strong>{h.name}</strong>: {formatIsoDateForDisplay(h.start_date)} – {formatIsoDateForDisplay(h.end_date)}
                      {h.region ? <span style={{ color: '#6c757d', marginLeft: 8 }}>({h.region})</span> : null}
                    </div>
                    <div style={{ display: 'flex', gap: 4, flexShrink: 0 }}>
                      <ButtonComponent cssClass="e-flat e-primary" onClick={() => onOpenEditHoliday(h)}>Bearbeiten</ButtonComponent>
                      <ButtonComponent cssClass="e-flat e-danger" onClick={() => { setDeletingHoliday(h); setShowDeleteHolidayDialog(true); }}>Löschen</ButtonComponent>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        </div>

        <div className="e-card" style={{ marginTop: 20 }}>
          <div className="e-card-header">
            <div className="e-card-header-caption">
              <div className="e-card-header-title">Dashboard-Anzeige</div>
            </div>
          </div>
          <div className="e-card-content">
            <div style={{ marginBottom: 16 }}>
              <CheckBoxComponent
                label="Ferienstatus-Banner auf Dashboard anzeigen"
                checked={holidayBannerEnabled}
                change={(e) => setHolidayBannerEnabled(e.checked || false)}
              />
              <div style={{ fontSize: '12px', color: '#666', marginTop: 4, marginLeft: 24 }}>
                Zeigt eine Information an, ob ein Ferienplan für die aktive Periode importiert wurde.
              </div>
            </div>
            <ButtonComponent
              cssClass="e-primary"
              onClick={onSaveHolidayBannerSetting}
              disabled={holidayBannerBusy}
            >
              {holidayBannerBusy ? 'Speichere…' : 'Einstellung speichern'}
            </ButtonComponent>
          </div>
        </div>

        {/* Holiday Create/Edit Dialog */}
        <DialogComponent
          header={holidayDialogMode === 'edit' ? 'Ferien bearbeiten' : 'Ferien hinzufügen'}
          visible={showHolidayFormDialog}
          isModal={true}
          showCloseIcon={true}
          close={() => setShowHolidayFormDialog(false)}
          width="500px"
          buttons={[
            { buttonModel: { content: 'Abbrechen', cssClass: 'e-flat' }, click: () => setShowHolidayFormDialog(false) },
            { buttonModel: { content: holidayFormBusy ? 'Speichere…' : 'Speichern', isPrimary: true, disabled: holidayFormBusy }, click: onSaveHoliday },
          ]}
        >
          <div style={{ padding: 16 }}>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>Name *</label>
              <TextBoxComponent
                value={holidayForm.name}
                change={(e) => setHolidayForm(f => ({ ...f, name: e.value || '' }))}
                placeholder="z.B. Weihnachtsferien"
                cssClass="e-outline"
                enabled={!holidayFormBusy}
              />
            </div>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>Startdatum *</label>
              <TextBoxComponent
                value={holidayForm.start_date}
                change={(e) => {
                  const nextStart = e.value || '';
                  setHolidayForm(f => {
                    const nextEnd = f.end_date && nextStart && f.end_date < nextStart ? nextStart : f.end_date;
                    return { ...f, start_date: nextStart, end_date: nextEnd };
                  });
                }}
                focus={() => {
                  setHolidayForm(f => {
                    if (!f.start_date && f.end_date) {
                      return { ...f, start_date: f.end_date };
                    }
                    return f;
                  });
                }}
                type="date"
                cssClass="e-outline"
                htmlAttributes={{ max: holidayForm.end_date || '' }}
                enabled={!holidayFormBusy}
              />
            </div>
            <div style={{ marginBottom: 16 }}>
              <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>Enddatum *</label>
              <TextBoxComponent
                value={holidayForm.end_date}
                change={(e) => {
                  const nextEnd = e.value || '';
                  setHolidayForm(f => ({
                    ...f,
                    end_date: f.start_date && nextEnd && nextEnd < f.start_date ? f.start_date : nextEnd,
                  }));
                }}
                focus={() => {
                  setHolidayForm(f => {
                    if (!f.end_date && f.start_date) {
                      return { ...f, end_date: f.start_date };
                    }
                    return f;
                  });
                }}
                type="date"
                cssClass="e-outline"
                htmlAttributes={{ min: holidayForm.start_date || '' }}
                enabled={!holidayFormBusy}
              />
            </div>
            <div>
              <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>Region (optional)</label>
              <TextBoxComponent
                value={holidayForm.region}
                change={(e) => setHolidayForm(f => ({ ...f, region: e.value || '' }))}
                placeholder="z.B. Österreich"
                cssClass="e-outline"
                enabled={!holidayFormBusy}
              />
              <div style={{ fontSize: '12px', color: '#666', marginTop: 4 }}>
                Region wird für die Filterung der Ferien verwendet.
              </div>
            </div>
          </div>
        </DialogComponent>

        {/* Holiday Delete Confirm Dialog */}
        <DialogComponent
          header="Ferien löschen?"
          visible={showDeleteHolidayDialog}
          isModal={true}
          showCloseIcon={true}
          close={() => { setShowDeleteHolidayDialog(false); setDeletingHoliday(null); }}
          width="460px"
          buttons={[
            { buttonModel: { content: 'Abbrechen', cssClass: 'e-flat' }, click: () => { setShowDeleteHolidayDialog(false); setDeletingHoliday(null); } },
            { buttonModel: { content: deleteHolidayBusy ? 'Lösche…' : 'Löschen', cssClass: 'e-flat e-danger', disabled: deleteHolidayBusy }, click: onConfirmDeleteHoliday },
          ]}
        >
          <div style={{ padding: 16 }}>
            <MessageComponent
              severity="Warning"
              content={`"${deletingHoliday?.name}" wird gelöscht. Betroffene Terminserie-Ausnahmen werden automatisch aktualisiert.`}
            />
          </div>
        </DialogComponent>
      </div>
    );
  };

  const AcademicPeriodsContent = () => (
    <div style={{ padding: 20 }}>
      {/* Header with Create Button and Filter */}
      <div style={{ marginBottom: 16, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
          <ButtonComponent cssClass="e-success" iconCss="e-icons e-plus" onClick={() => {
            setPeriodFormData({ name: '', displayName: '', startDate: '', endDate: '', periodType: 'schuljahr' });
            setSelectedPeriodId(null);
            setShowCreatePeriodDialog(true);
          }}>
            Neue Periode
          </ButtonComponent>
          {(showArchivedOnly || periods.some(p => p.isArchived)) && (
            <ButtonComponent cssClass="e-flat" onClick={() => setShowArchivedOnly(!showArchivedOnly)}>
              {showArchivedOnly ? 'Aktive zeigen' : 'Archiv ('+periods.filter(p => p.isArchived).length+')'}
            </ButtonComponent>
          )}
        </div>
      </div>

      {/* Periods List */}
      {displayedPeriods.length === 0 ? (
        <div className="e-card">
          <div className="e-card-content" style={{ color: '#666', textAlign: 'center', padding: '24px' }}>
            {showArchivedOnly ? 'Keine archivierten Perioden' : 'Keine aktiven Perioden. Erstelle eine neue Periode.'}
          </div>
        </div>
      ) : (
        displayedPeriods.map(period => (
          <div key={period.id} className="e-card" style={{ marginBottom: 12 }}>
            <div className="e-card-content">
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 16 }}>
                <div style={{ flex: 1 }}>
                  <div style={{ fontWeight: 600, fontSize: '16px', marginBottom: 4 }}>
                    {period.name}
                    {period.isActive && <span style={{ marginLeft: 8, backgroundColor: '#28a745', color: 'white', padding: '4px 12px', borderRadius: '12px', fontSize: '12px', fontWeight: 500, display: 'inline-block' }}>Aktiv</span>}
                    {period.isArchived && <span style={{ marginLeft: 8, backgroundColor: '#6c757d', color: 'white', padding: '4px 12px', borderRadius: '12px', fontSize: '12px', fontWeight: 500, display: 'inline-block' }}>Archiviert</span>}
                  </div>
                  {period.displayName && <div style={{ fontSize: '13px', color: '#666', marginBottom: 8 }}>Kurzname: {period.displayName}</div>}
                  <div style={{ fontSize: '13px', color: '#666', marginBottom: 4 }}>
                    {formatIsoDateForDisplay(period.startDate)} bis {formatIsoDateForDisplay(period.endDate)}
                  </div>
                  <div style={{ fontSize: '12px', color: '#6c757d' }}>{period.periodType}</div>
                </div>
                <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', justifyContent: 'flex-end' }}>
                  {!period.isArchived && !period.isActive && (
                    <ButtonComponent cssClass="e-flat e-primary" onClick={async () => {
                      try {
                        await setActiveAcademicPeriod(period.id);
                        showToast(`Aktive Periode: ${period.displayName || period.name}`, 'e-toast-success');
                        await loadAcademicPeriods();
                      } catch (e) {
                        const msg = e instanceof Error ? e.message : 'Fehler beim Aktivieren';
                        showToast(msg, 'e-toast-danger');
                      }
                    }}>Aktivieren</ButtonComponent>
                  )}
                  {!period.isArchived && (
                    <>
                      <ButtonComponent cssClass="e-flat e-primary" onClick={() => handleEditPeriod(period)}>Bearbeiten</ButtonComponent>
                      <ButtonComponent cssClass="e-flat e-danger" onClick={() => openArchiveDialog(period.id)}>Archivieren</ButtonComponent>
                    </>
                  )}
                  {period.isArchived && (
                    <>
                      <ButtonComponent cssClass="e-flat e-primary" onClick={() => {
                        setSelectedPeriodId(period.id);
                        setShowRestoreDialog(true);
                      }}>Wiederherstellen</ButtonComponent>
                      <ButtonComponent cssClass="e-flat e-danger" onClick={() => openDeleteDialog(period.id)}>Löschen</ButtonComponent>
                    </>
                  )}
                </div>
              </div>
            </div>
          </div>
        ))
      )}

      {/* Create/Edit Dialog */}
      <DialogComponent
        header={selectedPeriodId ? 'Periode bearbeiten' : 'Neue Periode'}
        visible={showCreatePeriodDialog || showEditPeriodDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => {
          setShowCreatePeriodDialog(false);
          setShowEditPeriodDialog(false);
          setSelectedPeriodId(null);
        }}
        width="500px"
        buttons={[
          { buttonModel: { content: 'Abbrechen', isPrimary: false }, click: () => {
            setShowCreatePeriodDialog(false);
            setShowEditPeriodDialog(false);
            setSelectedPeriodId(null);
          }},
          { buttonModel: { content: periodBusy ? 'Speichere...' : 'Speichern', isPrimary: true, disabled: periodBusy }, click: handleSavePeriod },
        ]}
      >
        <div style={{ padding: 16 }}>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 6, fontWeight: 600 }}>Name *</label>
            <TextBoxComponent
              value={periodFormData.name}
              change={(e) => setPeriodFormData({...periodFormData, name: e.value || ''})}
              placeholder="z.B. Schuljahr 2026/27"
              cssClass="e-outline"
            />
          </div>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 6, fontWeight: 600 }}>Kurzname (optional)</label>
            <TextBoxComponent
              value={periodFormData.displayName}
              change={(e) => setPeriodFormData({...periodFormData, displayName: e.value || ''})}
              placeholder="z.B. SJ 26/27"
              cssClass="e-outline"
            />
          </div>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 6, fontWeight: 600 }}>Startdatum *</label>
            <TextBoxComponent
              value={periodFormData.startDate}
              change={(e) => setPeriodFormData({...periodFormData, startDate: e.value || ''})}
              placeholder="YYYY-MM-DD"
              cssClass="e-outline"
              type="date"
            />
          </div>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 6, fontWeight: 600 }}>Enddatum *</label>
            <TextBoxComponent
              value={periodFormData.endDate}
              change={(e) => setPeriodFormData({...periodFormData, endDate: e.value || ''})}
              placeholder="YYYY-MM-DD"
              cssClass="e-outline"
              type="date"
            />
          </div>
          <div>
            <label style={{ display: 'block', marginBottom: 6, fontWeight: 600 }}>Periodtyp</label>
            <DropDownListComponent
              dataSource={['schuljahr', 'semester', 'trimester']}
              value={periodFormData.periodType}
              change={(e) => setPeriodFormData({...periodFormData, periodType: e.value})}
            />
          </div>
        </div>
      </DialogComponent>

      {/* Archive Confirmation Dialog */}
      <DialogComponent
        header="Periode archivieren?"
        visible={showArchiveDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => setShowArchiveDialog(false)}
        width="400px"
        buttons={[
          { buttonModel: { content: 'Abbrechen', isPrimary: false }, click: () => setShowArchiveDialog(false)},
          { buttonModel: { content: periodBusy ? 'Archiviere...' : 'Archivieren', isPrimary: true, disabled: periodBusy }, click: handleArchivePeriod },
        ]}
      >
        <div style={{ padding: 16 }}>
          <p>Die Periode wird archiviert und ist nicht mehr in der normalen Auswahlliste sichtbar.</p>
        </div>
      </DialogComponent>

      {/* Archive Blocked Dialog */}
      <DialogComponent
        header="Archivieren blockiert"
        visible={showArchiveBlockedDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => {
          setShowArchiveBlockedDialog(false);
          setSelectedPeriodId(null);
        }}
        width="500px"
        buttons={[
          { buttonModel: { content: 'OK', isPrimary: true }, click: () => {
            setShowArchiveBlockedDialog(false);
            setSelectedPeriodId(null);
          }},
        ]}
      >
        <div style={{ padding: 16 }}>
          <MessageComponent severity="Warning" content="Diese Periode kann nicht archiviert werden:" />
          <ul style={{ marginLeft: 16, color: '#6c757d', marginTop: 8 }}>
            {periodUsage?.blockers.map((blocker, i) => (
              <li key={i}>{blocker}</li>
            ))}
          </ul>
        </div>
      </DialogComponent>

      {/* Restore Confirmation Dialog */}
      <DialogComponent
        header="Periode wiederherstellen?"
        visible={showRestoreDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => setShowRestoreDialog(false)}
        width="400px"
        buttons={[
          { buttonModel: { content: 'Abbrechen', isPrimary: false }, click: () => setShowRestoreDialog(false)},
          { buttonModel: { content: periodBusy ? 'Stelle her...' : 'Wiederherstellen', isPrimary: true, disabled: periodBusy }, click: handleRestorePeriod },
        ]}
      >
        <div style={{ padding: 16 }}>
          <p>Die archivierte Periode wird wiederhergestellt und ist inaktiv.</p>
        </div>
      </DialogComponent>

      {/* Delete Confirmation Dialog */}
      <DialogComponent
        header="Periode löschen?"
        visible={showDeleteDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => setShowDeleteDialog(false)}
        width="400px"
        buttons={[
          { buttonModel: { content: 'Abbrechen', isPrimary: false }, click: () => setShowDeleteDialog(false)},
          { buttonModel: { content: periodBusy ? 'Lösche...' : 'Löschen', isPrimary: true, cssClass: 'e-danger', disabled: periodBusy }, click: handleDeletePeriod },
        ]}
      >
        <div style={{ padding: 16 }}>
          <MessageComponent severity="Warning" content="Diese Periode wird permanent gelöscht. Diese Aktion kann nicht rückgängig gemacht werden." />
        </div>
      </DialogComponent>

      {/* Delete Blocked Dialog */}
      <DialogComponent
        header="Löschen blockiert"
        visible={showDeleteBlockedDialog}
        isModal={true}
        showCloseIcon={true}
        close={() => {
          setShowDeleteBlockedDialog(false);
          setSelectedPeriodId(null);
        }}
        width="500px"
        buttons={[
          { buttonModel: { content: 'OK', isPrimary: true }, click: () => {
            setShowDeleteBlockedDialog(false);
            setSelectedPeriodId(null);
          }},
        ]}
      >
        <div style={{ padding: 16 }}>
          <MessageComponent severity="Warning" content="Diese Periode kann nicht gelöscht werden:" />
          <ul style={{ marginLeft: 16, color: '#6c757d', marginTop: 8 }}>
            {periodUsage?.blockers.map((blocker, i) => (
              <li key={i}>{blocker}</li>
            ))}
          </ul>
        </div>
      </DialogComponent>
    </div>
  );

  // Display & Clients
  const DisplayDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Standard-Einstellungen</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter für Anzeige-Defaults (z. B. Heartbeat-Timeout, Screenshot-Aufbewahrung, Standard-Gruppe).
        </div>
      </div>
    </div>
  );

  const ClientsConfigContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Client-Konfiguration</div>
          </div>
        </div>
        <div className="e-card-content">
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <Link to="/clients"><ButtonComponent>Infoscreen-Clients öffnen</ButtonComponent></Link>
            <Link to="/infoscr_groups"><ButtonComponent>Raumgruppen öffnen</ButtonComponent></Link>
          </div>
        </div>
      </div>
    </div>
  );
        
  const UploadSettingsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Upload-Einstellungen</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter für Upload-Limits, erlaubte Dateitypen und Standardspeicherorte.
        </div>
      </div>
    </div>
  );

  const ConversionStatusContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Konvertierungsstatus</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter – Konversionsstatus-Übersicht kann hier integriert werden (siehe API /api/conversions/...).
        </div>
      </div>
    </div>
  );

  // Events
  const WebUntisSettingsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">WebUntis / Vertretungsplan</div>
          </div>
        </div>
        <div className="e-card-content">
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>
              Vertretungsplan URL
            </label>
            <TextBoxComponent
              placeholder="https://example.com/vertretungsplan"
              value={supplementUrl}
              change={(e) => setSupplementUrl(e.value || '')}
              cssClass="e-outline"
              width="100%"
            />
            <div style={{ fontSize: '12px', color: '#666', marginTop: 4 }}>
              Diese URL wird verwendet, um die Stundenplan-Änderungstabelle (Vertretungsplan) anzuzeigen.
            </div>
          </div>

          <div style={{ marginBottom: 16 }}>
            <CheckBoxComponent
              label="Vertretungsplan aktiviert"
              checked={supplementEnabled}
              change={(e) => setSupplementEnabled(e.checked || false)}
            />
          </div>

          <div style={{ display: 'flex', gap: 12 }}>
            <ButtonComponent
              cssClass="e-primary"
              onClick={onSaveSupplementSettings}
              disabled={supplementBusy}
            >
              {supplementBusy ? 'Speichere…' : 'Einstellungen speichern'}
            </ButtonComponent>
            <ButtonComponent
              cssClass="e-outline"
              onClick={onTestSupplementUrl}
              disabled={!supplementUrl}
            >
              Vorschau öffnen
            </ButtonComponent>
          </div>
        </div>
      </div>
    </div>
  );

  const PresentationsDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Präsentationen</div>
          </div>
        </div>
        <div className="e-card-content" style={{ fontSize: 14 }}>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>
              Slide-Show Intervall (Sekunden)
            </label>
            <NumericTextBoxComponent
              min={1}
              max={600}
              step={1}
              value={presentationInterval}
              format="n0"
              change={(e: { value: number }) => setPresentationInterval(Number(e.value) || 10)}
              placeholder="Intervall in Sekunden"
              width="120px"
            />
          </div>
          <div style={{ marginBottom: 16 }}>
            <CheckBoxComponent
              label="Seitenfortschritt anzeigen (Fortschrittsbalken)"
              checked={presentationPageProgress}
              change={e => setPresentationPageProgress(e.checked || false)}
            />
          </div>
          <div style={{ marginBottom: 16 }}>
            <CheckBoxComponent
              label="Präsentationsfortschritt anzeigen (Fortschrittsbalken)"
              checked={presentationAutoProgress}
              change={e => setPresentationAutoProgress(e.checked || false)}
            />
          </div>
          <ButtonComponent
            cssClass="e-primary"
            onClick={onSavePresentationSettings}
            style={{ marginTop: 8 }}
            disabled={presentationBusy}
          >
            {presentationBusy ? 'Speichere…' : 'Einstellungen speichern'}
          </ButtonComponent>
        </div>
      </div>
    </div>
  );

  const WebsitesDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Webseiten</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter für Standardwerte (Lade-Timeout, Intervall, Sandbox/Embedding) für Webseiten.
        </div>
      </div>
    </div>
  );

  const VideosDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Videos</div>
          </div>
        </div>
        <div className="e-card-content" style={{ fontSize: 14 }}>
          <div style={{ marginBottom: 16 }}>
            <CheckBoxComponent
              label="Automatisch abspielen"
              checked={videoAutoplay}
              change={e => setVideoAutoplay(!!e.checked)}
            />
          </div>

          <div style={{ marginBottom: 16 }}>
            <CheckBoxComponent
              label="In Schleife abspielen"
              checked={videoLoop}
              change={e => setVideoLoop(!!e.checked)}
            />
          </div>

          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 8, fontWeight: 500 }}>Lautstärke</label>
            <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
              <NumericTextBoxComponent
                min={0}
                max={1}
                step={0.05}
                value={videoVolume}
                format="n2"
                change={(e: { value: number }) => {
                  const v = typeof e.value === 'number' ? e.value : Number(e.value);
                  if (Number.isFinite(v)) setVideoVolume(Math.max(0, Math.min(1, v)));
                }}
                placeholder="0.0–1.0"
                width="140px"
              />
              <CheckBoxComponent
                label="Ton aus"
                checked={videoMuted}
                change={e => setVideoMuted(!!e.checked)}
              />
            </div>
          </div>

          <ButtonComponent
            cssClass="e-primary"
            onClick={onSaveVideoSettings}
            disabled={videoBusy}
          >
            {videoBusy ? 'Speichere…' : 'Einstellungen speichern'}
          </ButtonComponent>
        </div>
      </div>
    </div>
  );

  const MessagesDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Mitteilungen</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter für Standardwerte (Dauer, Layout/Styling) für Mitteilungen.
        </div>
      </div>
    </div>
  );

  const OtherDefaultsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Sonstige</div>
          </div>
        </div>
        <div className="e-card-content" style={{ color: '#666', fontSize: 14 }}>
          Platzhalter für sonstige Eventtypen.
        </div>
      </div>
    </div>
  );

  // Users
  const UsersQuickActionsContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Schnellaktionen</div>
          </div>
        </div>
        <div className="e-card-content">
          <div style={{ display: 'flex', gap: 12, flexWrap: 'wrap' }}>
            <Link to="/benutzer"><ButtonComponent cssClass="e-primary">Benutzerverwaltung öffnen</ButtonComponent></Link>
            <ButtonComponent disabled title="Demnächst">Benutzer einladen</ButtonComponent>
          </div>
        </div>
      </div>
    </div>
  );

  // System
  const OrganizationInfoContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Organisationsinformationen</div>
          </div>
        </div>
        <div className="e-card-content" style={{ padding: '16px' }}>
          <div style={{ marginBottom: 16 }}>
            <label style={{ display: 'block', marginBottom: 8, fontWeight: 600 }}>
              Organisationsname
            </label>
            <TextBoxComponent
              placeholder="z.B. Meine Schule GmbH"
              value={organizationName}
              change={(e) => setOrganizationName(e.value || '')}
              cssClass="e-outline"
              floatLabelType="Never"
              style={{ width: '100%', maxWidth: '500px' }}
            />
            <div style={{ marginTop: 8, color: '#666', fontSize: 13 }}>
              Dieser Name wird im Header des Dashboards angezeigt.
            </div>
          </div>
          <ButtonComponent
            cssClass="e-primary"
            onClick={onSaveOrganizationName}
            disabled={organizationBusy}
          >
            {organizationBusy ? 'Speichern...' : 'Speichern'}
          </ButtonComponent>
        </div>
      </div>
    </div>
  );

  const AdvancedConfigContent = () => (
    <div style={{ padding: 20 }}>
      <div className="e-card">
        <div className="e-card-header">
          <div className="e-card-header-caption">
            <div className="e-card-header-title">Erweiterte Konfiguration</div>
          </div>
        </div>
        <div className="e-card-content" style={{ padding: '16px' }}>
          <div style={{ marginBottom: 20 }}>
            <label style={{ display: 'block', marginBottom: 8, fontWeight: 600 }}>
              Scheduler: Refresh-Intervall (Sekunden)
            </label>
            <NumericTextBoxComponent
              value={refreshSeconds}
              min={0}
              step={1}
              format="n0"
              change={(e) => setRefreshSeconds(Number(e.value ?? 0))}
              cssClass="e-outline"
              width={200}
            />
            <div style={{ marginTop: 8, color: '#666', fontSize: 13 }}>
              Legt fest, wie oft der Scheduler Ereignisse an Clients republiziert, auch wenn sich nichts geändert hat.
              <br />
              <strong>0:</strong> Deaktiviert (Scheduler sendet nur bei Änderungen). 
              <br />
              <strong>&gt;0:</strong> Sekunden zwischen Republizierungen (z.B. 600 = alle 10 Min). 
              <br />
              Der Scheduler liest die Datenbank immer alle 30 Sekunden neu ab und sendet dann bei Bedarf die Änderungen an den Terminen.
            </div>
            <div style={{ marginTop: 12 }}>
              <ButtonComponent cssClass="e-primary" onClick={onSaveRefreshSeconds} disabled={refreshBusy}>
                {refreshBusy ? 'Speichern...' : 'Speichern'}
              </ButtonComponent>
            </div>
          </div>
        </div>
      </div>
    </div>
  );

  // ---------- Nested Tab wrappers (first-level tabs -> second-level content) ----------
  const AcademicCalendarTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={academicTabIndex}
      selected={(e: TabSelectedEvent) => setAcademicTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '🗂️ Perioden' }} content={AcademicPeriodsContent} />
        <TabItemDirective header={{ text: '📥 Ferienkalender: Import/Anzeige' }} content={HolidaysImportAndListContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  const DisplayClientsTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={displayTabIndex}
      selected={(e: TabSelectedEvent) => setDisplayTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '⚙️ Defaults' }} content={DisplayDefaultsContent} />
        <TabItemDirective header={{ text: '🖥️ Clients' }} content={ClientsConfigContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  const MediaFilesTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={mediaTabIndex}
      selected={(e: TabSelectedEvent) => setMediaTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '⬆️ Upload' }} content={UploadSettingsContent} />
        <TabItemDirective header={{ text: '🔄 Konvertierung' }} content={ConversionStatusContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  const EventsTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={eventsTabIndex}
      selected={(e: TabSelectedEvent) => setEventsTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '📘 WebUntis' }} content={WebUntisSettingsContent} />
        <TabItemDirective header={{ text: '🖼️ Präsentation' }} content={PresentationsDefaultsContent} />
        <TabItemDirective header={{ text: '🌐 Webseiten' }} content={WebsitesDefaultsContent} />
        <TabItemDirective header={{ text: '🎬 Videos' }} content={VideosDefaultsContent} />
        <TabItemDirective header={{ text: '💬 Mitteilungen' }} content={MessagesDefaultsContent} />
        <TabItemDirective header={{ text: '🔧 Sonstige' }} content={OtherDefaultsContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  const UsersTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={usersTabIndex}
      selected={(e: TabSelectedEvent) => setUsersTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '⚡ Schnellaktionen' }} content={UsersQuickActionsContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  const SystemTabs = () => (
    <TabComponent
      heightAdjustMode="Auto"
      selectedItem={systemTabIndex}
      selected={(e: TabSelectedEvent) => setSystemTabIndex(e.selectedIndex ?? 0)}
    >
      <TabItemsDirective>
        <TabItemDirective header={{ text: '🏢 Organisation' }} content={OrganizationInfoContent} />
        <TabItemDirective header={{ text: '🧩 Erweiterte Optionen' }} content={AdvancedConfigContent} />
      </TabItemsDirective>
    </TabComponent>
  );

  // ---------- Top-level (root) tabs ----------
  return (
    <div style={{ padding: 20 }}>
      <ToastComponent ref={toastRef} position={{ X: 'Right', Y: 'Top' }} />

      <h2 style={{ marginBottom: 20, fontSize: '24px', fontWeight: 600 }}>Einstellungen</h2>

      <TabComponent heightAdjustMode="Auto">
        <TabItemsDirective>
          <TabItemDirective header={{ text: '📅 Akademischer Kalender' }} content={AcademicCalendarTabs} />
          {isAdmin && (
            <TabItemDirective header={{ text: '🖥️ Anzeige & Clients' }} content={DisplayClientsTabs} />
          )}
          {isAdmin && (
            <TabItemDirective header={{ text: '🎬 Medien & Dateien' }} content={MediaFilesTabs} />
          )}
          {isAdmin && (
            <TabItemDirective header={{ text: '🗓️ Events' }} content={EventsTabs} />
          )}
          {isAdmin && (
            <TabItemDirective header={{ text: '👥 Benutzer' }} content={UsersTabs} />
          )}
          {isSuperadmin && (
            <TabItemDirective header={{ text: '⚙️ System' }} content={SystemTabs} />
          )}
        </TabItemsDirective>
      </TabComponent>
    </div>
  );
};

export default Einstellungen;
