import 'package:em2rp/models/event_model.dart';
import 'package:em2rp/models/event_statistics_models.dart';
import 'package:em2rp/providers/local_user_provider.dart';
import 'package:em2rp/services/api_service.dart';
import 'package:em2rp/services/data_service.dart';
import 'package:em2rp/services/event_statistics_service.dart';
import 'package:em2rp/utils/colors.dart';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';

enum _AmountDisplayMode { ht, ttc }

enum _DatePreset { currentMonth, previousMonth, currentYear, previousYear }

class EventStatisticsTab extends StatefulWidget {
  const EventStatisticsTab({super.key});

  @override
  State<EventStatisticsTab> createState() => _EventStatisticsTabState();
}

class _EventStatisticsTabState extends State<EventStatisticsTab> {
  final DataService _dataService = DataService(FirebaseFunctionsApiService());
  final EventStatisticsService _statisticsService =
      const EventStatisticsService();

  final NumberFormat _currencyFormat =
      NumberFormat.currency(locale: 'fr_FR', symbol: 'EUR ');
  final NumberFormat _percentFormat = NumberFormat.percentPattern('fr_FR');

  DateTimeRange _selectedPeriod = _initialPeriod();
  final Set<String> _selectedEventTypeIds = {};
  final Set<EventStatus> _selectedStatuses = {
    EventStatus.confirmed,
    EventStatus.waitingForApproval,
  };
  _AmountDisplayMode _amountDisplayMode = _AmountDisplayMode.ht;

  bool _isLoading = true;
  String? _errorMessage;

  List<EventModel> _events = [];
  Map<String, String> _eventTypeNames = {};
  EventStatisticsSummary _summary = EventStatisticsSummary.empty;

  @override
  void initState() {
    super.initState();
    _loadStatistics();
  }

  static DateTimeRange _initialPeriod() {
    final now = DateTime.now();
    return DateTimeRange(
      start: DateTime(now.year, now.month, 1),
      end: DateTime(now.year, now.month + 1, 0, 23, 59, 59),
    );
  }

  Future<void> _loadStatistics() async {
    setState(() {
      _isLoading = true;
      _errorMessage = null;
    });

    try {
      final localUserProvider =
          Provider.of<LocalUserProvider>(context, listen: false);
      final userId = localUserProvider.uid;

      final results = await Future.wait([
        _dataService.getEvents(userId: userId),
        _dataService.getEventTypes(),
      ]);

      final eventsResult = results[0] as Map<String, dynamic>;
      final eventTypesResult = results[1] as List<Map<String, dynamic>>;
      final eventsData = eventsResult['events'] as List<Map<String, dynamic>>;

      final parsedEvents = <EventModel>[];
      for (final eventData in eventsData) {
        try {
          parsedEvents
              .add(EventModel.fromMap(eventData, eventData['id'] as String));
        } catch (_) {
          // Ignore malformed rows and continue to keep the dashboard available.
        }
      }

      final eventTypeNames = <String, String>{};
      for (final eventType in eventTypesResult) {
        final id = (eventType['id'] ?? '').toString();
        if (id.isEmpty) {
          continue;
        }
        eventTypeNames[id] = (eventType['name'] ?? id).toString();
      }

      if (!mounted) {
        return;
      }

      setState(() {
        _events = parsedEvents;
        _eventTypeNames = eventTypeNames;
        _isLoading = false;
      });

      _rebuildSummary();
    } catch (error) {
      if (!mounted) {
        return;
      }
      setState(() {
        _isLoading = false;
        _errorMessage = 'Erreur lors du chargement des statistiques: $error';
      });
    }
  }

  void _rebuildSummary() {
    final filter = EventStatisticsFilter(
      period: _selectedPeriod,
      eventTypeIds: _selectedEventTypeIds,
      includeCanceled: _selectedStatuses.contains(EventStatus.canceled),
      selectedStatuses: _selectedStatuses,
    );

    setState(() {
      _summary = _statisticsService.buildSummary(
        events: _events,
        filter: filter,
        eventTypeNames: _eventTypeNames,
      );
    });
  }

  Future<void> _selectDateRange() async {
    final selectedRange = await showDateRangePicker(
      context: context,
      firstDate: DateTime(2020),
      lastDate: DateTime(2035),
      initialDateRange: _selectedPeriod,
      locale: const Locale('fr', 'FR'),
      builder: (context, child) {
        return Theme(
          data: Theme.of(context).copyWith(
            colorScheme: ColorScheme.light(
              primary: AppColors.rouge,
              onPrimary: Colors.white,
            ),
          ),
          child: child ?? const SizedBox.shrink(),
        );
      },
    );

    if (selectedRange == null) {
      return;
    }

    setState(() {
      _selectedPeriod = DateTimeRange(
        start: selectedRange.start,
        end: DateTime(
          selectedRange.end.year,
          selectedRange.end.month,
          selectedRange.end.day,
          23,
          59,
          59,
        ),
      );
    });

    _rebuildSummary();
  }

