import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:intl/intl.dart';

// profile_tab.dart
// This file contains the ProfileTab widget, which allows users to view and edit their profile information, including training times and durations. Trainers have additional options for managing training schedules.

/// The ProfileTab displays and allows editing of user profile information.
class ProfileTab extends StatefulWidget {
  /// Callback for when the user logs out successfully.
  final VoidCallback? onLogoutSuccess;
  const ProfileTab({super.key, this.onLogoutSuccess});

  @override
  State<ProfileTab> createState() => _ProfileTabState();
}

class _ProfileTabState extends State<ProfileTab> {
  // Form key for validating the profile form.
  //final _formKey = GlobalKey<FormState>();
  // Indicates if the user is a trainer.
  bool _isTrainer = false;
  // Indicates if data is currently loading.
  bool _isLoading = false;
  // Stores training times for each day.
  Map<String, TimeOfDay?> _trainingTimes = {};
  // Stores training durations for each day.
  Map<String, int> _trainingDurations = {};
  // User's name.
  String _name = '';
  // User's email.
  String _email = '';
  // User's club.
  String _club = '';
  // User's role (trainer or player).
  String? _userRole;
  // Date the user joined.
  DateTime? _joinDate;

  @override
  void initState() {
    super.initState();
    // Load user data when the widget is initialized.
    _loadUserData();
  }

  /// Loads user data from Firebase and updates the state.
  Future<void> _loadUserData() async {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) return;

    setState(() => _isLoading = true);
    try {
      final doc = await FirebaseFirestore.instance.collection('User').doc(user.uid).get();
      if (doc.exists) {
        final data = doc.data()!;
        final trainingTimes = data['trainingTimes'] as Map<String, dynamic>? ?? {};
        final trainingDurations = data['trainingDurations'] as Map<String, dynamic>? ?? {};
        
        // Convert training times from string to TimeOfDay.
        final convertedTrainingTimes = <String, TimeOfDay?>{};
        trainingTimes.forEach((key, value) {
          if (value != null) {
            final timeStr = value.toString();
            final timeParts = timeStr.split(':');
            if (timeParts.length == 2) {
              final hour = int.tryParse(timeParts[0]) ?? 0;
              final minute = int.tryParse(timeParts[1]) ?? 0;
              convertedTrainingTimes[key] = TimeOfDay(hour: hour, minute: minute);
            }
          }
        });

        setState(() {
          _name = data['name'] ?? '';
          _email = data['email'] ?? '';
          _club = data['club'] ?? '';
          _isTrainer = data['role'] == 'trainer';
          _userRole = data['role'] as String?;
          _trainingTimes = convertedTrainingTimes;
          _trainingDurations = Map<String, int>.from(trainingDurations);
          _joinDate = (data['createdAt'] as Timestamp?)?.toDate();
        });
      }
    } catch (e) {
      print('Error loading user data: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Fehler beim Laden der Daten: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  /// Saves the training time and duration for a specific day to Firebase.
  Future<void> _saveTrainingTime(String day, TimeOfDay? time, int? duration) async {
    if (time == null || duration == null) return;

    setState(() => _isLoading = true);
    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) return;

      final timeString = '${time.hour.toString().padLeft(2, '0')}:${time.minute.toString().padLeft(2, '0')}';
      
      // Update training times and durations in Firestore.
      await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
        'trainingTimes.$day': timeString,
        'trainingDurations.$day': duration,
      });

      // Create training entries from the start of the year for 52 weeks ahead.
      final now = DateTime.now();
      final yearStart = DateTime(now.year, 1, 1);
      final weekdays = {
        'Montag': 1,
        'Dienstag': 2,
        'Mittwoch': 3,
        'Donnerstag': 4,
        'Freitag': 5,
        'Samstag': 6,
        'Sonntag': 7,
      };
      final targetWeekday = weekdays[day] ?? 1;

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

      final newTrainingDates = <String>[];
      for (var i = 0; i < 52; i++) {
        final date = firstDate.add(Duration(days: i * 7));
        final normalizedDate = DateTime(date.year, date.month, date.day, time.hour, time.minute);
        final dateString = DateTime(normalizedDate.year, normalizedDate.month, normalizedDate.day).toIso8601String();
        newTrainingDates.add(dateString);
      }

      // Load existing trainingExercises and cancelledTrainings from Firestore.
      final userDoc = await FirebaseFirestore.instance.collection('User').doc(user.uid).get();
      final data = userDoc.data() ?? {};
      final trainingExercises = Map<String, dynamic>.from(data['trainingExercises'] ?? {});
      final cancelledTrainings = List<Map<String, dynamic>>.from(data['cancelledTrainings'] ?? []);

