import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:geosector_app/presentation/widgets/charts/payment_data.dart';
import 'package:geosector_app/core/constants/app_keys.dart';
import 'package:geosector_app/core/theme/app_theme.dart';
import 'package:geosector_app/core/services/current_user_service.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:geosector_app/core/data/models/passage_model.dart';
import 'package:geosector_app/app.dart';
import 'package:go_router/go_router.dart';

/// Widget commun pour afficher une carte de synthèse des règlements
/// avec liste des types à gauche et graphique en camembert à droite
class PaymentSummaryCard extends StatefulWidget {
  /// Titre de la carte
  final String title;

  /// Couleur de l'icône et du titre
  final Color titleColor;

  /// Icône à afficher dans le titre
  final IconData? titleIcon;

  /// Hauteur totale de la carte
  final double? height;

  /// Utiliser ValueListenableBuilder pour mise à jour automatique
  final bool useValueListenable;

  /// ID de l'utilisateur pour filtrer les passages (si null, tous les utilisateurs)
  final int? userId;

  /// Afficher tous les règlements (admin) ou seulement ceux de l'utilisateur
  final bool showAllPayments;

  /// Données statiques de règlements par type (utilisé si useValueListenable = false)
  final Map<int, double>? paymentsByType;

  /// Fonction de callback pour afficher la valeur totale personnalisée
  final String Function(double totalAmount)? customTotalDisplay;

  /// Afficher le graphique en mode desktop ou mobile
  final bool isDesktop;

  /// Icône d'arrière-plan (optionnelle)
  final IconData? backgroundIcon;

  /// Couleur de l'icône d'arrière-plan
  final Color? backgroundIconColor;

  /// Opacité de l'icône d'arrière-plan
  final double backgroundIconOpacity;

  /// Taille de l'icône d'arrière-plan
  final double backgroundIconSize;

  const PaymentSummaryCard({
    super.key,
    required this.title,
    this.titleColor = AppTheme.accentColor,
    this.titleIcon = Icons.payments,
    this.height,
    this.useValueListenable = true,
    this.userId,
    this.showAllPayments = false,
    this.paymentsByType,
    this.customTotalDisplay,
    this.isDesktop = true,
    this.backgroundIcon = Icons.euro_symbol,
    this.backgroundIconColor,
    this.backgroundIconOpacity = 0.07,
    this.backgroundIconSize = 180,
  });

  @override
  State<PaymentSummaryCard> createState() => _PaymentSummaryCardState();
}

