import 'package:equatable/equatable.dart';
import 'compte_adherent_entity.dart';

/// Entité pour les statistiques du dashboard

class DashboardStatsEntity extends Equatable {
  final int totalMembers;
  final int activeMembers;
  final int totalEvents;
  final int upcomingEvents;
  final int totalContributions;
  final double totalContributionAmount;
  /// Montant des cotisations seules (sans épargne), pour la carte « Contribution Totale » membre.
  final double? contributionsAmountOnly;
  final int pendingRequests;
  final int completedProjects;
  final double monthlyGrowth;
  final double engagementRate;
  final DateTime lastUpdated;
  final int? totalOrganizations;
  final Map<String, int>? organizationTypeDistribution;

  const DashboardStatsEntity({
    required this.totalMembers,
    required this.activeMembers,
    required this.totalEvents,
    required this.upcomingEvents,
    required this.totalContributions,
    required this.totalContributionAmount,
    this.contributionsAmountOnly,
    required this.pendingRequests,
    required this.completedProjects,
    required this.monthlyGrowth,
    required this.engagementRate,
    required this.lastUpdated,
    this.totalOrganizations,
    this.organizationTypeDistribution,
  });

  // Méthodes utilitaires
  double get memberActivityRate => totalMembers > 0 ? activeMembers / totalMembers : 0.0;
  bool get hasGrowth => monthlyGrowth > 0;
  bool get isHighEngagement => engagementRate > 0.7;
  
  String get formattedContributionAmount {
    if (totalContributionAmount >= 1000000) {
      return '${(totalContributionAmount / 1000000).toStringAsFixed(1)}M';
    } else if (totalContributionAmount >= 1000) {
      return '${(totalContributionAmount / 1000).toStringAsFixed(1)}K';
    }
    return totalContributionAmount.toStringAsFixed(0);
  }

  @override
  List<Object?> get props => [
        totalMembers,
        activeMembers,
        totalEvents,
        upcomingEvents,
        totalContributions,
        totalContributionAmount,
        contributionsAmountOnly,
        pendingRequests,
        completedProjects,
        monthlyGrowth,
        engagementRate,
        lastUpdated,
        totalOrganizations,
        organizationTypeDistribution,
      ];
}

/// Entité pour les activités récentes
class RecentActivityEntity extends Equatable {
  final String id;
  final String type;
  final String title;
  final String description;
  final String? userAvatar;
  final String userName;
  final DateTime timestamp;
  final String? actionUrl;
  final Map<String, dynamic>? metadata;

  const RecentActivityEntity({
    required this.id,
    required this.type,
    required this.title,
    required this.description,
    this.userAvatar,
    required this.userName,
    required this.timestamp,
    this.actionUrl,
    this.metadata,
  });

  // Méthodes utilitaires
  String get timeAgo {
    final now = DateTime.now();
    final difference = now.difference(timestamp);
    
    if (difference.inDays > 0) {
      return '${difference.inDays}j';
    } else if (difference.inHours > 0) {
      return '${difference.inHours}h';
    } else if (difference.inMinutes > 0) {
      return '${difference.inMinutes}min';
    } else {
      return 'maintenant';
    }
  }

  bool get isRecent => DateTime.now().difference(timestamp).inHours < 24;
  bool get hasAction => actionUrl != null && actionUrl!.isNotEmpty;

  @override
  List<Object?> get props => [
        id,
        type,
        title,
        description,
        userAvatar,
        userName,
        timestamp,
        actionUrl,
        metadata,
      ];
}

/// Entité pour les événements à venir
class UpcomingEventEntity extends Equatable {
  final String id;
  final String title;
  final String description;
  final DateTime startDate;
  final DateTime? endDate;
  final String location;
  final int maxParticipants;
  final int currentParticipants;
  final String status;
  final String? imageUrl;
  final List<String> tags;

  const UpcomingEventEntity({
    required this.id,
    required this.title,
    required this.description,
    required this.startDate,
    this.endDate,
    required this.location,
    required this.maxParticipants,
    required this.currentParticipants,
    required this.status,
    this.imageUrl,
    required this.tags,
  });

  // Méthodes utilitaires
  bool get isAlmostFull => currentParticipants >= (maxParticipants * 0.8);
  bool get isFull => currentParticipants >= maxParticipants;
  double get fillPercentage => maxParticipants > 0 ? currentParticipants / maxParticipants : 0.0;
  
  int get daysUntilEventInt {
    final now = DateTime.now();
    final difference = startDate.difference(now);
    return difference.inDays;
  }

  String get daysUntilEvent {
    final now = DateTime.now();
    final difference = startDate.difference(now);

    if (difference.inDays > 0) {
      return '${difference.inDays} jour${difference.inDays > 1 ? 's' : ''}';
    } else if (difference.inHours > 0) {
      return '${difference.inHours}h';
    } else if (difference.inMinutes > 0) {
      return '${difference.inMinutes}min';
    } else {
      return 'En cours';
    }
  }

  String get formattedDate {
    final months = ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jun',
                    'Jul', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'];
    return '${startDate.day} ${months[startDate.month - 1]} ${startDate.year}';
  }

  bool get hasParticipantInfo => maxParticipants > 0;

  bool get isToday {
    final now = DateTime.now();
    return startDate.year == now.year &&
           startDate.month == now.month &&
           startDate.day == now.day;
  }

  bool get isTomorrow {
    final tomorrow = DateTime.now().add(const Duration(days: 1));
    return startDate.year == tomorrow.year &&
           startDate.month == tomorrow.month &&
           startDate.day == tomorrow.day;
  }

  @override
  List<Object?> get props => [
        id,
        title,
        description,
        startDate,
        endDate,
        location,
        maxParticipants,
        currentParticipants,
        status,
        imageUrl,
        tags,
      ];
}

/// Entité principale du dashboard
class DashboardEntity extends Equatable {
  final DashboardStatsEntity stats;
  final List<RecentActivityEntity> recentActivities;
  final List<UpcomingEventEntity> upcomingEvents;
  final Map<String, dynamic> userPreferences;
  final String organizationId;
  final String userId;
  /// Compte adhérent unifié (si disponible)
  final CompteAdherentEntity? monCompte;

  const DashboardEntity({
    required this.stats,
    required this.recentActivities,
    required this.upcomingEvents,
    required this.userPreferences,
    required this.organizationId,
    required this.userId,
    this.monCompte,
  });

  // Méthodes utilitaires
  bool get hasRecentActivity => recentActivities.isNotEmpty;
  bool get hasUpcomingEvents => upcomingEvents.isNotEmpty;
  int get todayEventsCount => upcomingEvents.where((e) => e.isToday).length;
  int get tomorrowEventsCount => upcomingEvents.where((e) => e.isTomorrow).length;
  int get recentActivitiesCount => recentActivities.length;

  @override
  List<Object?> get props => [
        stats,
        recentActivities,
        upcomingEvents,
        userPreferences,
        organizationId,
        userId,
        monCompte,
      ];
}