      // Add empty training only if not already present.
      for (final dateString in newTrainingDates) {
        if (!trainingExercises.containsKey(dateString)) {
          trainingExercises[dateString] = [];
        }
      }

      // Remove cancelledTrainings for these dates.
      cancelledTrainings.removeWhere((cancelled) =>
        //cancelled is Map<String, dynamic> &&
        cancelled.containsKey('date') &&
        newTrainingDates.contains(cancelled['date'])
      );

      await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
        'cancelledTrainings': cancelledTrainings,
        'trainingExercises': trainingExercises,
      });

      setState(() {
        _trainingTimes[day] = time;
        _trainingDurations[day] = duration;
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Trainingszeit gespeichert')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Fehler beim Speichern: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  /// Removes the training time and duration for a specific day from Firebase.
  Future<void> _removeTrainingTime(String day) async {
    setState(() => _isLoading = true);
    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) return;

      await FirebaseFirestore.instance.collection('User').doc(user.uid).update({
        'trainingTimes.$day': FieldValue.delete(),
        'trainingDurations.$day': FieldValue.delete(),
      });

      setState(() {
        _trainingTimes.remove(day);
        _trainingDurations.remove(day);
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Trainingszeit entfernt')),
        );
      }
    } catch (e) {
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('Fehler beim Entfernen: $e')),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  /// Opens a time picker dialog for selecting a training time, then a dialog for duration.
  Future<void> _selectTime(BuildContext context, String day) async {
    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: _trainingTimes[day] ?? TimeOfDay.now(),
    );
    if (picked != null) {
      final duration = await showDialog<int>(
        context: context,
        builder: (context) => _DurationDialog(
          initialDuration: _trainingDurations[day] ?? 60,
        ),
      );
      if (duration != null) {
        await _saveTrainingTime(day, picked, duration);
      }
    }
  }

  /// Saves the user's profile data (name, club, training times, durations) to Firebase.
  Future<void> _saveUserData() async {
    if (FirebaseAuth.instance.currentUser == null) return;

    setState(() => _isLoading = true);
    try {
      final trainingTimesMap = <String, String>{};
      _trainingTimes.forEach((key, value) {
        if (value != null) {
          trainingTimesMap[key] = '${value.hour.toString().padLeft(2, '0')}:${value.minute.toString().padLeft(2, '0')}';
        }
      });

      await FirebaseFirestore.instance
          .collection('User')
          .doc(FirebaseAuth.instance.currentUser!.uid)
          .update({
        'name': _name,
        'club': _club,
        'trainingTimes': trainingTimesMap,
        'trainingDurations': _trainingDurations,
      });

      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Profil wurde aktualisiert')),
        );
      }
    } catch (e) {
      print('Error saving user data: $e');
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Fehler beim Speichern des Profils')),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final user = FirebaseAuth.instance.currentUser;
    if (user == null) {
      // Show message if user is not logged in.
      return const Center(child: Text('Nicht eingeloggt'));
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text('Profil'),
        actions: [
          IconButton(
            icon: const Icon(Icons.logout),
            onPressed: () async {
              // Log out the user and call the callback if provided.
              await FirebaseAuth.instance.signOut();
              if (widget.onLogoutSuccess != null) {
                widget.onLogoutSuccess!();
              }
            },
          ),
          IconButton(
            icon: const Icon(Icons.save),
            onPressed: _isLoading ? null : _saveUserData,
          ),
        ],
      ),
      body: _isLoading
          ? const Center(child: CircularProgressIndicator())
          : SingleChildScrollView(
              padding: const EdgeInsets.all(16.0),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  // Card for personal information fields.
                  Card(
                    elevation: 4,
                    child: Padding(
                      padding: const EdgeInsets.all(16.0),
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          const Text(
                            'Persönliche Informationen',
                            style: TextStyle(
                              fontSize: 20,
                              fontWeight: FontWeight.bold,
                            ),
                          ),
                          const SizedBox(height: 16),
                          // Editable name field.
                          TextField(
                            controller: TextEditingController(text: _name),
                            decoration: const InputDecoration(
                              labelText: 'Name',
                              border: OutlineInputBorder(),
                              prefixIcon: Icon(Icons.person),
                            ),
                            onChanged: (value) => _name = value,
                          ),
                          const SizedBox(height: 16),
                          // Non-editable email field.
                          TextField(
                            controller: TextEditingController(text: _email),
                            decoration: const InputDecoration(
                              labelText: 'E-Mail',
                              border: OutlineInputBorder(),
                              prefixIcon: Icon(Icons.email),
                            ),
                            enabled: false,
                          ),
                          const SizedBox(height: 16),
                          // Editable club field.
                          TextField(
                            controller: TextEditingController(text: _club),
                            decoration: const InputDecoration(
                              labelText: 'Verein',
                              border: OutlineInputBorder(),
                              prefixIcon: Icon(Icons.sports),
                              hintText: 'Geben Sie Ihren Verein ein',
                            ),
                            onChanged: (value) => _club = value,
                          ),
                          const SizedBox(height: 16),
                          // Non-editable role field.
                          TextField(
                            controller: TextEditingController(text: _userRole == 'trainer' ? 'Trainer' : 'Spieler'),
                            decoration: const InputDecoration(
                              labelText: 'Rolle',
                              border: OutlineInputBorder(),
                              prefixIcon: Icon(Icons.work),
                            ),
                            enabled: false,
                          ),
                          if (_joinDate != null) ...[
                            const SizedBox(height: 16),
                            // Non-editable join date field.
                            TextField(
                              controller: TextEditingController(text: DateFormat('dd.MM.yyyy').format(_joinDate!)),
                              decoration: const InputDecoration(
                                labelText: 'Beigetreten am',
                                border: OutlineInputBorder(),
                                prefixIcon: Icon(Icons.calendar_today),
                              ),
                              enabled: false,
                            ),
                          ],
                        ],
                      ),
                    ),
                  ),
                  if (_userRole == 'trainer') ...[
                    const SizedBox(height: 24),
                    // Card for managing training times (visible only to trainers).
                    Card(
                      elevation: 4,
                      child: Padding(
                        padding: const EdgeInsets.all(16.0),
                        child: Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            const Text(
                              'Trainingszeiten',
                              style: TextStyle(
                                fontSize: 20,
                                fontWeight: FontWeight.bold,
                              ),
                            ),
                            const SizedBox(height: 16),
                            // List of training days with time and duration controls.
                            ...['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag', 'Sonntag']
                                .map((day) => Card(
                                      margin: const EdgeInsets.only(bottom: 8),
                                      child: ListTile(
                                        leading: const Icon(Icons.access_time),
                                        title: Text(day),
                                        subtitle: _trainingTimes[day] != null
                                            ? Text(
                                                '${_trainingTimes[day]!.format(context)} - ${_trainingDurations[day]} Minuten',
                                              )
                                            : const Text('Keine Trainingszeit'),
                                        trailing: Row(
                                          mainAxisSize: MainAxisSize.min,
                                          children: [
                                            // Edit or add training time button.
                                            IconButton(
                                              icon: Icon(
                                                _trainingTimes[day] != null
                                                    ? Icons.edit
                                                    : Icons.add,
                                              ),
                                              onPressed: _isLoading
                                                  ? null
                                                  : () => _selectTime(context, day),
                                            ),
                                            if (_trainingTimes[day] != null)
                                              // Remove training time button.
                                              IconButton(
                                                icon: const Icon(Icons.delete),
                                                onPressed: _isLoading
                                                    ? null
                                                    : () => _removeTrainingTime(day),
                                              ),
                                          ],
                                        ),
                                      ),
                                    ))
                                .toList(),
                          ],
                        ),
                      ),
                    ),
                  ],
                ],
              ),
            ),
    );
  }
}