class _PaymentSummaryCardState extends State<PaymentSummaryCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;

  @override
  void initState() {
    super.initState();
    _animationController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 2000),
    );
    _animationController.forward();
  }

  @override
  void didUpdateWidget(PaymentSummaryCard oldWidget) {
    super.didUpdateWidget(oldWidget);

    // Relancer l'animation si les paramètres importants ont changé
    final bool shouldResetAnimation = oldWidget.userId != widget.userId ||
        oldWidget.showAllPayments != widget.showAllPayments ||
        oldWidget.useValueListenable != widget.useValueListenable;

    if (shouldResetAnimation) {
      _animationController.reset();
      _animationController.forward();
    }
  }

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

  @override
  Widget build(BuildContext context) {
    // Si useValueListenable, construire avec ValueListenableBuilder centralisé
    if (widget.useValueListenable) {
      return ValueListenableBuilder(
        valueListenable: Hive.box<PassageModel>(AppKeys.passagesBoxName).listenable(),
        builder: (context, Box<PassageModel> passagesBox, child) {
          // Calculer les données une seule fois
          final paymentAmounts = _calculatePaymentAmounts(passagesBox);
          final totalAmount = paymentAmounts.values.fold(0.0, (sum, amount) => sum + amount);

          return _buildCardContent(
            context,
            totalAmount: totalAmount,
            paymentAmounts: paymentAmounts,
          );
        },
      );
    } else {
      // Données statiques
      final totalAmount = widget.paymentsByType?.values.fold(0.0, (sum, amount) => sum + amount) ?? 0.0;
      return _buildCardContent(
        context,
        totalAmount: totalAmount,
        paymentAmounts: widget.paymentsByType ?? {},
      );
    }
  }

  /// Construit le contenu de la card avec les données calculées
  Widget _buildCardContent(
    BuildContext context, {
    required double totalAmount,
    required Map<int, double> paymentAmounts,
  }) {
    return Card(
      elevation: 4,
      shape: RoundedRectangleBorder(
        borderRadius: BorderRadius.circular(16),
      ),
      child: Stack(
        children: [
          // Icône d'arrière-plan (optionnelle)
          if (widget.backgroundIcon != null)
            Positioned.fill(
              child: Center(
                child: Icon(
                  widget.backgroundIcon,
                  size: widget.backgroundIconSize,
                  color: (widget.backgroundIconColor ?? Colors.blue)
                      .withOpacity(widget.backgroundIconOpacity),
                ),
              ),
            ),
          // Contenu principal
          Container(
            height: widget.height,
            padding: const EdgeInsets.fromLTRB(16.0, 12.0, 16.0, 8.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                // Titre avec comptage
                _buildTitle(context, totalAmount),
                const Divider(height: 24),
                // Contenu principal
                Expanded(
                  child: SizedBox(
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        // Liste des règlements à gauche
                        Expanded(
                          flex: widget.isDesktop ? 1 : 2,
                          child: _buildPaymentsList(context, paymentAmounts),
                        ),

                        // Séparateur vertical
                        if (widget.isDesktop) const VerticalDivider(width: 24),

                        // Graphique en camembert à droite
                        Expanded(
                          flex: widget.isDesktop ? 1 : 2,
                          child: Padding(
                            padding: const EdgeInsets.all(8.0),
                            child: _buildPieChart(paymentAmounts),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  /// Construction du titre
  Widget _buildTitle(BuildContext context, double totalAmount) {
    return Row(
      children: [
        if (widget.titleIcon != null) ...[
          Icon(
            widget.titleIcon,
            color: widget.titleColor,
            size: 24,
          ),
          const SizedBox(width: 8),
        ],
        Expanded(
          child: Text(
            widget.title,
            style: TextStyle(
              fontSize: AppTheme.r(context, 16),
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
        Text(
          widget.customTotalDisplay?.call(totalAmount) ??
              '${totalAmount.toStringAsFixed(2)} €',
          style: TextStyle(
            fontSize: AppTheme.r(context, 20),
            fontWeight: FontWeight.bold,
            color: widget.titleColor,
          ),
        ),
      ],
    );
  }

  /// Gérer le clic sur un type de règlement
  void _handlePaymentTypeClick(int typeId) {
    // Réinitialiser TOUS les filtres avant de sauvegarder le nouveau
    final settingsBox = Hive.box(AppKeys.settingsBoxName);
    settingsBox.delete('history_selectedTypeId');
    settingsBox.delete('history_selectedSectorId');
    settingsBox.delete('history_selectedSectorName');
    settingsBox.delete('history_selectedMemberId');
    settingsBox.delete('history_startDate');
    settingsBox.delete('history_endDate');

    // Sauvegarder uniquement le type de règlement sélectionné
    settingsBox.put('history_selectedPaymentTypeId', typeId);

    // Naviguer directement vers la page historique
    final bool isAdmin = CurrentUserService.instance.shouldShowAdminUI;
    context.go(isAdmin ? '/admin/history' : '/user/history');
  }

  /// Construction de la liste des règlements (avec clics)
  Widget _buildPaymentsList(BuildContext context, Map<int, double> paymentAmounts) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        ...AppKeys.typesReglements.entries.map((entry) {
          final int typeId = entry.key;
          final Map<String, dynamic> typeData = entry.value;
          final double amount = paymentAmounts[typeId] ?? 0.0;
          final Color color = Color(typeData['couleur'] as int);
          final IconData iconData = typeData['icon_data'] as IconData;

          return Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: InkWell(
              onTap: () => _handlePaymentTypeClick(typeId),
              borderRadius: BorderRadius.circular(8),
              child: Padding(
                padding: const EdgeInsets.symmetric(vertical: 4.0, horizontal: 4.0),
                child: Row(
                  children: [
                    Container(
                      width: 24,
                      height: 24,
                      decoration: BoxDecoration(
                        color: color,
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        iconData,
                        color: Colors.white,
                        size: 16,
                      ),
                    ),
                    const SizedBox(width: 8),
                    Expanded(
                      child: Text(
                        typeData['titre'] as String,
                        style: TextStyle(fontSize: AppTheme.r(context, 14)),
                      ),
                    ),
                    Text(
                      '${amount.toStringAsFixed(2)} €',
                      style: TextStyle(
                        fontSize: AppTheme.r(context, 16),
                        fontWeight: FontWeight.bold,
                        color: color,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        }),
      ],
    );
  }

  /// Construction du graphique en camembert (avec clics)
  Widget _buildPieChart(Map<int, double> paymentAmounts) {
    final chartData = _prepareChartDataFromMap(paymentAmounts);

    // Si aucune donnée, afficher un message
    if (chartData.isEmpty) {
      return const Center(
        child: Text('Aucune donnée disponible'),
      );
    }

    // Créer des animations
    final progressAnimation = CurvedAnimation(
      parent: _animationController,
      curve: Curves.easeOutCubic,
    );

    final explodeAnimation = CurvedAnimation(
      parent: _animationController,
      curve: const Interval(0.7, 1.0, curve: Curves.elasticOut),
    );

    final opacityAnimation = CurvedAnimation(
      parent: _animationController,
      curve: const Interval(0.1, 0.5, curve: Curves.easeIn),
    );

    return AnimatedBuilder(
      animation: _animationController,
      builder: (context, child) {
        return SfCircularChart(
          margin: EdgeInsets.zero,
          legend: Legend(
            isVisible: false,
            position: LegendPosition.bottom,
            overflowMode: LegendItemOverflowMode.wrap,
            textStyle: const TextStyle(fontSize: 12),
          ),
          tooltipBehavior: TooltipBehavior(enable: true),
          onSelectionChanged: (SelectionArgs args) {
            // Gérer le clic sur un segment du graphique
            final pointIndex = args.pointIndex;
            if (pointIndex < chartData.length) {
              final selectedData = chartData[pointIndex];
              _handlePaymentTypeClick(selectedData.typeId);
            }
          },
          series: <CircularSeries>[
            DoughnutSeries<PaymentData, String>(
              dataSource: chartData,
              xValueMapper: (PaymentData data, _) => data.title,
              yValueMapper: (PaymentData data, _) => data.amount,
              pointColorMapper: (PaymentData data, _) => data.color,
              enableTooltip: true,
              selectionBehavior: SelectionBehavior(
                enable: true,
                selectedColor: null, // Garde la couleur d'origine
                unselectedOpacity: 0.5,
              ),
              dataLabelMapper: (PaymentData data, _) {
                // Calculer le pourcentage avec une décimale
                final total = chartData.fold(0.0, (sum, item) => sum + item.amount);
                final percentage = (data.amount / total * 100);
                return '${percentage.toStringAsFixed(1)}%';
              },
              dataLabelSettings: DataLabelSettings(
                isVisible: true,
                labelPosition: ChartDataLabelPosition.inside,
                textStyle: const TextStyle(
                  fontSize: 12,
                  color: Colors.white,
                  fontWeight: FontWeight.bold,
                ),
              ),
              innerRadius: '50%',
              explode: true,
              explodeIndex: 0,
              explodeOffset: '${(5 * explodeAnimation.value).toStringAsFixed(1)}%',
              opacity: opacityAnimation.value,
              animationDuration: 0,
              startAngle: 270,
              endAngle: 270 + (360 * progressAnimation.value).toInt(),
            ),
          ],
        );
      },
    );
  }

  /// Calcule les montants par type de règlement
  Map<int, double> _calculatePaymentAmounts(Box<PassageModel> passagesBox) {
    final Map<int, double> paymentAmounts = {};

    // Initialiser tous les types
    for (final typeId in AppKeys.typesReglements.keys) {
      paymentAmounts[typeId] = 0.0;
    }

    // En mode user, filtrer uniquement les passages créés par l'utilisateur (fkUser)
    final currentUser = userRepository.getCurrentUser();
    final int? filterUserId = widget.showAllPayments ? null : currentUser?.opeUserId;

    for (final passage in passagesBox.values) {
      // En mode user, ne compter que les passages de l'utilisateur (comparer avec ope_users.id)
      if (filterUserId != null && passage.fkUser != filterUserId) {
        continue;
      }

      final int typeReglement = passage.fkTypeReglement;

      // Convertir la chaîne de montant en double
      double montant = 0.0;
      try {
        String montantStr = passage.montant.replaceAll(',', '.');
        montant = double.tryParse(montantStr) ?? 0.0;
      } catch (e) {
        // Ignorer les erreurs de conversion
      }

      if (montant > 0) {
        if (paymentAmounts.containsKey(typeReglement)) {
          paymentAmounts[typeReglement] =
              (paymentAmounts[typeReglement] ?? 0.0) + montant;
        } else {
          paymentAmounts[0] = (paymentAmounts[0] ?? 0.0) + montant;
        }
      }
    }

    return paymentAmounts;
  }

  /// Prépare les données pour le graphique en camembert à partir d'une Map
  List<PaymentData> _prepareChartDataFromMap(Map<int, double> paymentsMap) {
    final List<PaymentData> paymentDataList = [];

    paymentsMap.forEach((typeReglement, montant) {
      if (montant > 0) {
        // Ne retourner que les types avec un montant > 0
        // Récupérer les informations depuis AppKeys.typesReglements
        final reglementInfo = AppKeys.typesReglements[typeReglement];

        if (reglementInfo != null) {
          paymentDataList.add(PaymentData(
            typeId: typeReglement,
            title: reglementInfo['titre'] as String,
            amount: montant,
            color: Color(reglementInfo['couleur'] as int),
            icon: reglementInfo['icon_data'] as IconData,
          ));
        } else {
          // Fallback pour les types non définis
          paymentDataList.add(PaymentData(
            typeId: typeReglement,
            title: 'Type inconnu',
            amount: montant,
            color: Colors.grey,
            icon: Icons.help_outline,
          ));
        }
      }
    });

    return paymentDataList;
  }
}
