import 'package:flutter/material.dart';
import 'package:flutter/foundation.dart' show listEquals;
import 'package:syncfusion_flutter_charts/charts.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';

/// Modèle de données pour le graphique en camembert des passages
class PassageChartData {
  final int typeId;
  final int count;
  final String title;
  final Color color;
  final IconData icon;

  PassageChartData({
    required this.typeId,
    required this.count,
    required this.title,
    required this.color,
    required this.icon,
  });
}

/// Widget commun pour afficher une carte de synthèse des passages
/// avec liste des types à gauche et graphique en camembert à droite
class PassageSummaryCard 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 passages (admin) ou seulement ceux de l'utilisateur
  final bool showAllPassages;

  /// Types de passages à exclure du graphique
  final List<int> excludePassageTypes;

  /// Données statiques de passages par type (utilisé si useValueListenable = false)
  final Map<int, int>? passagesByType;

  /// Fonction de callback pour afficher la valeur totale personnalisée
  final String Function(int totalPassages)? 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 PassageSummaryCard({
    super.key,
    required this.title,
    this.titleColor = AppTheme.primaryColor,
    this.titleIcon = Icons.route,
    this.height,
    this.useValueListenable = true,
    this.userId,
    this.showAllPassages = false,
    this.excludePassageTypes = const [2], // Exclure "À finaliser" par défaut
    this.passagesByType,
    this.customTotalDisplay,
    this.isDesktop = true,
    this.backgroundIcon = Icons.route,
    this.backgroundIconColor,
    this.backgroundIconOpacity = 0.07,
    this.backgroundIconSize = 180,
  });

  @override
  State<PassageSummaryCard> createState() => _PassageSummaryCardState();
}