/// Dialog for selecting the duration of a training session.
class _DurationDialog extends StatefulWidget {
  final int initialDuration;

  const _DurationDialog({required this.initialDuration});

  @override
  State<_DurationDialog> createState() => _DurationDialogState();
}

class _DurationDialogState extends State<_DurationDialog> {
  late int _duration;

  @override
  void initState() {
    super.initState();
    // Initialize duration with the provided initial value.
    _duration = widget.initialDuration;
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: const Text('Trainingsdauer'),
      content: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          const Text('Wähle die Dauer der Trainingseinheit in Minuten:'),
          const SizedBox(height: 16),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Decrement duration button (minimum 15 minutes).
              IconButton(
                icon: const Icon(Icons.remove),
                onPressed: () {
                  if (_duration > 15) {
                    setState(() => _duration -= 15);
                  }
                },
              ),
              Text(
                '$_duration Minuten',
                style: const TextStyle(fontSize: 18),
              ),
              // Increment duration button (maximum 300 minutes).
              IconButton(
                icon: const Icon(Icons.add),
                onPressed: _duration < 300
                    ? () => setState(() => _duration += 15)
                    : null,
              ),
            ],
          ),
        ],
      ),
      actions: [
        // Cancel button.
        TextButton(
          onPressed: () => Navigator.pop(context),
          child: const Text('Abbrechen'),
        ),
        // Confirm button.
        ElevatedButton(
          onPressed: () => Navigator.pop(context, _duration),
          child: const Text('Bestätigen'),
        ),
      ],
    );
  }
}
