// calendar_tab.dart
// This file contains the CalendarTab widget, which displays a calendar view of trainings and allows users to view, add, and manage training events.

import 'package:flutter/material.dart';
import 'package:table_calendar/table_calendar.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'training_detail_screen.dart';
import 'package:uuid/uuid.dart';

/// Mapping of training categories to colors for calendar display.
const Map<String, Color> categoryColors = {
  'Aufwärmen & Mobilisation': Colors.deepOrange,
  'Wurf- & Torabschluss': Colors.orange,
  'Torwarttraining': Colors.green,
  'Athletik': Colors.blue,
  'Pass': Colors.purple,
  'Koordination': Colors.teal,
};

/// The CalendarTab displays a calendar with all training events for the user.
class CalendarTab extends StatefulWidget {
  final DateTime? initialDate;
  const CalendarTab({super.key, this.initialDate});

  @override
  State<CalendarTab> createState() => _CalendarTabState();
}

/// State for the CalendarTab, manages event loading, calendar state, and user interactions.
class _CalendarTabState extends State<CalendarTab> {
  CalendarFormat _calendarFormat = CalendarFormat.week;
  late DateTime _focusedDay;
  DateTime? _selectedDay;
  Map<DateTime, List<Map<String, dynamic>>> _events = {};
  bool _isLoading = false;
  String? _currentUserId;
  String? _userRole;
  final _exerciseController = TextEditingController();
  final _durationController = TextEditingController();

  @override
  void dispose() {
    _exerciseController.dispose();
    _durationController.dispose();
    super.dispose();
  }

  @override
  void initState() {
    super.initState();
    _focusedDay = widget.initialDate ?? DateTime.now();
    _selectedDay = _focusedDay;
    _currentUserId = FirebaseAuth.instance.currentUser?.uid;
    _initializeData();
  }

