// SPDX-FileCopyrightText: © 2025 Nøkken.io <nokken.io@proton.me>
// SPDX-License-Identifier: AGPL-3.0
//
//  as_needed_medication_dialog.dart
//  Dialog for selecting an as-needed medication to take
//
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.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_text_styles.dart';
import 'package:nokken/src/core/ui/widgets/shared_widgets.dart';
import 'package:nokken/src/core/utils/get_icons_colors.dart';
import 'package:nokken/src/features/medication_tracker/models/medication.dart';
import 'package:nokken/src/features/medication_tracker/models/medication_dose.dart';
import 'package:nokken/src/features/medication_tracker/providers/medication_state.dart';
import 'package:nokken/src/core/services/navigation/navigation_service.dart';

/// Provider to filter medications that are marked as "take as needed"
final asNeededMedicationsProvider = Provider<List<Medication>>((ref) {
  final allMedications = ref.watch(medicationsProvider);
  return allMedications.where((med) => med.asNeeded).toList();
});

/// Dialog for selecting an as-needed medication to take now
class AsNeededMedicationDialog extends ConsumerStatefulWidget {
  /// Callback for when a medication is selected to be taken
  final void Function(Medication medication, DateTime time) onTakeMedication;

  const AsNeededMedicationDialog({
    super.key,
    required this.onTakeMedication,
  });

  @override
  ConsumerState<AsNeededMedicationDialog> createState() =>
      _AsNeededMedicationDialogState();
}

class _AsNeededMedicationDialogState
    extends ConsumerState<AsNeededMedicationDialog> {
  Medication? _selectedMedication;
  TimeOfDay _selectedTime = TimeOfDay.now();
  bool _isCustomTime = false;

  @override
  Widget build(BuildContext context) {
    final asNeededMedications = ref.watch(asNeededMedicationsProvider);

    // Sort medications by name for easier selection
    asNeededMedications.sort((a, b) => a.name.compareTo(b.name));

    return Dialog(
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(16),
      ),
      child: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          mainAxisSize: MainAxisSize.min,
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            // Dialog title
            Text(
              'Take As-Needed Medication',
              style: AppTextStyles.titleLarge,
            ),
            SharedWidgets.verticalSpace(AppTheme.doubleSpacing),

            // If no as-needed medications are available, show a message
            if (asNeededMedications.isEmpty)
              Padding(
                padding: const EdgeInsets.all(16.0),
                child: Column(
                  children: [
                    Text(
                      'You don\'t have any medications marked as "take as needed".',
                      textAlign: TextAlign.center,
                      style: AppTextStyles.bodyMedium,
                    ),
                    SharedWidgets.verticalSpace(AppTheme.doubleSpacing),
                    ElevatedButton(
                      onPressed: () {
                        Navigator.of(context).pop();
                        // Navigate to add medication screen
                        NavigationService.goToMedicationAddEdit(context);
                      },
                      child: const Text('Add As-Needed Medication'),
                    ),
                  ],
                ),
              )
            else
              // Medication dropdown and selection UI
              Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: [
                  Text(
                    'Select Medication:',
                    style: AppTextStyles.titleSmall,
                  ),
                  SharedWidgets.verticalSpace(),

                  // Custom medication selector that handles nullable values
                  InkWell(
                    onTap: () async {
                      final result = await showDialog<Medication>(
                        context: context,
                        barrierDismissible: true,
                        barrierColor: Colors.transparent,
                        builder: (context) {
                          return Dialog(
                            child: ListView.builder(
                              shrinkWrap: true,
                              itemCount: asNeededMedications.length,
                              itemBuilder: (context, index) {
                                final medication = asNeededMedications[index];
                                final isSelected = _selectedMedication !=
                                        null &&
                                    medication.id == _selectedMedication!.id;

                                return ListTile(
                                  leading:
                                      GetIconsColors.getMedicationIconWithColor(
                                          medication.medicationType),
                                  title: Text(medication.name),
                                  subtitle: Text(medication.dosage),
                                  selected: isSelected,
                                  tileColor: isSelected
                                      ? AppColors.primary.withAlpha(20)
                                      : null,
                                  onTap: () =>
                                      Navigator.of(context).pop(medication),
                                );
                              },
                            ),
                          );
                        },
                      );

                      if (result != null) {
                        setState(() {
                          _selectedMedication = result;
                        });
                      }
                    },
                    child: InputDecorator(
                      decoration: AppTheme.defaultTextFieldDecoration.copyWith(
                        suffixIcon: Icon(Icons.arrow_drop_down),
                      ),
                      child: _selectedMedication == null
                          ? Text(
                              "Select a medication",
                              style: TextStyle(color: AppTheme.grey),
                            )
                          : Row(
                              children: [
                                GetIconsColors.getMedicationIconWithColor(
                                    _selectedMedication!.medicationType),
                                const SizedBox(width: 8),
                                Expanded(
                                  child: Text(
                                    _selectedMedication!.name,
                                    overflow: TextOverflow.ellipsis,
                                  ),
                                ),
                              ],
                            ),
                    ),
                  ),

                  SharedWidgets.verticalSpace(AppTheme.doubleSpacing),

                  // Time selector
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        'Use current time:',
                        style: AppTextStyles.titleSmall,
                      ),
                      Switch(
                        value: !_isCustomTime,
                        onChanged: (value) {
                          setState(() {
                            _isCustomTime = !value;
                            if (!_isCustomTime) {
                              _selectedTime = TimeOfDay.now();
                            }
                          });
                        },
                        activeColor: AppColors.tertiary,
                      ),
                    ],
                  ),

                  if (_isCustomTime) ...[
                    SharedWidgets.verticalSpace(),
                    InkWell(
                      onTap: () => _selectTime(context),
                      child: InputDecorator(
                        decoration:
                            AppTheme.defaultTextFieldDecoration.copyWith(
                          suffixIcon: Icon(Icons.access_time),
                        ),
                        child: Text(
                          _formatTimeOfDay(_selectedTime),
                          style: AppTextStyles.bodyLarge,
                        ),
                      ),
                    ),
                  ],

                  SharedWidgets.verticalSpace(AppTheme.doubleSpacing),

                  // Actions
                  Row(
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: [
                      TextButton(
                        onPressed: () => Navigator.of(context).pop(),
                        child: Text('Cancel'),
                      ),
                      SharedWidgets.horizontalSpace(),
                      ElevatedButton(
                        onPressed: _selectedMedication == null
                            ? null
                            : () {
                                final now = DateTime.now();
                                final selectedDateTime = DateTime(
                                  now.year,
                                  now.month,
                                  now.day,
                                  _selectedTime.hour,
                                  _selectedTime.minute,
                                );
                                widget.onTakeMedication(
                                  _selectedMedication!,
                                  selectedDateTime,
                                );
                                Navigator.of(context).pop();
                              },
                        child: Text('Take'),
                      ),
                    ],
                  ),
                ],
              ),
          ],
        ),
      ),
    );
  }

  /// Show time picker dialog
  Future<void> _selectTime(BuildContext context) async {
    final TimeOfDay? picked = await showTimePicker(
      context: context,
      initialTime: _selectedTime,
    );
    if (picked != null && picked != _selectedTime) {
      setState(() {
        _selectedTime = picked;
      });
    }
  }

  /// Format time of day to display string
  String _formatTimeOfDay(TimeOfDay time) {
    final hour = time.hourOfPeriod == 0 ? 12 : time.hourOfPeriod;
    final minute = time.minute.toString().padLeft(2, '0');
    final period = time.period == DayPeriod.am ? 'AM' : 'PM';
    return '$hour:$minute $period';
  }
}
