// SPDX-FileCopyrightText: © 2025 Nøkken.io <nokken.io@proton.me>
// SPDX-License-Identifier: AGPL-3.0
//
//  mood_tracker_screen.dart
//
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:nokken/src/features/mood_tracker/models/mood_entry.dart';
import 'package:nokken/src/features/mood_tracker/providers/mood_state.dart';
import 'package:nokken/src/features/mood_tracker/utils/mood_utils.dart';
import 'package:nokken/src/core/services/navigation/navigation_service.dart';
import 'package:nokken/src/core/ui/theme/app_theme.dart';
import 'package:nokken/src/core/ui/theme/app_colors.dart';
import 'package:nokken/src/core/ui/theme/app_icons.dart';
import 'package:nokken/src/core/ui/theme/app_text_styles.dart';
import 'package:nokken/src/core/ui/widgets/dialog_service.dart';
import 'package:nokken/src/core/ui/widgets/shared_widgets.dart';
import 'package:nokken/src/core/utils/date_time_formatter.dart';

/// This widget adds a header decorator for each section in the mood tracker
class MoodSectionHeader extends StatelessWidget {
  final String title;
  final Color headerColor;
  final Widget content;
  final IconData? headerIcon;

  const MoodSectionHeader({
    super.key,
    required this.title,
    required this.headerColor,
    required this.content,
    this.headerIcon,
  });

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Header
        Container(
          color: AppColors.surface,
          padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
          child: Row(
            children: [
              // Icon if provided
              if (headerIcon != null) ...[
                Icon(
                  headerIcon,
                  size: 20,
                  color: headerColor,
                ),
                SharedWidgets.horizontalSpace(),
              ],
              // Section title
              Text(
                title,
                style: AppTextStyles.titleMedium.copyWith(
                  color: headerColor,
                  fontWeight: FontWeight.bold,
                ),
              ),
            ],
          ),
        ),
        // Content
        Padding(
          padding: const EdgeInsets.fromLTRB(16, 0, 16, 16),
          child: content,
        ),
      ],
    );
  }
}

class MoodTrackerScreen extends ConsumerStatefulWidget {
  final DateTime selectedDate;
  final MoodEntry? existingEntry;

  const MoodTrackerScreen({
    super.key,
    required this.selectedDate,
    this.existingEntry,
  });

  @override
  ConsumerState<MoodTrackerScreen> createState() => _MoodTrackerScreenState();
}

class _MoodTrackerScreenState extends ConsumerState<MoodTrackerScreen> {
  late MoodRating _selectedMood;
  late Set<Emotion> _selectedEmotions;
  late SleepQuality? _selectedSleepQuality;
  late EnergyLevel? _selectedEnergyLevel;
  late LibidoLevel? _selectedLibidoLevel;
  late AppetiteLevel? _selectedAppetiteLevel;
  late FocusLevel? _selectedFocusLevel;
  late DysphoriaLevel? _selectedDysphoriaLevel;
  late ExerciseLevel? _selectedExerciseLevel;
  late TextEditingController _notesController;
  bool _isLoading = false;

  @override
  void initState() {
    super.initState();
    _selectedMood = widget.existingEntry?.mood ?? MoodRating.okay;
    _selectedEmotions = widget.existingEntry?.emotions != null
        ? Set<Emotion>.from(widget.existingEntry!.emotions)
        : {};
    _selectedSleepQuality = widget.existingEntry?.sleepQuality;
    _selectedEnergyLevel = widget.existingEntry?.energyLevel;
    _selectedLibidoLevel = widget.existingEntry?.libidoLevel;
    _selectedAppetiteLevel = widget.existingEntry?.appetiteLevel;
    _selectedFocusLevel = widget.existingEntry?.focusLevel;
    _selectedDysphoriaLevel = widget.existingEntry?.dysphoriaLevel;
    _selectedExerciseLevel = widget.existingEntry?.exerciseLevel;
    _notesController =
        TextEditingController(text: widget.existingEntry?.notes ?? '');
  }

  @override
  void dispose() {
    _notesController.dispose();
    super.dispose();
  }