  @override
  void didUpdateWidget(covariant CalendarTab oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.initialDate != null && widget.initialDate != oldWidget.initialDate) {
      setState(() {
        _focusedDay = widget.initialDate!;
        _selectedDay = widget.initialDate!;
      });
    }
  }

  /// Initializes user data and loads events for the calendar.
  Future<void> _initializeData() async {
    if (_currentUserId != null) {
      final userDoc = await FirebaseFirestore.instance
          .collection('User')
          .doc(_currentUserId)
          .get();
      
      if (userDoc.exists) {
        setState(() {
          _userRole = userDoc.data()?['role'] as String?;
        });
        await _loadEvents();
      }
    }
  }

  /// Loads all training events for the current user (trainer or player).
  Future<void> _loadEvents() async {
    if (_userRole == null) return;
    
    setState(() => _isLoading = true);
    try {
      QuerySnapshot trainersSnapshot;
      
      if (_userRole == 'trainer') {
        // Trainer: only their own trainings
        trainersSnapshot = await FirebaseFirestore.instance
            .collection('User')
            .where('role', isEqualTo: 'trainer')
            .where(FieldPath.documentId, isEqualTo: _currentUserId)
            .get();
      } else {
        // Player: trainings from trainers in their club
        final userDoc = await FirebaseFirestore.instance
            .collection('User')
            .doc(_currentUserId)
            .get();
        
        if (!userDoc.exists) {
          setState(() => _isLoading = false);
          return;
        }

        final userData = userDoc.data() as Map<String, dynamic>;
        final userClub = userData['club'] as String?;

        if (userClub == null || userClub.isEmpty) {
          setState(() {
            _events = {};
            _isLoading = false;
          });
          return;
        }

        trainersSnapshot = await FirebaseFirestore.instance
            .collection('User')
            .where('role', isEqualTo: 'trainer')
            .where('club', isEqualTo: userClub)
            .get();
      }

      final events = <DateTime, List<Map<String, dynamic>>>{};

      for (var trainerDoc in trainersSnapshot.docs) {
        final trainerData = trainerDoc.data() as Map<String, dynamic>;
        final trainings = trainerData['trainings'] as Map<String, dynamic>? ?? {};
        final cancelledTrainings = trainerData['cancelledTrainings'] as List<dynamic>? ?? [];
        final trainingTimes = trainerData['trainingTimes'] as Map<String, dynamic>? ?? {};
        final trainingDurations = trainerData['trainingDurations'] as Map<String, dynamic>? ?? {};

        // Load all specific trainings for each date
        trainings.forEach((dateString, trainingsList) {
          final date = DateTime.tryParse(dateString);
          if (date == null) return;
          final normalizedDate = DateTime(date.year, date.month, date.day);
          final list = List<Map<String, dynamic>>.from(trainingsList);
          for (final training in list) {
            final timeStr = training['time'] as String? ?? '00:00';
            final duration = training['duration'] as int? ?? 60;
            final exercises = training['exercises'] as List<dynamic>? ?? [];
            final totalExerciseDuration = exercises.fold<int>(0, (sum, exercise) {
              if (exercise is Map<String, dynamic>) {
                return sum + (exercise['duration'] as int? ?? 0);
              }
              return sum;
            });

            // Build the event map for this training
            final event = {
              'trainerName': trainerData['name'] ?? 'Unbekannter Trainer',
              'time': timeStr,
              'duration': duration,
              'trainerId': trainerDoc.id,
              'isCurrentUser': trainerDoc.id == _currentUserId,
              'day': dateString,
              'date': dateString,
              'exercises': exercises,
              'remainingTime': duration - totalExerciseDuration,
              'club': trainerData['club'] ?? 'Kein Verein',
              'id': training['id'],
            };
            if (events.containsKey(normalizedDate)) {
              events[normalizedDate]!.add(event);
            } else {
              events[normalizedDate] = [event];
            }
          }
        });

        // Add recurring weekly trainings for the year
        final now = DateTime.now();
        final yearStart = DateTime(now.year, 1, 1);
        final yearEnd = DateTime(now.year + 1, 1, 1);
        final weekdays = {
          'Montag': 1,
          'Dienstag': 2,
          'Mittwoch': 3,
          'Donnerstag': 4,
          'Freitag': 5,
          'Samstag': 6,
          'Sonntag': 7,
        };

        // Create a set of cancelled dates for fast lookup
        final cancelledDates = cancelledTrainings
            .where((cancelled) => cancelled is Map<String, dynamic>)
            .map((cancelled) => DateTime.parse((cancelled as Map<String, dynamic>)['date'] as String))
            .toSet();

        trainingTimes.forEach((day, timeStr) {
          if (timeStr == null) return;
          final timeParts = (timeStr as String).split(':');
          if (timeParts.length != 2) return;
          
          //final hour = int.tryParse(timeParts[0]) ?? 0;
          //final minute = int.tryParse(timeParts[1]) ?? 0;
          final duration = trainingDurations[day] ?? 60;
          final targetWeekday = weekdays[day] ?? 1;

          // Find the first desired weekday date from the start of the year
          DateTime firstDate = yearStart;
          while (firstDate.weekday != targetWeekday) {
            firstDate = firstDate.add(const Duration(days: 1));
          }

          // Generate weekly trainings for the whole year
          while (firstDate.isBefore(yearEnd)) {
            final normalizedDate = DateTime(firstDate.year, firstDate.month, firstDate.day);
            final dateString = normalizedDate.toIso8601String();
            
            // Check if the training for this date is cancelled
            final isCancelled = cancelledDates.any((cancelledDate) => 
              isSameDay(cancelledDate, normalizedDate)
            );

            // Check if a specific training already exists for this date
            final hasSpecificTraining = trainings.containsKey(dateString);

            if (!isCancelled && !hasSpecificTraining) {
              final event = {
                'trainerName': trainerData['name'] ?? 'Unbekannter Trainer',
                'time': timeStr,
                'duration': duration,
                'trainerId': trainerDoc.id,
                'isCurrentUser': trainerDoc.id == _currentUserId,
                'day': day,
                'date': dateString,
                'exercises': [],
                'remainingTime': duration,
                'club': trainerData['club'] ?? 'Kein Verein',
                'id': 'weekly_${day}_${dateString}',
              };
              if (events.containsKey(normalizedDate)) {
                events[normalizedDate]!.add(event);
              } else {
                events[normalizedDate] = [event];
              }
            }
            firstDate = firstDate.add(const Duration(days: 7));
          }
        });
      }

      setState(() {
        _events = events;
        _isLoading = false;
      });
    } catch (e) {
      setState(() => _isLoading = false);
    }
  }

  Future<void> _addExercise(Map<String, dynamic> event) async {
    if (_userRole != 'trainer' || !event['isCurrentUser']) return;

    // Navigiere zum Suchbildschirm und warte auf das Ergebnis
    final result = await Navigator.pushNamed(
      context,
      '/search',
      arguments: {
        'selectMode': true,
        'remainingTime': event['remainingTime'],
      },
    );

    // Wenn eine Übung ausgewählt wurde
    if (result != null && result is Map<String, dynamic>) {
      try {
        bool shouldAddExercise = true;

        // Prüfe die Bewertungen der Übung in der Training-Collection
        final exerciseDoc = await FirebaseFirestore.instance
            .collection('Training')
            .doc(result['id'])
            .get();

        // NEU: Prüfe, ob die Übung in den letzten 4 Wochen schon einmal durchgeführt wurde
        final userDocForCheck = await FirebaseFirestore.instance
            .collection('User')
            .doc(_currentUserId)
            .get();
        if (userDocForCheck.exists) {
          final userData = userDocForCheck.data() as Map<String, dynamic>;
          final trainings = Map<String, dynamic>.from(userData['trainings'] ?? {});
          final trainingDate = DateTime.tryParse(event['date'] as String) ?? DateTime.now();
          final fourWeeksAgo = trainingDate.subtract(const Duration(days: 28));
          bool foundInLast4Weeks = false;
          trainings.forEach((dateString, trainingsList) {
            final date = DateTime.tryParse(dateString);
            // Prüfe: im Zeitraum [fourWeeksAgo, trainingDate) (also vor dem aktuellen Training)
            if (date != null && date.isAfter(fourWeeksAgo) && date.isBefore(trainingDate)) {
              final list = List<Map<String, dynamic>>.from(trainingsList);
              for (final training in list) {
                final exercises = List<Map<String, dynamic>>.from(training['exercises'] ?? []);
                for (final exercise in exercises) {
                  if (exercise['id'] == result['id']) {
                    foundInLast4Weeks = true;
                  }
                }
              }
            }
          });
          if (foundInLast4Weeks) {
            shouldAddExercise = await showDialog<bool>(
              context: context,
              barrierDismissible: false,
              builder: (context) => AlertDialog(
                title: const Text('Übung kürzlich verwendet'),
                content: Column(
                  mainAxisSize: MainAxisSize.min,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Text('Die Übung "${result['title']}" wurde in den 4 Wochen vor diesem Training bereits durchgeführt.'),
                    const SizedBox(height: 16),
                    const Text('Möchten Sie diese Übung trotzdem zu Ihrem Training hinzufügen?'),
                  ],
                ),
                actions: [
                  TextButton(
                    onPressed: () => Navigator.pop(context, false),
                    child: const Text('Abbrechen'),
                  ),
                  TextButton(
                    onPressed: () => Navigator.pop(context, true),
                    child: const Text('Trotzdem hinzufügen'),
                  ),
                ],
              ),
            ) ?? false;
            if (!shouldAddExercise) {
              return;
            }
          }
        }

        if (exerciseDoc.exists) {
          final exerciseData = exerciseDoc.data() as Map<String, dynamic>;
          
          // Versuche die Bewertungen aus verschiedenen möglichen Feldern zu lesen
          List<Map<String, dynamic>> ratings = [];
          if (exerciseData.containsKey('ratings')) {
            ratings = List<Map<String, dynamic>>.from(exerciseData['ratings'] ?? []);
          } else if (exerciseData.containsKey('rating')) {
            ratings = List<Map<String, dynamic>>.from(exerciseData['rating'] ?? []);
          }
          
          if (ratings.isNotEmpty) {
            // Berechne den Durchschnitt der Bewertungen
            double totalRating = 0;
            for (var rating in ratings) {
              if (rating.containsKey('rating')) {
                totalRating += (rating['rating'] as num).toDouble();
              }
            }
            final averageRating = totalRating / ratings.length;

            // Wenn die durchschnittliche Bewertung unter 3 liegt, zeige eine Warnung
            if (averageRating < 3) {
              if (mounted) {
                showDialog<bool>(
                  context: context,
                  barrierDismissible: false,
                  builder: (context) => AlertDialog(
                    title: const Text('Hinweis zur Übungsbewertung'),
                    content: Column(
                      mainAxisSize: MainAxisSize.min,
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        Text('Die Übung "${result['title']}" wurde von anderen Trainern mit ${averageRating.toStringAsFixed(1)} von 5 Sternen bewertet.'),
                        const SizedBox(height: 16),
                        const Text('Möchten Sie diese Übung trotzdem zu Ihrem Training hinzufügen?'),
                      ],
                    ),
                    actions: [
                      TextButton(
                        onPressed: () => Navigator.pop(context, false),
                        child: const Text('Abbrechen'),
                      ),
                      TextButton(
                        onPressed: () => Navigator.pop(context, true),
                        child: const Text('Trotzdem hinzufügen'),
                      ),
                    ],
                  ),
                ); //?? false;
              }
            }
          }
        }

        if (!shouldAddExercise) {
          return;
        }

        // Füge die Übung zum Training hinzu
        final userDoc = await FirebaseFirestore.instance
            .collection('User')
            .doc(_currentUserId)
            .get();

        if (!userDoc.exists) return;

        final data = userDoc.data() as Map<String, dynamic>;
        final trainings = Map<String, dynamic>.from(data['trainings'] ?? {});
        final dateString = event['date'] as String;
        final trainingId = event['id'] as String;

        final newExerciseData = {
          'id': result['id'],
          'name': result['title'],
          'description': result['description'],
          'duration': result['duration'],
        };

        final trainingsForDay = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);
        final trainingIndex = trainingsForDay.indexWhere((t) => t['id'] == trainingId);

        String finalTrainingId = trainingId;

        if (trainingIndex != -1) {
          // Fall 1: Training ist bereits spezifisch, füge die Übung hinzu
          final exercises = List<Map<String, dynamic>>.from(trainingsForDay[trainingIndex]['exercises'] ?? []);
          exercises.add(newExerciseData);
          trainingsForDay[trainingIndex]['exercises'] = exercises;
        } else {
          // Fall 2: Training ist wiederkehrend, erstelle eine neue spezifische Instanz
          final newId = const Uuid().v4();
          finalTrainingId = newId;
          trainingsForDay.add({
            'id': newId,
            'time': event['time'],
            'duration': event['duration'],
            'exercises': [newExerciseData],
          });
        }
        
        trainings[dateString] = trainingsForDay;

        final updates = <String, dynamic>{'trainings': trainings};

        // Wenn das Original-Event wiederkehrend war, unterdrücke es für diesen Tag
        if (trainingId.startsWith('weekly_')) {
          final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
          if (!cancelledTrainings.any((c) => c['date'] == dateString)) {
             cancelledTrainings.add({'date': dateString});
             updates['cancelledTrainings'] = cancelledTrainings;
          }
        }
        
        // Aktualisiere die Datenbank
        await FirebaseFirestore.instance
            .collection('User')
            .doc(_currentUserId)
            .update(updates);

        // Aktualisiere die UI sofort
        setState(() {
          final normalizedDate = DateTime.parse(dateString);
          if (_events.containsKey(normalizedDate)) {
            final eventIndex = _events[normalizedDate]!.indexWhere((e) => e['id'] == trainingId);
            if (eventIndex != -1) {
              final oldEvent = _events[normalizedDate]![eventIndex];
              final exercises = List<Map<String, dynamic>>.from(oldEvent['exercises'] ?? []);
              exercises.add(newExerciseData);
              
              oldEvent['exercises'] = exercises;
              oldEvent['remainingTime'] = (oldEvent['duration'] as int) - exercises.fold<int>(0, (sum, exercise) => sum + (exercise['duration'] as int));
              
              if (trainingId.startsWith('weekly_')) {
                oldEvent['id'] = finalTrainingId; 
              }
            }
          }
        });

        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Übung wurde hinzugefügt')),
          );
        }
      } catch (e) {
        if (mounted) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Fehler beim Hinzufügen der Übung')),
          );
        }
      }
    }
  }

  Future<void> _deleteTraining(Map<String, dynamic> event) async {
    if (_userRole != 'trainer' || !event['isCurrentUser']) return;
    try {
      final userDoc = await FirebaseFirestore.instance.collection('User').doc(_currentUserId).get();
      if (!userDoc.exists) return;
      final data = userDoc.data() as Map<String, dynamic>;
      final trainings = Map<String, dynamic>.from(data['trainings'] ?? {});
      final dateString = event['date'] as String;
      final trainingId = event['id'] as String?;
      final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);

      // Wenn es sich um ein regelmäßiges Training handelt (ID beginnt mit 'weekly_')
      if (trainingId != null && trainingId.startsWith('weekly_')) {
        // Füge das Datum zu cancelledTrainings hinzu, wenn es noch nicht existiert
        if (!cancelledTrainings.any((cancelled) => 
          //cancelled is Map<String, dynamic> && 
          cancelled['date'] == dateString
        )) {
          cancelledTrainings.add({
            'date': dateString,
          });
        }
      } else {
        // Für spezifische Trainings: Entferne das Training aus der Liste
        if (trainings.containsKey(dateString)) {
          final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
          trainingsList.removeWhere((t) => t['id'] == trainingId);
          
          if (trainingsList.isEmpty) {
            trainings.remove(dateString);
          } else {
            trainings[dateString] = trainingsList;
          }
        }

        // Entferne den Eintrag aus cancelledTrainings nur, wenn es sich um ein spezifisches Training handelt
        // und kein regelmäßiges Training an diesem Tag stattfindet
        final weekdays = {
          'Montag': 1,
          'Dienstag': 2,
          'Mittwoch': 3,
          'Donnerstag': 4,
          'Freitag': 5,
          'Samstag': 6,
          'Sonntag': 7,
        };

        final date = DateTime.parse(dateString);
        final weekday = date.weekday;
        final weekdayName = weekdays.entries.firstWhere((entry) => entry.value == weekday).key;
        final trainingTimes = data['trainingTimes'] as Map<String, dynamic>? ?? {};

        // Wenn an diesem Tag kein regelmäßiges Training stattfindet, entferne den Eintrag aus cancelledTrainings
        if (!trainingTimes.containsKey(weekdayName)) {
          cancelledTrainings.removeWhere((cancelled) =>
            //cancelled is Map<String, dynamic> &&
            cancelled.containsKey('date') &&
            cancelled['date'] == dateString
          );
        }
      }

      // Aktualisiere die Datenbank
      final updates = <String, dynamic>{};

      // Aktualisiere trainings nur, wenn es nicht leer ist
      if (trainings.isNotEmpty) {
        updates['trainings'] = trainings;
      } else {
        updates['trainings'] = null;
      }

      // Aktualisiere cancelledTrainings nur, wenn es nicht leer ist
      if (cancelledTrainings.isNotEmpty) {
        updates['cancelledTrainings'] = cancelledTrainings;
      } else {
        updates['cancelledTrainings'] = null;
      }

      // Führe die Aktualisierung durch
      await FirebaseFirestore.instance.collection('User').doc(_currentUserId).update(updates);

      // Aktualisiere die UI sofort
      setState(() {
        final normalizedDate = DateTime.parse(dateString);
        if (_events.containsKey(normalizedDate)) {
          _events[normalizedDate]!.removeWhere((e) => e['id'] == trainingId);
          if (_events[normalizedDate]!.isEmpty) {
            _events.remove(normalizedDate);
          }
        }
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Training wurde gelöscht')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Fehler beim Löschen des Trainings')),
        );
      }
    }
  }

  Future<void> _removeExercise(Map<String, dynamic> event, Map<String, dynamic> exercise) async {
    if (_userRole != 'trainer' || !event['isCurrentUser']) return;

    try {
      final userDoc = await FirebaseFirestore.instance
          .collection('User')
          .doc(_currentUserId)
          .get();

      if (!userDoc.exists) return;

      final data = userDoc.data() as Map<String, dynamic>;
      final trainings = Map<String, dynamic>.from(data['trainings'] ?? {});
      final dateString = event['date'] as String;
      final trainingId = event['id'] as String;

      // Finde das Training und entferne die Übung
      if (trainings.containsKey(dateString)) {
        final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString]);
        final trainingIndex = trainingsList.indexWhere((t) => t['id'] == trainingId);
        
        if (trainingIndex != -1) {
          final exercises = List<Map<String, dynamic>>.from(trainingsList[trainingIndex]['exercises'] ?? []);
          exercises.removeWhere((e) => e['id'] == exercise['id']);
          trainingsList[trainingIndex]['exercises'] = exercises;
          trainings[dateString] = trainingsList;
        }
      }

      // Aktualisiere die Datenbank
      await FirebaseFirestore.instance
          .collection('User')
          .doc(_currentUserId)
          .update({
        'trainings': trainings,
      });

      // Aktualisiere die UI sofort
      setState(() {
        final normalizedDate = DateTime.parse(dateString);
        if (_events.containsKey(normalizedDate)) {
          final eventIndex = _events[normalizedDate]!.indexWhere((e) => e['id'] == trainingId);
          if (eventIndex != -1) {
            final exercises = List<Map<String, dynamic>>.from(_events[normalizedDate]![eventIndex]['exercises'] ?? []);
            exercises.removeWhere((e) => e['id'] == exercise['id']);
            _events[normalizedDate]![eventIndex]['exercises'] = exercises;
            _events[normalizedDate]![eventIndex]['remainingTime'] = 
                (_events[normalizedDate]![eventIndex]['duration'] as int) - 
                exercises.fold<int>(0, (sum, exercise) => sum + (exercise['duration'] as int));
          }
        }
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Übung wurde entfernt')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Fehler beim Entfernen der Übung')),
        );
      }
    }
  }

  List<Map<String, dynamic>> _getEventsForDay(DateTime day) {
    final normalizedDate = DateTime(day.year, day.month, day.day);
    return _events[normalizedDate] ?? [];
  }

  @override
  Widget build(BuildContext context) {
    final isTrainer = _userRole == 'trainer';
    return Scaffold(
      appBar: AppBar(
        title: const Text('Kalender'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: _isLoading ? null : _loadEvents,
          ),
        ],
      ),
      body: SafeArea(
        child: Column(
          children: [
            Container(
              padding: const EdgeInsets.all(8.0),
              child: TableCalendar(
                firstDay: DateTime.utc(2024, 1, 1),
                lastDay: DateTime.utc(2025, 12, 31),
                focusedDay: _focusedDay,
                calendarFormat: _calendarFormat,
                locale: 'de_DE',
                selectedDayPredicate: (day) {
                  return isSameDay(_selectedDay, day);
                },
                onDaySelected: (selectedDay, focusedDay) {
                  setState(() {
                    _selectedDay = selectedDay;
                    _focusedDay = focusedDay;
                  });
                },
                onFormatChanged: (format) {
                  setState(() {
                    _calendarFormat = format;
                  });
                },
                onPageChanged: (focusedDay) {
                  setState(() {
                    _focusedDay = focusedDay;
                  });
                },
                eventLoader: _getEventsForDay,
                calendarStyle: const CalendarStyle(
                  markersMaxCount: 1,
                  markerDecoration: BoxDecoration(
                    color: Colors.blue,
                    shape: BoxShape.circle,
                  ),
                ),
                headerStyle: const HeaderStyle(
                  formatButtonVisible: true,
                  titleCentered: true,
                ),
                calendarBuilders: CalendarBuilders(
                  markerBuilder: (context, date, events) {
                    if (events.isEmpty) return null;
                    return Positioned(
                      bottom: 1,
                      child: Container(
                        width: 8,
                        height: 8,
                        decoration: const BoxDecoration(
                          color: Colors.blue,
                          shape: BoxShape.circle,
                        ),
                      ),
                    );
                  },
                ),
                startingDayOfWeek: StartingDayOfWeek.monday,
                daysOfWeekStyle: const DaysOfWeekStyle(
                  weekdayStyle: TextStyle(fontWeight: FontWeight.bold),
                  weekendStyle: TextStyle(color: Colors.red),
                ),
                availableCalendarFormats: const {
                  CalendarFormat.week: 'Woche',
                  CalendarFormat.month: 'Monat',
                },
              ),
            ),
            if (isTrainer && _selectedDay != null) ...[
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
                child: SizedBox(
                  width: double.infinity,
                  child: ElevatedButton.icon(
                    icon: const Icon(Icons.add),
                    label: const Text('Training an diesem Tag hinzufügen'),
                    onPressed: () async {
                      final result = await showDialog<Map<String, dynamic>>(
                        context: context,
                        builder: (context) => _TrainingEditDialog(
                          date: _selectedDay!,
                        ),
                      );
                      if (result != null) {
                        await _addOrEditTraining(_selectedDay!, result['time'], result['duration'], isException: false);
                        await _loadEvents();
                      }
                    },
                  ),
                ),
              ),
            ],
            const Divider(),
            Expanded(
              child: _isLoading
                  ? const Center(child: CircularProgressIndicator())
                  : _selectedDay == null
                      ? const Center(child: Text('Bitte wähle einen Tag aus'))
                      : (() {
                          final events = _getEventsForDay(_selectedDay!);
                          // Sortiere nach Uhrzeit (Format: 'HH:mm')
                          events.sort((a, b) {
                            final aTime = a['time'] as String? ?? '00:00';
                            final bTime = b['time'] as String? ?? '00:00';
                            final aParts = aTime.split(':').map(int.parse).toList();
                            final bParts = bTime.split(':').map(int.parse).toList();
                            final aMinutes = aParts[0] * 60 + aParts[1];
                            final bMinutes = bParts[0] * 60 + bParts[1];
                            return aMinutes.compareTo(bMinutes);
                          });
                          return ListView.builder(
                            padding: const EdgeInsets.symmetric(horizontal: 16),
                            itemCount: events.length,
                            itemBuilder: (context, index) {
                              final event = events[index];
                              final isCurrentUser = event['isCurrentUser'] as bool;
                              final exercises = event['exercises'] as List<dynamic>;
                              final remainingTime = event['remainingTime'] as int;

                              return Card(
                                margin: const EdgeInsets.only(bottom: 8),
                                color: isCurrentUser ? Colors.blue.withOpacity(0.1) : null,
                                child: Column(
                                  children: [
                                    ListTile(
                                      leading: Icon(
                                        Icons.sports,
                                        color: categoryColors[event['day']] ?? (isCurrentUser ? Colors.blue : Colors.grey),
                                      ),
                                      title: Text(
                                        isCurrentUser ? 'Training' : event['trainerName'],
                                        style: TextStyle(
                                          fontWeight: isCurrentUser ? FontWeight.bold : null,
                                        ),
                                      ),
                                      subtitle: Text(
                                        '${event['time']} - ${event['duration']} Minuten\nVerbleibende Zeit: $remainingTime Minuten',
                                      ),
                                      trailing: Row(
                                        mainAxisSize: MainAxisSize.min,
                                        children: [
                                          if (isCurrentUser)
                                            IconButton(
                                              icon: const Icon(Icons.edit),
                                              onPressed: () async {
                                                final result = await showDialog<Map<String, dynamic>>(
                                                  context: context,
                                                  builder: (context) => _TrainingEditDialog(
                                                    date: _selectedDay!,
                                                    initialTime: event['time'],
                                                    initialDuration: event['duration'],
                                                    trainingId: event['id'],
                                                  ),
                                                );
                                                if (result != null) {
                                                  await _addOrEditTraining(
                                                    _selectedDay!, 
                                                    result['time'], 
                                                    result['duration'], 
                                                    isException: true,
                                                    trainingId: result['trainingId'],
                                                  );
                                                  await _loadEvents();
                                                }
                                              },
                                            ),
                                          if (isCurrentUser)
                                            IconButton(
                                              icon: const Icon(Icons.add),
                                              onPressed: () => _addExercise(event),
                                            ),
                                          IconButton(
                                            icon: const Icon(Icons.info),
                                            onPressed: () {
                                              showDialog(
                                                context: context,
                                                builder: (context) => AlertDialog(
                                                  title: Text(isCurrentUser ? 'Training' : event['trainerName']),
                                                  content: Column(
                                                    mainAxisSize: MainAxisSize.min,
                                                    crossAxisAlignment: CrossAxisAlignment.start,
                                                    children: [
                                                      Text('Zeit: ${event['time']}'),
                                                      const SizedBox(height: 8),
                                                      Text('Dauer: ${event['duration']} Minuten'),
                                                      const SizedBox(height: 8),
                                                      Text('Verbleibende Zeit: $remainingTime Minuten'),
                                                      if (exercises.isNotEmpty) ...[
                                                        const SizedBox(height: 16),
                                                        const Text('Übungen:', style: TextStyle(fontWeight: FontWeight.bold)),
                                                        const SizedBox(height: 8),
                                                        ...exercises.map((exercise) {
                                                          if (exercise is Map<String, dynamic>) {
                                                            return Padding(
                                                              padding: const EdgeInsets.only(bottom: 4),
                                                              child: Row(
                                                                children: [
                                                                  const Icon(Icons.fitness_center, size: 16),
                                                                  const SizedBox(width: 8),
                                                                  Expanded(
                                                                    child: InkWell(
                                                                      onTap: () {
                                                                        Navigator.push(
                                                                          context,
                                                                          MaterialPageRoute(
                                                                            builder: (context) => TrainingDetailScreen(
                                                                              trainingId: exercise['id'],
                                                                            ),
                                                                          ),
                                                                        );
                                                                      },
                                                                      child: Text(
                                                                        '${exercise['name']} - ${exercise['duration']} Minuten',
                                                                        style: const TextStyle(
                                                                          decoration: TextDecoration.underline,
                                                                          color: Colors.blue,
                                                                        ),
                                                                      ),
                                                                    ),
                                                                  ),
                                                                  if (isCurrentUser)
                                                                    IconButton(
                                                                      icon: const Icon(Icons.delete, color: Colors.red, size: 20),
                                                                      onPressed: () {
                                                                        showDialog(
                                                                          context: context,
                                                                          builder: (context) => AlertDialog(
                                                                            title: const Text('Übung entfernen'),
                                                                            content: Text('Möchten Sie die Übung "${exercise['name']}" wirklich entfernen?'),
                                                                            actions: [
                                                                              TextButton(
                                                                                onPressed: () => Navigator.pop(context),
                                                                                child: const Text('Abbrechen'),
                                                                              ),
                                                                              TextButton(
                                                                                onPressed: () {
                                                                                  Navigator.pop(context);
                                                                                  _removeExercise(event, exercise);
                                                                                },
                                                                                child: const Text('Entfernen', style: TextStyle(color: Colors.red)),
                                                                              ),
                                                                            ],
                                                                          ),
                                                                        );
                                                                      },
                                                                    ),
                                                                ],
                                                              ),
                                                            );
                                                          }
                                                          return const SizedBox.shrink();
                                                        }),
                                                      ],
                                                    ],
                                                  ),
                                                  actions: [
                                                    TextButton(
                                                      onPressed: () => Navigator.pop(context),
                                                      child: const Text('Schließen'),
                                                    ),
                                                  ],
                                                ),
                                              );
                                            },
                                          ),
                                          if (isCurrentUser)
                                            IconButton(
                                              icon: const Icon(Icons.delete, color: Colors.red),
                                              onPressed: () {
                                                showDialog(
                                                  context: context,
                                                  builder: (context) => AlertDialog(
                                                    title: const Text('Training löschen'),
                                                    content: const Text('Möchten Sie dieses Training wirklich löschen?'),
                                                    actions: [
                                                      TextButton(
                                                        onPressed: () => Navigator.pop(context),
                                                        child: const Text('Abbrechen'),
                                                      ),
                                                      TextButton(
                                                        onPressed: () {
                                                          Navigator.pop(context);
                                                          _deleteTraining(event);
                                                        },
                                                        child: const Text('Löschen', style: TextStyle(color: Colors.red)),
                                                      ),
                                                    ],
                                                  ),
                                                );
                                              },
                                            ),
                                        ],
                                      ),
                                    ),
                                    if (exercises.isNotEmpty)
                                      Padding(
                                        padding: const EdgeInsets.all(8.0),
                                        child: Column(
                                          crossAxisAlignment: CrossAxisAlignment.start,
                                          children: [
                                            const Divider(),
                                            const Text('Übungen:', style: TextStyle(fontWeight: FontWeight.bold)),
                                            const SizedBox(height: 8),
                                            ...exercises.map((exercise) {
                                              if (exercise is Map<String, dynamic>) {
                                                return Padding(
                                                  padding: const EdgeInsets.only(bottom: 4),
                                                  child: Row(
                                                    children: [
                                                      const Icon(Icons.fitness_center, size: 16),
                                                      const SizedBox(width: 8),
                                                      Expanded(
                                                        child: InkWell(
                                                          onTap: () {
                                                            Navigator.push(
                                                              context,
                                                              MaterialPageRoute(
                                                                builder: (context) => TrainingDetailScreen(
                                                                  trainingId: exercise['id'],
                                                                ),
                                                              ),
                                                            );
                                                          },
                                                          child: Text(
                                                            '${exercise['name']} - ${exercise['duration']} Minuten',
                                                            style: const TextStyle(
                                                              decoration: TextDecoration.underline,
                                                              color: Colors.blue,
                                                            ),
                                                          ),
                                                        ),
                                                      ),
                                                      if (isCurrentUser)
                                                        IconButton(
                                                          icon: const Icon(Icons.delete, color: Colors.red, size: 20),
                                                          onPressed: () {
                                                            showDialog(
                                                              context: context,
                                                              builder: (context) => AlertDialog(
                                                                title: const Text('Übung entfernen'),
                                                                content: Text('Möchten Sie die Übung "${exercise['name']}" wirklich entfernen?'),
                                                                actions: [
                                                                  TextButton(
                                                                    onPressed: () => Navigator.pop(context),
                                                                    child: const Text('Abbrechen'),
                                                                  ),
                                                                  TextButton(
                                                                    onPressed: () {
                                                                      Navigator.pop(context);
                                                                      _removeExercise(event, exercise);
                                                                    },
                                                                    child: const Text('Entfernen', style: TextStyle(color: Colors.red)),
                                                                  ),
                                                                ],
                                                              ),
                                                            );
                                                          },
                                                        ),
                                                    ],
                                                  ),
                                                );
                                              }
                                              return const SizedBox.shrink();
                                            }),
                                          ],
                                        ),
                                      ),
                                  ],
                                ),
                              );
                            },
                          );
                        })()
            ),
          ],
        ),
      ),
    );
  }

  Future<void> _addOrEditTraining(DateTime date, String time, int duration, {bool isException = false, String? trainingId}) async {
    final dateString = DateTime(date.year, date.month, date.day).toIso8601String();
    final userDoc = await FirebaseFirestore.instance.collection('User').doc(_currentUserId).get();
    final data = userDoc.data() ?? {};
    final trainings = Map<String, dynamic>.from(data['trainings'] ?? {});
    final uuid = const Uuid();
    final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);
    final trainingTimes = data['trainingTimes'] as Map<String, dynamic>? ?? {};

    // Trainingsliste für das Datum holen oder neu anlegen
    final trainingsList = List<Map<String, dynamic>>.from(trainings[dateString] ?? []);

    if (trainingId != null) {
      // Bearbeiten: Training mit ID ersetzen
      final idx = trainingsList.indexWhere((t) => t['id'] == trainingId);
      if (idx != -1) {
        trainingsList[idx] = {
          'id': trainingId,
          'time': time,
          'duration': duration,
          'exercises': trainingsList[idx]['exercises'] ?? [],
        };
      }
    } else {
      // Hinzufügen: neues Training-Objekt anfügen
      trainingsList.add({
        'id': uuid.v4(),
        'time': time,
        'duration': duration,
        'exercises': [],
      });
    }

    trainings[dateString] = trainingsList;

    // Prüfe, ob an diesem Tag ein regelmäßiges Training stattfindet
    final weekdays = {
      'Montag': 1,
      'Dienstag': 2,
      'Mittwoch': 3,
      'Donnerstag': 4,
      'Freitag': 5,
      'Samstag': 6,
      'Sonntag': 7,
    };

    final weekday = date.weekday;
    final weekdayName = weekdays.entries.firstWhere((entry) => entry.value == weekday).key;

    // Wenn an diesem Tag ein regelmäßiges Training stattfindet, füge es zu cancelledTrainings hinzu
    if (trainingTimes.containsKey(weekdayName)) {
      if (!cancelledTrainings.any((cancelled) => 
        //cancelled is Map<String, dynamic> && 
        cancelled['date'] == dateString
      )) {
        cancelledTrainings.add({
          'date': dateString,
        });
      }
    } else {
      // Wenn kein regelmäßiges Training stattfindet, entferne den Eintrag aus cancelledTrainings
      cancelledTrainings.removeWhere((cancelled) =>
        //cancelled is Map<String, dynamic> &&
        cancelled.containsKey('date') &&
        cancelled['date'] == dateString
      );
    }

    // Aktualisiere die Datenbank
    final updates = <String, dynamic>{};

    // Aktualisiere trainings nur, wenn es nicht leer ist
    if (trainings.isNotEmpty) {
      updates['trainings'] = trainings;
    } else {
      updates['trainings'] = null;
    }

    // Aktualisiere cancelledTrainings nur, wenn es nicht leer ist
    if (cancelledTrainings.isNotEmpty) {
      updates['cancelledTrainings'] = cancelledTrainings;
    } else {
      updates['cancelledTrainings'] = null;
    }

    // Führe die Aktualisierung durch
    await FirebaseFirestore.instance.collection('User').doc(_currentUserId).update(updates);

    // Aktualisiere die UI sofort
    setState(() {
      final normalizedDate = DateTime(date.year, date.month, date.day);
      final event = {
        'trainerName': data['name'] ?? 'Unbekannter Trainer',
        'time': time,
        'duration': duration,
        'trainerId': _currentUserId,
        'isCurrentUser': true,
        'day': dateString,
        'date': dateString,
        'exercises': [],
        'remainingTime': duration,
        'club': data['club'] ?? 'Kein Verein',
        'id': trainingId ?? uuid.v4(),
      };
      if (_events.containsKey(normalizedDate)) {
        _events[normalizedDate]!.add(event);
      } else {
        _events[normalizedDate] = [event];
      }
    });
  }

}