class _PassageSummaryCardState extends State<PassageSummaryCard>
    with SingleTickerProviderStateMixin {
  late AnimationController _animationController;

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

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

    // Relancer l'animation si les paramètres importants ont changé
    final bool shouldResetAnimation = oldWidget.userId != widget.userId ||
        !listEquals(
            oldWidget.excludePassageTypes, widget.excludePassageTypes) ||
        oldWidget.showAllPassages != widget.showAllPassages ||
        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 passagesCounts = _calculatePassagesCounts(passagesBox);
          final totalUserPassages = passagesCounts.values.fold(0, (sum, count) => sum + count);

          return _buildCardContent(
            context,
            totalUserPassages: totalUserPassages,
            passagesCounts: passagesCounts,
          );
        },
      );
    } else {
      // Données statiques
      final totalPassages = widget.passagesByType?.values.fold(0, (sum, count) => sum + count) ?? 0;
      return _buildCardContent(
        context,
        totalUserPassages: totalPassages,
        passagesCounts: widget.passagesByType ?? {},
      );
    }
  }

  /// Construit le contenu de la card avec les données calculées
  Widget _buildCardContent(
    BuildContext context, {
    required int totalUserPassages,
    required Map<int, int> passagesCounts,
  }) {
    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 ?? AppTheme.primaryColor)
                      .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, totalUserPassages),
                const Divider(height: 24),
                // Contenu principal
                Expanded(
                  child: SizedBox(
                    child: Row(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      children: [
                        // Liste des passages à gauche
                        Expanded(
                          flex: widget.isDesktop ? 1 : 2,
                          child: _buildPassagesList(context, passagesCounts),
                        ),

                        // 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(passagesCounts),
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          ),
        ],
      ),
    );
  }

  /// Construction du titre
  Widget _buildTitle(BuildContext context, int totalUserPassages) {
    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(totalUserPassages) ??
              totalUserPassages.toString(),
          style: TextStyle(
            fontSize: AppTheme.r(context, 20),
            fontWeight: FontWeight.bold,
            color: widget.titleColor,
          ),
        ),
      ],
    );
  }

  /// Gérer le clic sur un type de passage
  void _handlePassageTypeClick(int typeId) {
    // Réinitialiser TOUS les filtres avant de sauvegarder le nouveau
    final settingsBox = Hive.box(AppKeys.settingsBoxName);
    settingsBox.delete('history_selectedPaymentTypeId');
    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 passage sélectionné
    settingsBox.put('history_selectedTypeId', 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 passages (avec clics)
  Widget _buildPassagesList(BuildContext context, Map<int, int> passagesCounts) {
    // Vérifier si le type Lot doit être affiché
    bool showLotType = true;
    final currentUser = userRepository.getCurrentUser();
    if (currentUser != null && currentUser.fkEntite != null) {
      final userAmicale = amicaleRepository.getAmicaleById(currentUser.fkEntite!);
      if (userAmicale != null) {
        showLotType = userAmicale.chkLotActif;
      }
    }

    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: [
        ...AppKeys.typesPassages.entries.where((entry) {
          // Exclure le type Lot (5) si chkLotActif = false
          if (entry.key == 5 && !showLotType) {
            return false;
          }
          return true;
        }).map((entry) {
          final int typeId = entry.key;
          final Map<String, dynamic> typeData = entry.value;
          final int count = passagesCounts[typeId] ?? 0;
          final Color color = Color(typeData['couleur2'] as int);
          final IconData iconData = typeData['icon_data'] as IconData;

          return Padding(
            padding: const EdgeInsets.only(bottom: 8.0),
            child: InkWell(
              onTap: () => _handlePassageTypeClick(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['titres'] as String,
                        style: TextStyle(fontSize: AppTheme.r(context, 14)),
                      ),
                    ),
                    Text(
                      count.toString(),
                      style: TextStyle(
                        fontSize: AppTheme.r(context, 16),
                        fontWeight: FontWeight.bold,
                        color: color,
                      ),
                    ),
                  ],
                ),
              ),
            ),
          );
        }),
      ],
    );
  }

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

    // 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];
              _handlePassageTypeClick(selectedData.typeId);
            }
          },
          series: <CircularSeries>[
            DoughnutSeries<PassageChartData, String>(
              dataSource: chartData,
              xValueMapper: (PassageChartData data, _) => data.title,
              yValueMapper: (PassageChartData data, _) => data.count,
              pointColorMapper: (PassageChartData data, _) => data.color,
              enableTooltip: true,
              selectionBehavior: SelectionBehavior(
                enable: true,
                selectedColor: null, // Garde la couleur d'origine
                unselectedOpacity: 0.5,
              ),
              dataLabelMapper: (PassageChartData data, _) {
                // Calculer le pourcentage avec une décimale
                final total = chartData.fold(0, (sum, item) => sum + item.count);
                final percentage = (data.count / total * 100);
                return '${percentage.toStringAsFixed(1)}%';
              },
              dataLabelSettings: DataLabelSettings(
                isVisible: true,
                labelPosition: ChartDataLabelPosition.outside,
                textStyle: const TextStyle(fontSize: 12),
                connectorLineSettings: const ConnectorLineSettings(
                  type: ConnectorType.curve,
                  length: '15%',
                ),
              ),
              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 compteurs de passages par type
  Map<int, int> _calculatePassagesCounts(Box<PassageModel> passagesBox) {
    final Map<int, int> counts = {};

    // Vérifier si le type Lot doit être affiché
    bool showLotType = true;
    final currentUser = userRepository.getCurrentUser();
    if (currentUser != null && currentUser.fkEntite != null) {
      final userAmicale = amicaleRepository.getAmicaleById(currentUser.fkEntite!);
      if (userAmicale != null) {
        showLotType = userAmicale.chkLotActif;
      }
    }

    // Initialiser tous les types
    for (final typeId in AppKeys.typesPassages.keys) {
      // Exclure le type Lot (5) si chkLotActif = false
      if (typeId == 5 && !showLotType) {
        continue;
      }
      // Exclure les types non désirés
      if (widget.excludePassageTypes.contains(typeId)) {
        continue;
      }
      counts[typeId] = 0;
    }

    // L'API filtre déjà les passages côté serveur
    // On compte simplement tous les passages de la box
    for (final passage in passagesBox.values) {
      // Exclure le type Lot (5) si chkLotActif = false
      if (passage.fkType == 5 && !showLotType) {
        continue;
      }
      // Exclure les types non désirés
      if (widget.excludePassageTypes.contains(passage.fkType)) {
        continue;
      }
      counts[passage.fkType] = (counts[passage.fkType] ?? 0) + 1;
    }

    return counts;
  }

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

    // Vérifier si le type Lot doit être affiché
    bool showLotType = true;
    final currentUser = CurrentUserService.instance.currentUser;
    if (currentUser != null && currentUser.fkEntite != null) {
      final userAmicale = amicaleRepository.getAmicaleById(currentUser.fkEntite!);
      if (userAmicale != null) {
        showLotType = userAmicale.chkLotActif;
      }
    }

    // Créer les données du graphique
    passagesByType.forEach((typeId, count) {
      // Exclure le type Lot (5) si chkLotActif = false
      if (typeId == 5 && !showLotType) {
        return; // Skip ce type
      }

      // Vérifier que le type existe et que le compteur est positif
      if (count > 0 && AppKeys.typesPassages.containsKey(typeId)) {
        final typeInfo = AppKeys.typesPassages[typeId]!;

        chartData.add(PassageChartData(
          typeId: typeId,
          count: count,
          title: typeInfo['titre'] as String,
          color: Color(typeInfo['couleur2'] as int),
          icon: typeInfo['icon_data'] as IconData,
        ));
      }
    });

    return chartData;
  }
}
