// screens/home_screen.dart
// This file contains the main HomeScreen widget, which manages the bottom navigation bar and navigation between the main screens of the app.

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';
import 'search_tab.dart';
import 'favorites_tab.dart';
import 'calendar_tab.dart';
import 'profile_tab.dart';
import 'training_detail_screen.dart';
import '../models/categories.dart';

/// The main home screen of the app, containing the bottom navigation bar and all main tabs.
class HomeScreen extends StatefulWidget {
  final VoidCallback? onLogoutSuccess;
  const HomeScreen({super.key, this.onLogoutSuccess});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

/// State for the HomeScreen, manages navigation and data loading for the home tab.
class _HomeScreenState extends State<HomeScreen> {
  int _selectedIndex = 0;
  Map<String, dynamic>? _nextTraining;
  bool _isLoading = true;
  DateTime? _calendarInitialDate;
  String? _favoriteCategoryFilter;
  List<Map<String, dynamic>> _suggestions = [];
  bool _isLoadingSuggestions = true;
  String? _suggestionsError;
  String? _userRole;

  @override
  void initState() {
    super.initState();
    _loadNextTraining();
    _loadSuggestions();
  }

  /// Loads exercise suggestions for the user based on unused and highly rated exercises.
  Future<void> _loadSuggestions() async {
    setState(() {
      _isLoadingSuggestions = true;
      _suggestionsError = null;
    });

    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        setState(() => _isLoadingSuggestions = false);
        return;
      }