  void _resetFilters() {
    setState(() {
      _selectedPeriod = _initialPeriod();
      _selectedEventTypeIds.clear();
      _selectedStatuses.clear();
      _selectedStatuses.addAll({
        EventStatus.confirmed,
        EventStatus.waitingForApproval,
      });
      _amountDisplayMode = _AmountDisplayMode.ht;
    });
    _rebuildSummary();
  }

  String _formatCurrency(double value) => _currencyFormat.format(value);

  String _formatPercent(double value) => _percentFormat.format(value);

  String get _amountUnitLabel =>
      _amountDisplayMode == _AmountDisplayMode.ht ? 'HT' : 'TTC';

  double _toDisplayAmount(double htAmount) {
    if (_amountDisplayMode == _AmountDisplayMode.ttc) {
      return htAmount * 1.2;
    }
    return htAmount;
  }

  String _formatAmount(double htAmount) =>
      _formatCurrency(_toDisplayAmount(htAmount));

  String _presetLabel(_DatePreset preset) {
    switch (preset) {
      case _DatePreset.currentMonth:
        return 'Ce mois-ci';
      case _DatePreset.previousMonth:
        return 'Mois dernier';
      case _DatePreset.currentYear:
        return 'Cette année';
      case _DatePreset.previousYear:
        return 'Année dernière';
    }
  }

  DateTimeRange _rangeForMonth(int year, int month) {
    return DateTimeRange(
      start: DateTime(year, month, 1),
      end: DateTime(year, month + 1, 0, 23, 59, 59),
    );
  }

  DateTimeRange _rangeForYear(int year) {
    return DateTimeRange(
      start: DateTime(year, 1, 1),
      end: DateTime(year, 12, 31, 23, 59, 59),
    );
  }

  DateTimeRange _rangeForPreset(_DatePreset preset) {
    final now = DateTime.now();

    switch (preset) {
      case _DatePreset.currentMonth:
        return _rangeForMonth(now.year, now.month);
      case _DatePreset.previousMonth:
        return _rangeForMonth(now.year, now.month - 1);
      case _DatePreset.currentYear:
        return _rangeForYear(now.year);
      case _DatePreset.previousYear:
        return _rangeForYear(now.year - 1);
    }
  }

  bool _isPresetSelected(_DatePreset preset) {
    final presetRange = _rangeForPreset(preset);
    return _selectedPeriod.start == presetRange.start &&
        _selectedPeriod.end == presetRange.end;
  }

  void _applyDatePreset(_DatePreset preset) {
    setState(() {
      _selectedPeriod = _rangeForPreset(preset);
    });
    _rebuildSummary();
  }

