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

part 'dashboard_stats_model.g.dart';

/// Modèle pour les statistiques du dashboard
@JsonSerializable()
class DashboardStatsModel extends Equatable {
  final int totalMembers;
  final int activeMembers;
  final int totalEvents;
  final int upcomingEvents;
  final int totalContributions;
  final double totalContributionAmount;
  final int pendingRequests;
  final int completedProjects;
  final double monthlyGrowth;
  final double engagementRate;
  final DateTime lastUpdated;
  final int? totalOrganizations;
  final Map<String, int>? organizationTypeDistribution;

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

  factory DashboardStatsModel.fromJson(Map<String, dynamic> json) =>
      _$DashboardStatsModelFromJson(json);

  Map<String, dynamic> toJson() => _$DashboardStatsModelToJson(this);

  // Getters calculés
  String get formattedContributionAmount {
    return '${totalContributionAmount.toStringAsFixed(2)} €';
  }

  bool get hasGrowth => monthlyGrowth > 0;

  bool get isHighEngagement => engagementRate > 0.7;

  double get activeMemberPercentage {
    return totalMembers > 0 ? (activeMembers / totalMembers) : 0.0;
  }

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

/// Modèle pour les activités récentes
@JsonSerializable()
class RecentActivityModel 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 RecentActivityModel({
    required this.id,
    required this.type,
    required this.title,
    required this.description,
    this.userAvatar,
    required this.userName,
    required this.timestamp,
    this.actionUrl,
    this.metadata,
  });

  factory RecentActivityModel.fromJson(Map<String, dynamic> json) =>
      _$RecentActivityModelFromJson(json);

  Map<String, dynamic> toJson() => _$RecentActivityModelToJson(this);

  // Getter calculé pour l'affichage du temps
  String get timeAgo {
    final now = DateTime.now();
    final difference = now.difference(timestamp);

    if (difference.inDays > 0) {
      return 'il y a ${difference.inDays} jour${difference.inDays > 1 ? 's' : ''}';
    } else if (difference.inHours > 0) {
      return 'il y a ${difference.inHours} heure${difference.inHours > 1 ? 's' : ''}';
    } else if (difference.inMinutes > 0) {
      return 'il y a ${difference.inMinutes} minute${difference.inMinutes > 1 ? 's' : ''}';
    } else {
      return 'à l\'instant';
    }
  }

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

/// Modèle pour les événements à venir
@JsonSerializable()
class UpcomingEventModel 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 UpcomingEventModel({
    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,
  });

  factory UpcomingEventModel.fromJson(Map<String, dynamic> json) =>
      _$UpcomingEventModelFromJson(json);

  Map<String, dynamic> toJson() => _$UpcomingEventModelToJson(this);

  bool get isAlmostFull => currentParticipants >= (maxParticipants * 0.8);
  bool get isFull => currentParticipants >= maxParticipants;
  double get fillPercentage => maxParticipants > 0 ? currentParticipants / maxParticipants : 0.0;

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

/// Modèle pour les données du dashboard complet
@JsonSerializable()
class DashboardDataModel extends Equatable {
  final DashboardStatsModel stats;
  final List<RecentActivityModel> recentActivities;
  final List<UpcomingEventModel> upcomingEvents;
  final Map<String, dynamic> userPreferences;
  final String organizationId;
  final String userId;

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

  factory DashboardDataModel.fromJson(Map<String, dynamic> json) =>
      _$DashboardDataModelFromJson(json);

  Map<String, dynamic> toJson() => _$DashboardDataModelToJson(this);

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