// ABOUTME: Weight chart screen for visualizing weight data over time
// ABOUTME: Comprehensive weight tracking visualization with date range selection, statistics, and export

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:albi/bloc/health_data_bloc.dart';
import 'package:albi/bloc/health_data_event.dart';
import 'package:albi/services/chart_data_service.dart';
import 'package:albi/utils/constants.dart';
import 'package:albi/widgets/charts/weight_line_chart.dart';
import 'package:albi/widgets/charts/chart_date_selector.dart';
import 'package:albi/widgets/charts/chart_legend.dart';
import 'package:albi/widgets/charts/data_point_popup.dart';
import 'package:shared_preferences/shared_preferences.dart';

/// Screen for displaying weight data visualization
class WeightChartScreen extends StatefulWidget {
  const WeightChartScreen({super.key});

  @override
  State<WeightChartScreen> createState() => _WeightChartScreenState();
}

class _WeightChartScreenState extends State<WeightChartScreen>
    with SingleTickerProviderStateMixin {
  final ChartDataService _chartDataService = ChartDataService();
  
  ChartTimePeriod _selectedPeriod = ChartTimePeriod.oneMonth;
  DateTimeRange? _customRange;
  String _selectedUnit = UnitConstants.kgUnit;
  bool _showTrendLine = true;
  bool _smoothData = false;
  
  ChartData? _chartData;
  ChartDataPoint? _selectedDataPoint;
  bool _isLoading = true;
  String? _error;
  
  late AnimationController _animationController;
  late Animation<double> _fadeAnimation;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      duration: const Duration(milliseconds: 300),
      vsync: this,
    );
    _fadeAnimation = Tween<double>(begin: 0, end: 1).animate(
      CurvedAnimation(parent: _animationController, curve: Curves.easeInOut),
    );
    
    _loadSettings();
    _loadChartData();
  }

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

  /// Load user preferences for chart display
  Future<void> _loadSettings() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      setState(() {
        _selectedUnit = prefs.getString('preferred_weight_unit') ?? UnitConstants.kgUnit;
        _showTrendLine = prefs.getBool('show_trend_line') ?? true;
        _smoothData = prefs.getBool('smooth_chart_data') ?? false;
      });
    } catch (e) {
      // Continue with defaults if preferences can't be loaded
    }
  }

  /// Save user preferences for chart display
  Future<void> _saveSettings() async {
    try {
      final prefs = await SharedPreferences.getInstance();
      await prefs.setString('preferred_weight_unit', _selectedUnit);
      await prefs.setBool('show_trend_line', _showTrendLine);
      await prefs.setBool('smooth_chart_data', _smoothData);
    } catch (e) {
      // Ignore save errors for preferences
    }
  }

  /// Load chart data based on current settings
  Future<void> _loadChartData() async {
    setState(() {
      _isLoading = true;
      _error = null;
    });

    try {
      ChartData chartData;
      
      if (_customRange != null) {
        chartData = await _chartDataService.getCustomRangeWeightData(
          startDate: _customRange!.start,
          endDate: _customRange!.end,
          displayUnit: _selectedUnit,
          smoothData: _smoothData,
          includeTrend: _showTrendLine,
        );
      } else {
        chartData = await _chartDataService.getWeightChartData(
          timePeriod: _selectedPeriod,
          displayUnit: _selectedUnit,
          smoothData: _smoothData,
          includeTrend: _showTrendLine,
        );
      }

      setState(() {
        _chartData = chartData;
        _isLoading = false;
        _selectedDataPoint = null;
      });

      _animationController.forward();
    } catch (e) {
      setState(() {
        _error = 'Failed to load chart data: ${e.toString()}';
        _isLoading = false;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Weight Chart'),
        backgroundColor: Theme.of(context).colorScheme.surface,
        foregroundColor: Theme.of(context).colorScheme.onSurface,
        actions: [
          IconButton(
            onPressed: _showExportOptions,
            icon: const Icon(Icons.share),
            tooltip: 'Export chart data',
          ),
          PopupMenuButton<String>(
            onSelected: _handleMenuSelection,
            itemBuilder: (context) => [
              PopupMenuItem(
                value: 'refresh',
                child: Row(
                  children: [
                    const Icon(Icons.refresh, size: 20),
                    const SizedBox(width: 8),
                    const Text('Refresh'),
                  ],
                ),
              ),
              PopupMenuItem(
                value: 'settings',
                child: Row(
                  children: [
                    const Icon(Icons.settings, size: 20),
                    const SizedBox(width: 8),
                    const Text('Chart Settings'),
                  ],
                ),
              ),
              PopupMenuItem(
                value: 'units',
                child: Row(
                  children: [
                    const Icon(Icons.straighten, size: 20),
                    const SizedBox(width: 8),
                    const Text('Change Units'),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
      body: _buildBody(),
    );
  }

  /// Build main body content
  Widget _buildBody() {
    return Column(
      children: [
        // Date range selector
        ChartDateSelector(
          selectedPeriod: _selectedPeriod,
          customRange: _customRange,
          onDateRangeSelected: _handleDateRangeChanged,
        ),
        
        // Main chart area
        Expanded(
          child: _buildChartArea(),
        ),
      ],
    );
  }

  /// Build the main chart area with loading/error states
  Widget _buildChartArea() {
    if (_isLoading) {
      return _buildLoadingState();
    }
    
    if (_error != null) {
      return _buildErrorState();
    }
    
    if (_chartData == null || _chartData!.isEmpty) {
      return _buildEmptyState();
    }

    return FadeTransition(
      opacity: _fadeAnimation,
      child: SingleChildScrollView(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            // Chart statistics (compact view)
            ChartLegend(
              chartData: _chartData!,
              showTrend: _showTrendLine,
              compact: true,
              selectedUnit: _selectedUnit,
            ),
            
            const SizedBox(height: 16),
            
            // Main chart
            Card(
              child: WeightLineChart(
                chartData: _chartData!,
                showTrendLine: _showTrendLine,
                onDataPointTapped: _handleDataPointTapped,
                selectedUnit: _selectedUnit,
              ),
            ),
            
            const SizedBox(height: 16),
            
            // Detailed statistics
            ChartLegend(
              chartData: _chartData!,
              showTrend: _showTrendLine,
              compact: false,
              selectedUnit: _selectedUnit,
            ),
            
            // Selected data point details
            if (_selectedDataPoint != null) ...[
              const SizedBox(height: 16),
              DataPointPopup(
                dataPoint: _selectedDataPoint!,
                unit: _selectedUnit,
                onAction: _handleDataPointAction,
                onClose: () => setState(() => _selectedDataPoint = null),
              ),
            ],
          ],
        ),
      ),
    );
  }

  /// Build loading state
  Widget _buildLoadingState() {
    return const Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          CircularProgressIndicator(),
          SizedBox(height: 16),
          Text('Loading chart data...'),
        ],
      ),
    );
  }

  /// Build error state
  Widget _buildErrorState() {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.error_outline,
              size: 64,
              color: Theme.of(context).colorScheme.error,
            ),
            const SizedBox(height: 16),
            Text(
              'Failed to load chart',
              style: Theme.of(context).textTheme.titleLarge?.copyWith(
                color: Theme.of(context).colorScheme.error,
              ),
            ),
            const SizedBox(height: 8),
            Text(
              _error!,
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
              ),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 24),
            ElevatedButton.icon(
              onPressed: _loadChartData,
              icon: const Icon(Icons.refresh),
              label: const Text('Retry'),
            ),
          ],
        ),
      ),
    );
  }

  /// Build empty state
  Widget _buildEmptyState() {
    return Center(
      child: Padding(
        padding: const EdgeInsets.all(32),
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Icon(
              Icons.show_chart,
              size: 64,
              color: Theme.of(context).colorScheme.primary.withOpacity(0.3),
            ),
            const SizedBox(height: 16),
            Text(
              'No weight data',
              style: Theme.of(context).textTheme.titleLarge?.copyWith(
                color: Theme.of(context).colorScheme.onSurface.withOpacity(0.7),
              ),
            ),
            const SizedBox(height: 8),
            Text(
              'Add some weight entries to see your progress chart',
              style: Theme.of(context).textTheme.bodyMedium?.copyWith(
                color: Theme.of(context).colorScheme.onSurface.withOpacity(0.6),
              ),
              textAlign: TextAlign.center,
            ),
            const SizedBox(height: 24),
            ElevatedButton.icon(
              onPressed: () => Navigator.of(context).pop(),
              icon: const Icon(Icons.add),
              label: const Text('Add Weight Entry'),
            ),
          ],
        ),
      ),
    );
  }

  /// Handle date range selection changes
  void _handleDateRangeChanged(ChartTimePeriod? timePeriod, DateTimeRange? customRange) {
    setState(() {
      if (customRange != null) {
        _customRange = customRange;
        _selectedPeriod = ChartTimePeriod.oneMonth; // Reset to default
      } else {
        _customRange = null;
        _selectedPeriod = timePeriod ?? ChartTimePeriod.oneMonth;
      }
    });
    _loadChartData();
  }

  /// Handle data point selection
  void _handleDataPointTapped(ChartDataPoint? dataPoint) {
    setState(() {
      _selectedDataPoint = dataPoint;
    });
  }

  /// Handle data point actions (edit, delete, details)
  void _handleDataPointAction(String action, ChartDataPoint dataPoint) {
    switch (action) {
      case 'edit':
        _editDataPoint(dataPoint);
        break;
      case 'delete':
        _deleteDataPoint(dataPoint);
        break;
      case 'details':
        _showDataPointDetails(dataPoint);
        break;
    }
  }

  /// Edit a data point
  void _editDataPoint(ChartDataPoint dataPoint) {
    // Navigate to edit screen or show edit dialog
    // This would typically open the AddWeightScreen in edit mode
    ScaffoldMessenger.of(context).showSnackBar(
      const SnackBar(content: Text('Edit functionality coming soon')),
    );
  }

  /// Delete a data point
  void _deleteDataPoint(ChartDataPoint dataPoint) {
    if (dataPoint.entryId == null) return;

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Delete Weight Entry'),
        content: const Text('Are you sure you want to delete this weight entry? This action cannot be undone.'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Cancel'),
          ),
          TextButton(
            onPressed: () {
              Navigator.of(context).pop();
              context.read<HealthDataBloc>().add(
                DeleteWeightEvent(dataPoint.entryId!),
              );
              setState(() => _selectedDataPoint = null);
              _loadChartData(); // Refresh chart
            },
            child: const Text('Delete'),
          ),
        ],
      ),
    );
  }

  /// Show detailed data point information
  void _showDataPointDetails(ChartDataPoint dataPoint) {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Weight Entry Details'),
        content: DataPointPopup(
          dataPoint: dataPoint,
          unit: _selectedUnit,
          showActions: false,
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Close'),
          ),
        ],
      ),
    );
  }

  /// Handle menu selections
  void _handleMenuSelection(String value) {
    switch (value) {
      case 'refresh':
        _loadChartData();
        break;
      case 'settings':
        _showChartSettings();
        break;
      case 'units':
        _showUnitSelector();
        break;
    }
  }

  /// Show chart settings dialog
  void _showChartSettings() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Chart Settings'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            SwitchListTile(
              title: const Text('Show Trend Line'),
              subtitle: const Text('Display trend line on the chart'),
              value: _showTrendLine,
              onChanged: (value) {
                setState(() => _showTrendLine = value);
                _saveSettings();
                _loadChartData();
              },
            ),
            SwitchListTile(
              title: const Text('Smooth Data'),
              subtitle: const Text('Apply smoothing to reduce noise'),
              value: _smoothData,
              onChanged: (value) {
                setState(() => _smoothData = value);
                _saveSettings();
                _loadChartData();
              },
            ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Close'),
          ),
        ],
      ),
    );
  }

  /// Show unit selector dialog
  void _showUnitSelector() {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Select Weight Unit'),
        content: Column(
          mainAxisSize: MainAxisSize.min,
          children: [
            RadioListTile<String>(
              title: const Text('Kilograms (kg)'),
              value: UnitConstants.kgUnit,
              groupValue: _selectedUnit,
              onChanged: (value) {
                setState(() => _selectedUnit = value!);
                Navigator.of(context).pop();
                _saveSettings();
                _loadChartData();
              },
            ),
            RadioListTile<String>(
              title: const Text('Pounds (lbs)'),
              value: UnitConstants.poundsUnit,
              groupValue: _selectedUnit,
              onChanged: (value) {
                setState(() => _selectedUnit = value!);
                Navigator.of(context).pop();
                _saveSettings();
                _loadChartData();
              },
            ),
            RadioListTile<String>(
              title: const Text('Stones (st)'),
              value: UnitConstants.stonesUnit,
              groupValue: _selectedUnit,
              onChanged: (value) {
                setState(() => _selectedUnit = value!);
                Navigator.of(context).pop();
                _saveSettings();
                _loadChartData();
              },
            ),
          ],
        ),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Cancel'),
          ),
        ],
      ),
    );
  }

  /// Show export options dialog
  void _showExportOptions() {
    if (_chartData == null || _chartData!.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('No data available to export')),
      );
      return;
    }

    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text('Export Chart Data'),
        content: const Text('Export your weight data as a CSV file that can be opened in spreadsheet applications.'),
        actions: [
          TextButton(
            onPressed: () => Navigator.of(context).pop(),
            child: const Text('Cancel'),
          ),
          ElevatedButton.icon(
            onPressed: () {
              Navigator.of(context).pop();
              _exportChartData();
            },
            icon: const Icon(Icons.download),
            label: const Text('Export CSV'),
          ),
        ],
      ),
    );
  }

  /// Export chart data as CSV
  void _exportChartData() {
    if (_chartData == null) return;

    try {
      final csvData = _chartDataService.exportChartDataAsCSV(_chartData!);
      
      // In a real app, you would use a file picker or sharing plugin
      // For now, just show a success message
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(
          content: Text('CSV export functionality coming soon'),
          duration: Duration(seconds: 2),
        ),
      );
    } catch (e) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(
          content: Text('Export failed: ${e.toString()}'),
          backgroundColor: Theme.of(context).colorScheme.error,
        ),
      );
    }
  }
}