class _TrainingEditDialog extends StatefulWidget {
  final DateTime date;
  final String? initialTime;
  final int? initialDuration;
  final String? trainingId;
  const _TrainingEditDialog({
    required this.date, 
    this.initialTime, 
    this.initialDuration,
    this.trainingId,
  });
  @override
  State<_TrainingEditDialog> createState() => _TrainingEditDialogState();
}

class _TrainingEditDialogState extends State<_TrainingEditDialog> {
  TimeOfDay? _selectedTime;
  int _duration = 60;

  @override
  void initState() {
    super.initState();
    if (widget.initialTime != null) {
      final parts = widget.initialTime!.split(':');
      if (parts.length == 2) {
        _selectedTime = TimeOfDay(hour: int.parse(parts[0]), minute: int.parse(parts[1]));
      }
    }
    if (widget.initialDuration != null) {
      _duration = widget.initialDuration!;
    }
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Training bearbeiten (${widget.date.day}.${widget.date.month}.${widget.date.year})'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          ListTile(
            leading: const Icon(Icons.access_time),
            title: const Text('Uhrzeit wählen'),
            subtitle: Text(_selectedTime != null ? _selectedTime!.format(context) : 'Keine Uhrzeit gewählt'),
            onTap: () async {
              final picked = await showTimePicker(
                context: context,
                initialTime: _selectedTime ?? TimeOfDay.now(),
              );
              if (picked != null) {
                setState(() => _selectedTime = picked);
              }
            },
          ),
          const SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              IconButton(
                icon: const Icon(Icons.remove),
                onPressed: () {
                  if (_duration > 15) setState(() => _duration -= 15);
                },
              ),
              Text('$_duration Minuten', style: const TextStyle(fontSize: 18)),
              IconButton(
                icon: const Icon(Icons.add),
                onPressed: _duration < 300 ? () => setState(() => _duration += 15) : null,
              ),
            ],
          ),
        ],
      ),
      actions: [
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Abbrechen'),
        ),
        ElevatedButton(
          onPressed: _selectedTime != null
              ? () {
                  final timeString = _selectedTime!.hour.toString().padLeft(2, '0') + ':' + _selectedTime!.minute.toString().padLeft(2, '0');
                  Navigator.pop(context, {
                    'time': timeString, 
                    'duration': _duration,
                    'trainingId': widget.trainingId,
                  });
                }
              : null,
          child: const Text('Speichern'),
        ),
      ],
    );
  }
}
