/// États pour le BLoC des organisations
library organizations_state;

import 'package:equatable/equatable.dart';
import '../data/models/organization_model.dart';

/// Classe de base pour tous les états des organisations
abstract class OrganizationsState extends Equatable {
  const OrganizationsState();

  @override
  List<Object?> get props => [];
}

/// État initial
class OrganizationsInitial extends OrganizationsState {
  const OrganizationsInitial();
}

/// État de chargement
class OrganizationsLoading extends OrganizationsState {
  const OrganizationsLoading();
}

/// État de chargement de plus d'éléments (pagination)
class OrganizationsLoadingMore extends OrganizationsState {
  final List<OrganizationModel> currentOrganizations;

  const OrganizationsLoadingMore(this.currentOrganizations);

  @override
  List<Object?> get props => [currentOrganizations];
}

/// État de succès avec données
class OrganizationsLoaded extends OrganizationsState {
  final List<OrganizationModel> organizations;
  final List<OrganizationModel> filteredOrganizations;
  final bool hasReachedMax;
  final int currentPage;
  final String? currentSearch;
  final StatutOrganization? statusFilter;
  final TypeOrganization? typeFilter;
  final OrganizationSortType? sortType;
  final bool sortAscending;
  final Map<String, dynamic>? stats;
  /// Filtre appliqué (ex. orgAdmin : uniquement ses organisations)
  final List<String>? filterOrganizationIds;
  /// True si la liste provient de GET /mes (admin d'organisation)
  final bool useMesOnly;

  const OrganizationsLoaded({
    required this.organizations,
    required this.filteredOrganizations,
    this.hasReachedMax = false,
    this.currentPage = 0,
    this.currentSearch,
    this.statusFilter,
    this.typeFilter,
    this.sortType,
    this.sortAscending = true,
    this.stats,
    this.filterOrganizationIds,
    this.useMesOnly = false,
  });

  /// Copie avec modifications
  OrganizationsLoaded copyWith({
    List<OrganizationModel>? organizations,
    List<OrganizationModel>? filteredOrganizations,
    bool? hasReachedMax,
    int? currentPage,
    String? currentSearch,
    StatutOrganization? statusFilter,
    TypeOrganization? typeFilter,
    OrganizationSortType? sortType,
    bool? sortAscending,
    Map<String, dynamic>? stats,
    List<String>? filterOrganizationIds,
    bool? useMesOnly,
    bool clearSearch = false,
    bool clearStatusFilter = false,
    bool clearTypeFilter = false,
    bool clearSort = false,
  }) {
    return OrganizationsLoaded(
      organizations: organizations ?? this.organizations,
      filteredOrganizations: filteredOrganizations ?? this.filteredOrganizations,
      hasReachedMax: hasReachedMax ?? this.hasReachedMax,
      currentPage: currentPage ?? this.currentPage,
      currentSearch: clearSearch ? null : (currentSearch ?? this.currentSearch),
      statusFilter: clearStatusFilter ? null : (statusFilter ?? this.statusFilter),
      typeFilter: clearTypeFilter ? null : (typeFilter ?? this.typeFilter),
      sortType: clearSort ? null : (sortType ?? this.sortType),
      sortAscending: sortAscending ?? this.sortAscending,
      stats: stats ?? this.stats,
      filterOrganizationIds: filterOrganizationIds ?? this.filterOrganizationIds,
      useMesOnly: useMesOnly ?? this.useMesOnly,
    );
  }

  /// Nombre total d'organisations
  int get totalCount => organizations.length;

  /// Nombre d'organisations filtrées
  int get filteredCount => filteredOrganizations.length;

  /// Indique si des filtres sont appliqués
  bool get hasFilters =>
      currentSearch?.isNotEmpty == true ||
      statusFilter != null ||
      typeFilter != null;

  /// Indique si un tri est appliqué
  bool get hasSorting => sortType != null;