      // 1. Get all exercise IDs used by the user
      final userDoc = await FirebaseFirestore.instance.collection('User').doc(user.uid).get();
      final Set<String> usedExerciseIds = {};
      if (userDoc.exists) {
        final userData = userDoc.data() as Map<String, dynamic>;
        final trainings = Map<String, dynamic>.from(userData['trainings'] ?? {});
        trainings.forEach((date, trainingsList) {
          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.containsKey('id')) {
                usedExerciseIds.add(exercise['id']);
              }
            }
          }
        });
      }

      // 2. Get all exercises
      final exercisesSnapshot = await FirebaseFirestore.instance.collection('Training').get();

      final allExercises = exercisesSnapshot.docs.map((doc) {
        return {'id': doc.id, ...doc.data()};
      }).toList();

      // 3. Filter for unused and highly rated exercises
      final suggestions = allExercises.where((exercise) {
        final isUsed = usedExerciseIds.contains(exercise['id']);
        final rating = (exercise['rating overall'] as num?)?.toDouble() ?? 0.0;
        return !isUsed && rating >= 4.0;
      }).toList();

      suggestions.shuffle();
      
      setState(() {
        _suggestions = suggestions.take(5).toList();
        _isLoadingSuggestions = false;
      });

    } catch (e) {
      setState(() {
        _isLoadingSuggestions = false;
        _suggestionsError = 'Error loading suggestions.';
      });
    }
  }

  /// Loads the next training event for the user, depending on their role and club.
  Future<void> _loadNextTraining() async {
    setState(() => _isLoading = true);
    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) return;

      final userDoc = await FirebaseFirestore.instance
          .collection('User')
          .doc(user.uid)
          .get();

      if (!userDoc.exists) return;

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

      QuerySnapshot trainersSnapshot;
      if (_userRole == 'trainer') {
        // Trainer sees only their own trainings
        trainersSnapshot = await FirebaseFirestore.instance
            .collection('User')
            .where('role', isEqualTo: 'trainer')
            .where(FieldPath.documentId, isEqualTo: user.uid)
            .get();
      } else {
        // Player sees only trainings from trainers in their club
        if (userClub == null || userClub.isEmpty) {
          setState(() {
            _nextTraining = null;
            _isLoading = false;
          });
          return;
        }

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

      final now = DateTime.now();
      DateTime? nextTrainingDate;
      Map<String, dynamic>? nextTraining;

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

        // First, check individual trainings (manually added)
        trainings.forEach((dateString, trainingsList) {
          final date = DateTime.tryParse(dateString);
          if (date == null) return;
          
          // Only consider future trainings
          if (date.isBefore(now)) return;

          final list = List<Map<String, dynamic>>.from(trainingsList);
          for (final training in list) {
            final trainingTime = training['time'] as String? ?? '19:00';
            final trainingDuration = training['duration'] as int? ?? 60;
            
            final timeParts = trainingTime.split(':');
            if (timeParts.length != 2) continue;
            
            final hour = int.tryParse(timeParts[0]) ?? 0;
            final minute = int.tryParse(timeParts[1]) ?? 0;
            final trainingDateTime = DateTime(date.year, date.month, date.day, hour, minute);
            
            if (trainingDateTime.isAfter(now) && (nextTrainingDate == null || trainingDateTime.isBefore(nextTrainingDate!))) {
              nextTrainingDate = trainingDateTime;
              nextTraining = {
                'date': dateString,
                'time': trainingTime,
                'duration': trainingDuration,
                'trainerName': trainerData['name'] ?? 'Unknown Trainer',
                'day': DateFormat('EEEE', 'de_DE').format(date),
              };
            }
          }
        });

        // Then check regular training times (only if no individual training was found)
        if (nextTrainingDate == null) {
          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 daysUntilNext = _getDaysUntilNext(day, now.weekday);
            final eventDate = DateTime(now.year, now.month, now.day + daysUntilNext, hour, minute);

            // Check the next 4 weeks
            for (var i = 0; i < 4; i++) {
              final date = eventDate.add(Duration(days: i * 7));
              final normalizedDate = DateTime(date.year, date.month, date.day);
              final dateString = normalizedDate.toIso8601String();
              
              final isCancelled = cancelledTrainings.any((cancelled) {
                if (cancelled is Map<String, dynamic>) {
                  final cancelledDate = DateTime.parse(cancelled['date'] as String);
                  return isSameDay(cancelledDate, normalizedDate);
                }
                return false;
              });

              if (!isCancelled) {
                if (nextTrainingDate == null || date.isBefore(nextTrainingDate!)) {
                  nextTrainingDate = date;
                  nextTraining = {
                    'date': dateString,
                    'time': timeStr,
                    'duration': trainingDurations[day] ?? 60,
                    'trainerName': trainerData['name'] ?? 'Unknown Trainer',
                    'day': day,
                  };
                }
              }
            }
          });
        }
      }

      setState(() {
        _nextTraining = nextTraining;
        _isLoading = false;
      });
    } catch (e) {
      print('Error loading next training: $e');
      setState(() {
        _isLoading = false;
      });
    }
  }

  /// Returns the number of days until the next occurrence of a given weekday.
  int _getDaysUntilNext(String day, int currentWeekday) {
    final weekdays = {
      'Montag': 1,
      'Dienstag': 2,
      'Mittwoch': 3,
      'Donnerstag': 4,
      'Freitag': 5,
      'Samstag': 6,
      'Sonntag': 7,
    };

    final targetWeekday = weekdays[day] ?? 1;
    var daysUntilNext = targetWeekday - currentWeekday;
    if (daysUntilNext <= 0) {
      daysUntilNext += 7;
    }
    return daysUntilNext;
  }

  /// Checks if two DateTime objects represent the same day.
  bool isSameDay(DateTime a, DateTime b) {
    return a.year == b.year && a.month == b.month && a.day == b.day;
  }

  /// Handles navigation bar item taps and reloads suggestions if needed.
  void _onItemTapped(int index) {
    if (_selectedIndex != index) {
      setState(() {
        _selectedIndex = index;
      });
      // Reload suggestions and next training when switching to the Home tab
      if (index == 0) {
        _loadSuggestions();
        _loadNextTraining();
      }
    }
  }

  /// List of main screens for the bottom navigation bar.
  List<Widget> get _screens => [
        _buildHomeTab(),
        const SearchTab(),
        FavoritesTab(categoryFilter: _favoriteCategoryFilter),
        CalendarTab(initialDate: _calendarInitialDate),
        ProfileTab(onLogoutSuccess: widget.onLogoutSuccess),
      ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: _screens[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
          BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Suche'),
          BottomNavigationBarItem(
            icon: Icon(Icons.favorite_border),
            label: 'Favoriten',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.calendar_today),
            label: 'Kalender',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.person_outline),
            label: 'Profil',
          ),
        ],
      ),
    );
  }

  /// Builds the Home tab content, including next training, favorites, and suggestions.
  Widget _buildHomeTab() {
    return SafeArea(
      child: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            const SizedBox(height: 16),
            Center(
              child: Text(
                _userRole == 'trainer' ? 'Hallo Trainer!' : 'Hallo Spieler!',
                style: const TextStyle(
                  fontSize: 32,
                  fontWeight: FontWeight.bold,
                  color: Color(0xFFE57399),
                ),
              ),
            ),
            const SizedBox(height: 24),
            GestureDetector(
              onTap: () {
                if (_nextTraining != null) {
                  setState(() {
                    _calendarInitialDate = DateTime.parse(_nextTraining!['date']);
                    _selectedIndex = 3;
                  });
                } else {
                  setState(() => _selectedIndex = 3);
                }
              },
              child: Stack(
                children: [
                  Container(
                    height: 140,
                    width: double.infinity,
                    decoration: BoxDecoration(
                      color: Colors.pink[100],
                      borderRadius: BorderRadius.circular(20),
                    ),
                    child: const Center(
                      child: Icon(Icons.sports_handball, size: 80, color: Colors.white70),
                    ),
                  ),
                  Positioned(
                    left: 20,
                    bottom: 20,
                    child: FittedBox(
                      fit: BoxFit.scaleDown,
                      child: Text(
                        'Dein nächstes Training',
                        style: TextStyle(
                          color: Colors.white,
                          fontSize: 22,
                          fontWeight: FontWeight.bold,
                          shadows: [
                            Shadow(
                              blurRadius: 8,
                              color: Colors.black.withOpacity(0.5),
                              offset: Offset(2, 2),
                            ),
                          ],
                        ),
                      ),
                    ),
                  ),
                  if (_isLoading)
                    const Positioned.fill(
                      child: Center(child: CircularProgressIndicator()),
                    )
                  else if (_nextTraining != null)
                    Positioned(
                      right: 20,
                      bottom: 20,
                      child: Container(
                        padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 6),
                        decoration: BoxDecoration(
                          color: Colors.black54,
                          borderRadius: BorderRadius.circular(12),
                        ),
                        child: Text(
                          DateFormat('EEEE, dd.MM.yyyy', 'de_DE').format(
                            DateTime.parse(_nextTraining!['date']),
                          ),
                          style: const TextStyle(color: Colors.white, fontSize: 14),
                        ),
                      ),
                    ),
                ],
              ),
            ),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Favoriten',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                IconButton(
                  icon: const Icon(Icons.chevron_right),
                  onPressed: () {},
                ),
              ],
            ),
            Padding(
              padding: const EdgeInsets.symmetric(vertical: 8.0),
              child: SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: kTrainingCategories.map((cat) => _buildFavoriteCircle(
                    cat.name,
                    cat.icon,
                    categoryColors[cat.name] ?? Colors.grey,
                  )).toList(),
                ),
              ),
            ),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Vorschläge',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                IconButton(
                  icon: const Icon(Icons.chevron_right),
                  onPressed: () {
                    setState(() => _selectedIndex = 1);
                  },
                ),
              ],
            ),
            if (_isLoadingSuggestions)
              const SizedBox(
                height: 170,
                child: Center(child: CircularProgressIndicator()),
              )
            else if (_suggestionsError != null)
              SizedBox(
                height: 170,
                child: Center(child: Text(_suggestionsError!)),
              )
            else if (_suggestions.isEmpty)
              const SizedBox(
                height: 170,
                child: Center(child: Text('Keine neuen Vorschläge gefunden.')),
              )
            else
              SizedBox(
                height: 170,
                child: ListView.builder(
                  scrollDirection: Axis.horizontal,
                  itemCount: _suggestions.length,
                  itemBuilder: (context, index) {
                    return _buildSuggestionCard(_suggestions[index]);
                  },
                ),
              ),
          ],
        ),
      ),
    );
  }

  /// Builds a favorite category circle with icon and label.
  Widget _buildFavoriteCircle(String label, IconData icon, Color color) {
    return Padding(
      padding: const EdgeInsets.only(right: 16.0),
      child: GestureDetector(
        onTap: () {
          setState(() {
            _favoriteCategoryFilter = label;
            _selectedIndex = 2;
          });
        },
        child: Column(
          children: [
            CircleAvatar(
              radius: 24,
              backgroundColor: color.withOpacity(0.2),
              child: Icon(icon, color: color, size: 26),
            ),
            const SizedBox(height: 4),
            SizedBox(
              width: 60,
              child: Text(
                label,
                style: const TextStyle(fontSize: 12),
                textAlign: TextAlign.center,
                maxLines: 2,
                overflow: TextOverflow.ellipsis,
              ),
            ),
          ],
        ),
      ),
    );
  }

  /// Builds a suggestion card for an exercise.
  Widget _buildSuggestionCard(Map<String, dynamic> exercise) {
    final category = exercise['category'] as String? ?? 'Sonstiges';
    final title = exercise['title'] as String? ?? 'Unbekannte Übung';
    final id = exercise['id'] as String;

    final color = categoryColors[category] ?? Colors.grey;
    final icon = categoryIcons[category] ?? Icons.help_outline;

    return GestureDetector(
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(
            builder: (context) => TrainingDetailScreen(trainingId: id),
          ),
        );
      },
      child: Container(
        width: 130,
        margin: const EdgeInsets.only(right: 16),
        child: Card(
          shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
          elevation: 3,
          clipBehavior: Clip.antiAlias,
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Container(
                height: 80,
                width: double.infinity,
                color: color.withOpacity(0.15),
                child: Center(
                  child: Icon(icon, color: color, size: 40),
                ),
              ),
              Expanded(
                child: Padding(
                  padding: const EdgeInsets.all(8.0),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: [
                      Flexible(
                        child: FittedBox(
                          fit: BoxFit.scaleDown,
                          alignment: Alignment.centerLeft,
                          child: Text(
                            category,
                            style: const TextStyle(fontSize: 12, color: Colors.grey),
                            maxLines: 1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      ),
                      const SizedBox(height: 4),
                      Flexible(
                        child: FittedBox(
                          fit: BoxFit.scaleDown,
                          alignment: Alignment.centerLeft,
                          child: Text(
                            title,
                            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 13),
                            maxLines: 2,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

/// Mapping of category names to icons.
const Map<String, IconData> categoryIcons = {
  'Aufwärmen & Mobilisation': Icons.directions_run,
  'Wurf- & Torabschluss': Icons.sports_handball,
  'Torwarttraining': Icons.sports,
  'Athletik': Icons.fitness_center,
  'Pass': Icons.compare_arrows,
  'Koordination': Icons.directions_walk,
};

/// Mapping of category names to colors.
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,
  'Spielformen': Colors.indigo,
  'kleine Spiele': Colors.brown,
}; 