  /// Save the current mood entry
  Future<void> _saveMoodEntry() async {
    setState(() => _isLoading = true);

    try {
      // First check if an entry for this date already exists in the database
      final normalizedDate = DateTime(widget.selectedDate.year,
          widget.selectedDate.month, widget.selectedDate.day);
      final existingEntryInDb = await ref
          .read(moodStateProvider.notifier)
          .getMoodEntryForDate(normalizedDate);

      // Create entry with all fields including the new health categories
      final entry = MoodEntry(
        // Use the existing entry's ID from the database if available
        id: existingEntryInDb?.id ?? widget.existingEntry?.id,
        date: widget.selectedDate,
        mood: _selectedMood,
        emotions: _selectedEmotions,
        notes: _notesController.text.trim().isNotEmpty
            ? _notesController.text.trim()
            : null,
        sleepQuality: _selectedSleepQuality,
        energyLevel: _selectedEnergyLevel,
        libidoLevel: _selectedLibidoLevel,
        appetiteLevel: _selectedAppetiteLevel,
        focusLevel: _selectedFocusLevel,
        dysphoriaLevel: _selectedDysphoriaLevel,
        exerciseLevel: _selectedExerciseLevel,
      );

      // Add or update entry based on database existence, not the widget's existingEntry
      if (existingEntryInDb != null) {
        await ref.read(moodStateProvider.notifier).updateMoodEntry(entry);
      } else {
        await ref.read(moodStateProvider.notifier).addMoodEntry(entry);
      }

      if (mounted) {
        // Return true to indicate a successful save
        NavigationService.goBackWithResult(context, true);
      }
    } catch (e) {
      // Show error message
      if (mounted) {
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(
            content: Text('Error saving mood entry: $e'),
            backgroundColor: AppColors.error,
          ),
        );
      }
    } finally {
      if (mounted) {
        setState(() => _isLoading = false);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    final formattedDate =
        DateTimeFormatter.formatDateMMMDDYYYY(widget.selectedDate);

    // Get the mood color for theming
    final moodColor = MoodUtils.getMoodColor(_selectedMood);

    return Scaffold(
      appBar: AppBar(
        title: Text(formattedDate),
        leading: IconButton(
          icon: Icon(AppIcons.getIcon('arrow_back')),
          onPressed: () => _handleBackButton(context, ref),
        ),
        actions: [
          // Show loading indicator or save button
          _isLoading
              ? const Center(
                  child: Padding(
                    padding: AppTheme.standardCardPadding,
                    child: CircularProgressIndicator(),
                  ),
                )
              : TextButton(
                  onPressed: _saveMoodEntry,
                  child: Text(
                    'Save',
                    style: TextStyle(
                        color: AppColors.onPrimary,
                        fontWeight: FontWeight.w500),
                  ),
                ),
        ],
      ),
      body: CustomScrollView(
        slivers: [
          // Mood selector section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: '',
              headerColor: moodColor,
              content: _buildMoodSelectorContent(),
            ),
          ),

          // Emotions selector section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'What emotions did you feel today?',
              headerColor: moodColor,
              content: _buildEmotionsSelectorContent(),
            ),
          ),

          // Sleep quality section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Sleep Quality',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllSleepQualities(),
                selectedOption: _selectedSleepQuality,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getSleepQualityColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedSleepQuality = option;
                  });
                },
              ),
            ),
          ),

          // Energy level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Energy level',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllEnergyLevels(),
                selectedOption: _selectedEnergyLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getEnergyLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedEnergyLevel = option;
                  });
                },
              ),
            ),
          ),

          // Libido level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Libido',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllLibidoLevels(),
                selectedOption: _selectedLibidoLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getLibidoLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedLibidoLevel = option;
                  });
                },
              ),
            ),
          ),

          // Appetite level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Appetite',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllAppetiteLevels(),
                selectedOption: _selectedAppetiteLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getAppetiteLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedAppetiteLevel = option;
                  });
                },
              ),
            ),
          ),

          // Focus level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Focus',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllFocusLevels(),
                selectedOption: _selectedFocusLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getFocusLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedFocusLevel = option;
                  });
                },
              ),
            ),
          ),

          // Dysphoria level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Dysphoria',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllDysphoriaLevels(),
                selectedOption: _selectedDysphoriaLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getDysphoriaLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedDysphoriaLevel = option;
                  });
                },
              ),
            ),
          ),

          // Exercise level section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Exercise',
              headerColor: moodColor,
              content: _buildCategorySelectorContent(
                options: MoodUtils.getAllExerciseLevels(),
                selectedOption: _selectedExerciseLevel,
                getDisplayName: (option) => option.displayName,
                getEmoji: (option) => option.emoji,
                getColor: (option) => MoodUtils.getExerciseLevelColor(option),
                onOptionSelected: (option) {
                  setState(() {
                    _selectedExerciseLevel = option;
                  });
                },
              ),
            ),
          ),

          // Notes section
          SliverToBoxAdapter(
            child: MoodSectionHeader(
              title: 'Notes',
              headerColor: moodColor,
              headerIcon: AppIcons.getIcon('note'),
              content: _buildNotesContent(),
            ),
          ),

          // Add padding at the bottom
          const SliverPadding(
            padding: EdgeInsets.only(bottom: 80),
          ),
        ],
      ),
    );
  }

  /// Build the mood selector content
  Widget _buildMoodSelectorContent() {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        // Display the selected mood description
        Padding(
          padding: const EdgeInsets.only(bottom: 16),
          child: Text(
            _selectedMood.description,
            style: AppTextStyles.titleLarge.copyWith(
              color: MoodUtils.getMoodColor(_selectedMood),
            ),
          ),
        ),
        // Grid of mood options
        GridView.count(
          crossAxisCount: 5,
          shrinkWrap: true,
          physics: const NeverScrollableScrollPhysics(),
          children: MoodUtils.getAllMoodRatings().map((mood) {
            final isSelected = _selectedMood == mood;
            return _buildMoodOption(mood, isSelected);
          }).toList(),
        ),
      ],
    );
  }

  /// Build an individual mood option for the grid
  Widget _buildMoodOption(MoodRating mood, bool isSelected) {
    return GestureDetector(
      onTap: () {
        setState(() {
          _selectedMood = mood;
        });
      },
      child: Container(
        margin: const EdgeInsets.all(8),
        height: 50,
        width: 50,
        decoration: BoxDecoration(
          color: isSelected
              ? MoodUtils.getMoodColor(mood)
              : MoodUtils.getMoodColor(mood).withAlpha(60),
          shape: BoxShape.circle,
          border: isSelected
              ? Border.all(color: AppColors.primary, width: 2)
              : null,
        ),
        child: Center(
          child: Text(
            mood.emoji,
            style: TextStyle(
              fontSize: 24,
              fontFamily: AppTheme.emojiStyle,
              color: isSelected ? Colors.white : Colors.white.withAlpha(180),
            ),
          ),
        ),
      ),
    );
  }

  /// Build the emotions selector content
  Widget _buildEmotionsSelectorContent() {
    final allEmotions = MoodUtils.getAllEmotions();

    return GridView.count(
      crossAxisCount: 4,
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      childAspectRatio: 0.7, // To allow space for description
      mainAxisSpacing: 12,
      crossAxisSpacing: 8,
      children: allEmotions.map((emotion) {
        final isSelected = _selectedEmotions.contains(emotion);
        return _buildEmotionCircle(emotion, isSelected);
      }).toList(),
    );
  }

  /// Build an individual emotion as a circle with text underneath
  Widget _buildEmotionCircle(Emotion emotion, bool isSelected) {
    return GestureDetector(
      onTap: () {
        setState(() {
          if (_selectedEmotions.contains(emotion)) {
            _selectedEmotions.remove(emotion);
          } else {
            _selectedEmotions.add(emotion);
          }
        });
      },
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          // Emoji circle
          Container(
            margin: const EdgeInsets.all(4),
            height: 50,
            width: 50,
            decoration: BoxDecoration(
              color: isSelected
                  ? MoodUtils.getEmotionColor(emotion)
                  : MoodUtils.getEmotionColor(emotion).withAlpha(60),
              shape: BoxShape.circle,
              border: isSelected
                  ? Border.all(color: AppColors.primary, width: 2)
                  : null,
            ),
            child: Center(
              child: Text(
                emotion.emoji,
                style: TextStyle(
                  fontSize: 24,
                  fontFamily: AppTheme.emojiStyle,
                  color:
                      isSelected ? Colors.white : Colors.white.withAlpha(180),
                ),
              ),
            ),
          ),

          // Emotion name below the circle
          Padding(
            padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 4),
            child: Text(
              emotion.displayName,
              style: AppTextStyles.bodySmall.copyWith(
                color: isSelected
                    ? AppTextStyles.bodySmall.color
                    : AppTextStyles.bodySmall.color?.withAlpha(180),
              ),
              textAlign: TextAlign.center,
              maxLines: 2,
              overflow: TextOverflow.ellipsis,
            ),
          ),
        ],
      ),
    );
  }

  /// Generic method to build category selector content
  Widget _buildCategorySelectorContent<T>({
    required List<T> options,
    required T? selectedOption,
    required String Function(T) getDisplayName,
    required String Function(T) getEmoji,
    required Color Function(T) getColor,
    required void Function(T?) onOptionSelected,
  }) {
    return GridView.count(
      crossAxisCount: 4,
      shrinkWrap: true,
      physics: const NeverScrollableScrollPhysics(),
      childAspectRatio: 0.7, // To allow space for description
      mainAxisSpacing: 12,
      crossAxisSpacing: 8,
      children: options.map((option) {
        final isSelected = selectedOption == option;
        return GestureDetector(
          onTap: () {
            // Toggle selection - if already selected, deselect it
            if (isSelected) {
              onOptionSelected(null);
            } else {
              onOptionSelected(option);
            }
          },
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              // Emoji circle
              Container(
                margin: const EdgeInsets.all(4),
                height: 50,
                width: 50,
                decoration: BoxDecoration(
                  color: isSelected
                      ? getColor(option)
                      : getColor(option).withAlpha(60),
                  shape: BoxShape.circle,
                  border: isSelected
                      ? Border.all(color: AppColors.primary, width: 2)
                      : null,
                ),
                child: Center(
                  child: Text(
                    getEmoji(option),
                    style: TextStyle(
                      fontSize: 24,
                      fontFamily: AppTheme.emojiStyle,
                      color: isSelected
                          ? Colors.white
                          : Colors.white.withAlpha(180),
                    ),
                  ),
                ),
              ),

              // Option name below the circle
              Padding(
                padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 4),
                child: Text(
                  getDisplayName(option),
                  style: AppTextStyles.bodySmall.copyWith(
                    color: isSelected
                        ? AppTextStyles.bodySmall.color
                        : AppTextStyles.bodySmall.color?.withAlpha(180),
                  ),
                  textAlign: TextAlign.center,
                  maxLines: 2,
                  overflow: TextOverflow.ellipsis,
                ),
              ),
            ],
          ),
        );
      }).toList(),
    );
  }

  /// Build the notes content
  Widget _buildNotesContent() {
    return TextFormField(
      controller: _notesController,
      decoration: AppTheme.defaultTextFieldDecoration.copyWith(
        hintText: 'Write any thoughts or reflections here...',
      ),
      maxLines: 4,
    );
  }

  bool _checkForUnsavedChanges() {
    // If there's no existing entry, check if any fields have been filled
    if (widget.existingEntry == null) {
      // Check if any optional fields are set or if there are any emotions selected or if notes are added
      return _selectedSleepQuality != null ||
          _selectedEnergyLevel != null ||
          _selectedLibidoLevel != null ||
          _selectedAppetiteLevel != null ||
          _selectedFocusLevel != null ||
          _selectedDysphoriaLevel != null ||
          _selectedExerciseLevel != null ||
          _selectedEmotions.isNotEmpty ||
          _notesController.text.trim().isNotEmpty;
    }

    // Compare current values with existing entry values
    final entry = widget.existingEntry!;

    // Emotion set comparison
    final emotionsDifferent =
        _selectedEmotions.length != entry.emotions.length ||
            _selectedEmotions.any((e) => !entry.emotions.contains(e)) ||
            entry.emotions.any((e) => !_selectedEmotions.contains(e));

    // Check all fields
    return _selectedMood != entry.mood ||
        emotionsDifferent ||
        _selectedSleepQuality != entry.sleepQuality ||
        _selectedEnergyLevel != entry.energyLevel ||
        _selectedLibidoLevel != entry.libidoLevel ||
        _selectedAppetiteLevel != entry.appetiteLevel ||
        _selectedFocusLevel != entry.focusLevel ||
        _selectedDysphoriaLevel != entry.dysphoriaLevel ||
        _selectedExerciseLevel != entry.exerciseLevel ||
        _notesController.text.trim() != (entry.notes ?? '');
  }

  void _handleBackButton(BuildContext context, WidgetRef ref) {
    DialogService.handleBackWithUnsavedChanges(
      context: context,
      ref: ref,
      checkForUnsavedChanges: _checkForUnsavedChanges,
      saveFn: _saveMoodEntry,
    );
  }
}