  /// Statistiques rapides
  Map<String, int> get quickStats {
    final actives = organizations.where((org) => org.statut == StatutOrganization.active).length;
    final inactives = organizations.length - actives;
    final totalMembres = organizations.fold<int>(0, (sum, org) => sum + org.nombreMembres);

    return {
      'total': organizations.length,
      'actives': actives,
      'inactives': inactives,
      'totalMembres': totalMembres,
    };
  }

  @override
  List<Object?> get props => [
        organizations,
        filteredOrganizations,
        hasReachedMax,
        currentPage,
        currentSearch,
        statusFilter,
        typeFilter,
        sortType,
        sortAscending,
        stats,
        filterOrganizationIds,
        useMesOnly,
      ];
}

/// État d'erreur
class OrganizationsError extends OrganizationsState {
  final String message;
  final String? details;
  final List<OrganizationModel>? previousOrganizations;

  const OrganizationsError(
    this.message, {
    this.details,
    this.previousOrganizations,
  });

  @override
  List<Object?> get props => [message, details, previousOrganizations];
}

/// État de chargement d'une organisation spécifique
class OrganizationLoading extends OrganizationsState {
  final String id;

  const OrganizationLoading(this.id);

  @override
  List<Object?> get props => [id];
}

/// État d'organisation chargée
class OrganizationLoaded extends OrganizationsState {
  final OrganizationModel organization;

  const OrganizationLoaded(this.organization);

  @override
  List<Object?> get props => [organization];
}

/// État d'erreur pour une organisation spécifique
class OrganizationError extends OrganizationsState {
  final String message;
  final String? organizationId;

  const OrganizationError(this.message, {this.organizationId});

  @override
  List<Object?> get props => [message, organizationId];
}

/// État de création d'organisation
class OrganizationCreating extends OrganizationsState {
  const OrganizationCreating();
}

/// État de succès de création
class OrganizationCreated extends OrganizationsState {
  final OrganizationModel organization;

  const OrganizationCreated(this.organization);

  @override
  List<Object?> get props => [organization];
}

/// État de mise à jour d'organisation
class OrganizationUpdating extends OrganizationsState {
  final String id;

  const OrganizationUpdating(this.id);

  @override
  List<Object?> get props => [id];
}

/// État de succès de mise à jour
class OrganizationUpdated extends OrganizationsState {
  final OrganizationModel organization;

  const OrganizationUpdated(this.organization);

  @override
  List<Object?> get props => [organization];
}

/// État de suppression d'organisation
class OrganizationDeleting extends OrganizationsState {
  final String id;

  const OrganizationDeleting(this.id);

  @override
  List<Object?> get props => [id];
}

/// État de succès de suppression
class OrganizationDeleted extends OrganizationsState {
  final String id;

  const OrganizationDeleted(this.id);

  @override
  List<Object?> get props => [id];
}

/// État d'activation d'organisation
class OrganizationActivating extends OrganizationsState {
  final String id;

  const OrganizationActivating(this.id);

  @override
  List<Object?> get props => [id];
}

/// État de succès d'activation
class OrganizationActivated extends OrganizationsState {
  final OrganizationModel organization;

  const OrganizationActivated(this.organization);

  @override
  List<Object?> get props => [organization];
}

/// État de suspension d'organisation
class OrganizationSuspending extends OrganizationsState {
  final String id;

  const OrganizationSuspending(this.id);

  @override
  List<Object?> get props => [id];
}

/// État de succès de suspension
class OrganizationSuspended extends OrganizationsState {
  final OrganizationModel organization;

  const OrganizationSuspended(this.organization);

  @override
  List<Object?> get props => [organization];
}

/// État de chargement des statistiques
class OrganizationsStatsLoading extends OrganizationsState {
  const OrganizationsStatsLoading();
}

/// État des statistiques chargées
class OrganizationsStatsLoaded extends OrganizationsState {
  final Map<String, dynamic> stats;

  const OrganizationsStatsLoaded(this.stats);

  @override
  List<Object?> get props => [stats];
}

/// État d'erreur des statistiques
class OrganizationsStatsError extends OrganizationsState {
  final String message;

  const OrganizationsStatsError(this.message);

  @override
  List<Object?> get props => [message];
}