  @override
  Widget build(BuildContext context) {
    if (_isLoading) {
      return const Center(child: CircularProgressIndicator());
    }

    if (_errorMessage != null) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(24),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Text(
                _errorMessage!,
                textAlign: TextAlign.center,
                style: const TextStyle(color: Colors.red),
              ),
              const SizedBox(height: 12),
              ElevatedButton.icon(
                onPressed: _loadStatistics,
                icon: const Icon(Icons.refresh),
                label: const Text('Réessayer'),
              ),
            ],
          ),
        ),
      );
    }

    return RefreshIndicator(
      onRefresh: _loadStatistics,
      child: ListView(
        padding: const EdgeInsets.all(16),
        children: [
          _buildFiltersCard(),
          const SizedBox(height: 16),
          _buildSummaryCards(),
          const SizedBox(height: 16),
          _buildByTypeSection(),
          const SizedBox(height: 16),
          _buildTopOptionsSection(),
        ],
      ),
    );
  }

  Widget _buildFiltersCard() {
    final dateFormat = DateFormat('dd/MM/yyyy');

    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Row(
              children: [
                const Icon(Icons.filter_alt, color: AppColors.rouge),
                const SizedBox(width: 8),
                Text(
                  'Filtres',
                  style: Theme.of(context).textTheme.titleMedium?.copyWith(
                        fontWeight: FontWeight.bold,
                      ),
                ),
                const Spacer(),
                ToggleButtons(
                  isSelected: [
                    _amountDisplayMode == _AmountDisplayMode.ht,
                    _amountDisplayMode == _AmountDisplayMode.ttc,
                  ],
                  onPressed: (index) {
                    setState(() {
                      _amountDisplayMode = index == 0
                          ? _AmountDisplayMode.ht
                          : _AmountDisplayMode.ttc;
                    });
                  },
                  children: const [
                    Padding(
                      padding: EdgeInsets.symmetric(horizontal: 8),
                      child: Text('HT'),
                    ),
                    Padding(
                      padding: EdgeInsets.symmetric(horizontal: 8),
                      child: Text('TTC'),
                    ),
                  ],
                ),
                const SizedBox(width: 8),
                TextButton.icon(
                  onPressed: _resetFilters,
                  icon: const Icon(Icons.restart_alt),
                  label: const Text('Réinitialiser'),
                ),
              ],
            ),
            const SizedBox(height: 12),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              crossAxisAlignment: WrapCrossAlignment.center,
              children: [
                OutlinedButton.icon(
                  onPressed: _selectDateRange,
                  icon: const Icon(Icons.date_range),
                  label: Text(
                    '${dateFormat.format(_selectedPeriod.start)} - ${dateFormat.format(_selectedPeriod.end)}',
                  ),
                ),
                ..._DatePreset.values.map(
                  (preset) => ChoiceChip(
                    label: Text(_presetLabel(preset)),
                    selected: _isPresetSelected(preset),
                    onSelected: (_) => _applyDatePreset(preset),
                  ),
                ),
              ],
            ),
            const SizedBox(height: 12),
            const Text(
              'Statuts d\'événements',
              style: TextStyle(fontWeight: FontWeight.w600),
            ),
            const SizedBox(height: 8),
            Wrap(
              spacing: 8,
              runSpacing: 8,
              children: [
                FilterChip(
                  label: const Text('Validés'),
                  selected: _selectedStatuses.contains(EventStatus.confirmed),
                  onSelected: (value) {
                    setState(() {
                      if (value) {
                        _selectedStatuses.add(EventStatus.confirmed);
                      } else {
                        _selectedStatuses.remove(EventStatus.confirmed);
                      }
                    });
                    _rebuildSummary();
                  },
                ),
                FilterChip(
                  label: const Text('En attente'),
                  selected: _selectedStatuses.contains(EventStatus.waitingForApproval),
                  onSelected: (value) {
                    setState(() {
                      if (value) {
                        _selectedStatuses.add(EventStatus.waitingForApproval);
                      } else {
                        _selectedStatuses.remove(EventStatus.waitingForApproval);
                      }
                    });
                    _rebuildSummary();
                  },
                ),
                FilterChip(
                  label: const Text('Annulés'),
                  selected: _selectedStatuses.contains(EventStatus.canceled),
                  onSelected: (value) {
                    setState(() {
                      if (value) {
                        _selectedStatuses.add(EventStatus.canceled);
                      } else {
                        _selectedStatuses.remove(EventStatus.canceled);
                      }
                    });
                    _rebuildSummary();
                  },
                ),
              ],
            ),
            if (_eventTypeNames.isNotEmpty) ...[
              const SizedBox(height: 12),
              const Text(
                'Types d\'événements',
                style: TextStyle(fontWeight: FontWeight.w600),
              ),
              const SizedBox(height: 8),
              Wrap(
                spacing: 8,
                runSpacing: 8,
                children: _eventTypeNames.entries.map((entry) {
                  final selected = _selectedEventTypeIds.contains(entry.key);
                  return FilterChip(
                    label: Text(entry.value),
                    selected: selected,
                    onSelected: (value) {
                      setState(() {
                        if (value) {
                          _selectedEventTypeIds.add(entry.key);
                        } else {
                          _selectedEventTypeIds.remove(entry.key);
                        }
                      });
                      _rebuildSummary();
                    },
                  );
                }).toList(),
              ),
            ],
          ],
        ),
      ),
    );
  }

  Widget _buildSummaryCards() {
    final metrics = <_MetricConfig>[
      _MetricConfig(
        title: 'Total événements',
        value: _summary.totalEvents.toString(),
        subtitle: 'Sur la période sélectionnée',
        icon: Icons.event,
      ),
      _MetricConfig(
        title: 'Montant total',
        value: _formatAmount(_summary.totalAmount),
        subtitle: 'Base + options ($_amountUnitLabel)',
        icon: Icons.account_balance_wallet,
      ),
      _MetricConfig(
        title: 'Montant validé',
        value: _formatAmount(_summary.validatedAmount),
        subtitle: '${_summary.validatedEvents} événement(s) ($_amountUnitLabel)',
        icon: Icons.verified,
      ),
      _MetricConfig(
        title: 'Montant non validé',
        value: _formatAmount(_summary.pendingAmount),
        subtitle: '${_summary.pendingEvents} événement(s) ($_amountUnitLabel)',
        icon: Icons.hourglass_top,
      ),
      _MetricConfig(
        title: 'Montant annulé',
        value: _formatAmount(_summary.canceledAmount),
        subtitle: '${_summary.canceledEvents} événement(s) ($_amountUnitLabel)',
        icon: Icons.cancel,
      ),
      _MetricConfig(
        title: 'Panier moyen',
        value: _formatAmount(_summary.averageAmount),
        subtitle: 'Par événement ($_amountUnitLabel)',
        icon: Icons.trending_up,
      ),
      _MetricConfig(
        title: 'Panier médian',
        value: _formatAmount(_summary.medianAmount),
        subtitle: 'Par événement ($_amountUnitLabel)',
        icon: Icons.timeline,
      ),
      _MetricConfig(
        title: 'Pourcentage de validation',
        value: _formatPercent(_summary.validationRate),
        subtitle:
            '${_summary.validatedEvents} validés sur ${_summary.totalEvents}',
        icon: Icons.pie_chart,
      ),
      _MetricConfig(
        title: 'Base vs options',
        value:
            '${_formatPercent(_summary.baseContributionRate)} / ${_formatPercent(_summary.optionsContributionRate)}',
        subtitle:
            'Base: ${_formatAmount(_summary.baseAmount)} - Options: ${_formatAmount(_summary.optionsAmount)}',
        icon: Icons.stacked_bar_chart,
      ),
    ];

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        Text(
          'KPI période',
          style: Theme.of(context)
              .textTheme
              .titleMedium
              ?.copyWith(fontWeight: FontWeight.bold),
        ),
        const SizedBox(height: 12),
        Wrap(
          spacing: 12,
          runSpacing: 12,
          children: metrics
              .map(
                (metric) => _buildMetricCard(
                  title: metric.title,
                  value: metric.value,
                  subtitle: metric.subtitle,
                  icon: metric.icon,
                ),
              )
              .toList(),
        ),
      ],
    );
  }

  Widget _buildMetricCard({
    required String title,
    required String value,
    required String subtitle,
    required IconData icon,
  }) {
    return SizedBox(
      width: 280,
      child: Card(
        elevation: 1,
        child: Padding(
          padding: const EdgeInsets.all(14),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              Row(
                children: [
                  Icon(icon, color: AppColors.rouge),
                  const SizedBox(width: 8),
                  Expanded(
                    child: Text(
                      title,
                      style: const TextStyle(fontWeight: FontWeight.w600),
                    ),
                  ),
                ],
              ),
              const SizedBox(height: 12),
              Text(
                value,
                style:
                    const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
              ),
              const SizedBox(height: 4),
              Text(
                subtitle,
                style: TextStyle(color: Colors.grey.shade700),
              ),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildByTypeSection() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Répartition par type d\'événement',
              style: Theme.of(context)
                  .textTheme
                  .titleMedium
                  ?.copyWith(fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 12),
            if (_summary.byEventType.isEmpty)
              const Text(
                  'Aucune donnée pour la période et les filtres sélectionnés.')
            else
              SingleChildScrollView(
                scrollDirection: Axis.horizontal,
                child: DataTable(
                  columns: [
                    const DataColumn(label: Text('Type')),
                    const DataColumn(label: Text('Nb')),
                    const DataColumn(label: Text('Validé')),
                    const DataColumn(label: Text('Non validé')),
                    const DataColumn(label: Text('Annulé')),
                    DataColumn(label: Text('Total $_amountUnitLabel')),
                  ],
                  rows: _summary.byEventType
                      .map(
                        (row) => DataRow(
                          cells: [
                            DataCell(Text(row.eventTypeName)),
                            DataCell(Text(row.totalEvents.toString())),
                            DataCell(Text(_formatAmount(row.validatedAmount))),
                            DataCell(Text(_formatAmount(row.pendingAmount))),
                            DataCell(Text(_formatAmount(row.canceledAmount))),
                            DataCell(Text(_formatAmount(row.totalAmount))),
                          ],
                        ),
                      )
                      .toList(),
                ),
              ),
          ],
        ),
      ),
    );
  }

  Widget _buildTopOptionsSection() {
    return Card(
      child: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Text(
              'Top options',
              style: Theme.of(context)
                  .textTheme
                  .titleMedium
                  ?.copyWith(fontWeight: FontWeight.bold),
            ),
            const SizedBox(height: 12),
            if (_summary.topOptions.isEmpty)
              const Text('Aucune option valorisée sur la période sélectionnée.')
            else
              ..._summary.topOptions.map(
                (option) => ListTile(
                  dense: true,
                  contentPadding: EdgeInsets.zero,
                  leading: const Icon(Icons.add_chart, color: AppColors.rouge),
                  title: Text(option.optionLabel),
                  subtitle: Text(
                    'Validées ${option.validatedUsageCount} fois',
                  ),
                  trailing: Text(
                    _formatAmount(option.totalAmount),
                    style: const TextStyle(fontWeight: FontWeight.bold),
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }
}

class _MetricConfig {
  final String title;
  final String value;
  final String subtitle;
  final IconData icon;

  const _MetricConfig({
    required this.title,
    required this.value,
    required this.subtitle,
    required this.icon,
  });
}

