/// Wrapper BLoC pour la page des membres
/// 
/// Ce fichier enveloppe la MembersPage existante avec le MembresBloc
/// pour connecter l'UI riche existante à l'API backend réelle.
library members_page_wrapper;

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:get_it/get_it.dart';

import '../../../../shared/design_system/tokens/color_tokens.dart';
import '../../../../shared/widgets/error_widget.dart';
import '../../../../shared/widgets/loading_widget.dart';
import '../../../../core/utils/logger.dart';
import '../../bloc/membres_bloc.dart';
import '../../bloc/membres_event.dart';
import '../../bloc/membres_state.dart';
import '../../data/models/membre_complete_model.dart';
import '../widgets/add_member_dialog.dart' show showAddMemberSheet, showCredentialsDialog;
import 'members_page_connected.dart';

final _getIt = GetIt.instance;

/// Wrapper qui fournit le BLoC à la page des membres
class MembersPageWrapper extends StatelessWidget {
  final String? organisationId;

  const MembersPageWrapper({super.key, this.organisationId});

  @override
  Widget build(BuildContext context) {
    AppLogger.info('MembersPageWrapper: Création du BlocProvider');

    return BlocProvider<MembresBloc>(
      create: (context) {
        AppLogger.info('MembresPageWrapper: Initialisation du MembresBloc');
        final bloc = _getIt<MembresBloc>();
        // Charger les membres au démarrage
        bloc.add(LoadMembres(organisationId: organisationId));
        return bloc;
      },
      child: MembersPageConnected(organisationId: organisationId),
    );
  }
}

/// Page des membres connectée au BLoC
///
/// Cette page gère les états du BLoC et affiche l'UI appropriée
class MembersPageConnected extends StatelessWidget {
  final String? organisationId;

  const MembersPageConnected({super.key, this.organisationId});

  @override
  Widget build(BuildContext context) {
    return BlocListener<MembresBloc, MembresState>(
      listener: (context, state) {
        // Après création : recharger la liste (la dialog mot de passe est gérée dans AddMemberDialog)
        if (state is MembreCreated) {
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }

        // Accès refusé sur une action lifecycle (403) — SnackBar ciblé + rechargement liste
        if (state is MembresActionForbidden) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Row(children: [
                const Icon(Icons.block_outlined, color: Colors.white, size: 18),
                const SizedBox(width: 8),
                Expanded(child: Text(state.message)),
              ]),
              backgroundColor: ColorTokens.error,
              duration: const Duration(seconds: 5),
            ),
          );
          // Recharger pour revenir à l'état MembresLoaded (évite la page d'erreur plein écran)
          context.read<MembresBloc>().add(LoadMembres(organisationId: organisationId));
          return;
        }

        // Gestion des erreurs avec SnackBar
        if (state is MembresError) {
          final bloc = context.read<MembresBloc>();
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(state.message),
              backgroundColor: ColorTokens.error,
              duration: const Duration(seconds: 4),
              action: SnackBarAction(
                label: 'Réessayer',
                textColor: Colors.white,
                onPressed: () {
                  bloc.add(LoadMembres(organisationId: organisationId));
                },
              ),
            ),
          );
        }

        // Après activation : succès + rechargement
        if (state is MembreActivated) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Membre activé avec succès'),
              backgroundColor: ColorTokens.success,
              duration: Duration(seconds: 3),
            ),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }

        // Après suppression définitive : feedback + pop la page de détail si ouverte + rechargement
        if (state is MembreDeleted) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Row(children: const [
                Icon(Icons.delete_forever, color: Colors.white, size: 18),
                SizedBox(width: 8),
                Expanded(child: Text('Compte supprimé avec succès')),
              ]),
              backgroundColor: ColorTokens.error,
              duration: const Duration(seconds: 3),
            ),
          );
          // Si on est dans MemberDetailPage, revenir à la liste (pop unique)
          Navigator.of(context).maybePop();
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }

        // Après reset mot de passe : afficher le dialog credentials
        if (state is MotDePasseReinitialise) {
          showCredentialsDialog(context, state.membre);
        }

        // Après affectation à une organisation : succès + rechargement
        if (state is MembreAffecte) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              content: Text('Membre affecté à l\'organisation avec succès'),
              backgroundColor: ColorTokens.success,
              duration: Duration(seconds: 3),
            ),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }

        // Lifecycle adhésion : succès + rechargement
        if (state is MembreInvite) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Invitation envoyée'), backgroundColor: ColorTokens.info, duration: Duration(seconds: 3)),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }
        if (state is AdhesionActivee) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Adhésion activée'), backgroundColor: ColorTokens.success, duration: Duration(seconds: 3)),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }
        if (state is AdhesionSuspendue) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Adhésion suspendue'), backgroundColor: ColorTokens.warning, duration: Duration(seconds: 3)),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }
        if (state is MembreRadie) {
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(content: Text('Membre radié de l\'organisation'), backgroundColor: ColorTokens.error, duration: Duration(seconds: 3)),
          );
          context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
        }
      },
      child: BlocBuilder<MembresBloc, MembresState>(
        builder: (context, state) {
          AppLogger.blocState('MembresBloc', state.runtimeType.toString());

        // État initial
        if (state is MembresInitial) {
          return Container(
            color: null,
            child: const Center(
              child: AppLoadingWidget(message: 'Initialisation...'),
            ),
          );
        }

        // État de chargement
        if (state is MembresLoading) {
          return Container(
            color: null,
            child: const Center(
              child: AppLoadingWidget(message: 'Chargement des membres...'),
            ),
          );
        }

        // État de rafraîchissement (afficher l'UI avec un indicateur)
        if (state is MembresRefreshing) {
          // Affiche un indicateur pendant le rafraîchissement
          return Container(
            color: null,
            child: const Center(
              child: AppLoadingWidget(message: 'Actualisation...'),
            ),
          );
        }

        // Après création : on recharge la liste (listener a dispatché LoadMembres)
        if (state is MembreCreated) {
          return Container(
            color: null,
            child: const Center(
              child: AppLoadingWidget(message: 'Actualisation...'),
            ),
          );
        }

        // État chargé avec succès
        if (state is MembresLoaded) {
          final membres = state.membres;
          AppLogger.info('MembresPageConnected: ${membres.length} membres chargés');

          // Convertir les membres en format Map pour l'UI existante
          final membersData = _convertMembersToMapList(membres);

          return MembersPageWithDataAndPagination(
            members: membersData,
            totalCount: state.totalElements,
            currentPage: state.currentPage,
            totalPages: state.totalPages,
            organisationId: organisationId,
            onPageChanged: (newPage, recherche) {
              AppLogger.userAction('Load page', data: {'page': newPage});
              context.read<MembresBloc>().add(LoadMembres(page: newPage, recherche: recherche, organisationId: organisationId));
            },
            onRefresh: () {
              AppLogger.userAction('Refresh membres');
              context.read<MembresBloc>().add(LoadMembres(refresh: true, organisationId: organisationId));
            },
            onSearch: (query) {
              context.read<MembresBloc>().add(LoadMembres(page: 0, recherche: query, organisationId: organisationId));
            },
            onAddMember: () => showAddMemberSheet(context),
            onActivateMember: (memberId) {
              context.read<MembresBloc>().add(ActivateMembre(memberId));
            },
            onResetPassword: (memberId) {
              context.read<MembresBloc>().add(ResetMotDePasse(memberId));
            },
            onAffecterOrganisation: organisationId == null
                ? (memberId, orgId) {
                    context.read<MembresBloc>().add(AffecterOrganisation(memberId, orgId));
                  }
                : null,
            // Suppression définitive — SuperAdmin uniquement (organisationId == null)
            // Backend : DELETE /api/membres/{id} @RolesAllowed({ ADMIN, SUPER_ADMIN })
            onDeleteAccount: organisationId == null
                ? (memberId) {
                    context.read<MembresBloc>().add(DeleteMembre(memberId));
                  }
                : null,
            // onLifecycleAction est toujours fourni.
            // orgAdmin : organisationId fixe (contexte org).
            // superAdmin : organisationId provient du membre lui-même (passé par _lifecycleButtons).
            onLifecycleAction: (memberId, targetOrgId, action, motif) {
                final bloc = context.read<MembresBloc>();
                // En contexte orgAdmin on utilise l'org fixe, en superAdmin l'org du membre
                final effectiveOrgId = organisationId ?? targetOrgId;
                switch (action) {
                  case 'inviter':
                    bloc.add(InviterMembre(membreId: memberId, organisationId: effectiveOrgId));
                    break;
                  case 'activer':
                    bloc.add(ActiverAdhesion(membreId: memberId, organisationId: effectiveOrgId, motif: motif));
                    break;
                  case 'suspendre':
                    bloc.add(SuspendrAdhesion(membreId: memberId, organisationId: effectiveOrgId, motif: motif));
                    break;
                  case 'radier':
                    bloc.add(RadierAdhesion(membreId: memberId, organisationId: effectiveOrgId, motif: motif));
                    break;
                }
              },
          );
        }

        // État d'erreur réseau
        if (state is MembresNetworkError) {
          AppLogger.error('MembersPageConnected: Erreur réseau', error: state.message);
          return Container(
            color: null,
            child: NetworkErrorWidget(
              onRetry: () {
                AppLogger.userAction('Retry load membres after network error');
                context.read<MembresBloc>().add(LoadMembres(organisationId: organisationId));
              },
            ),
          );
        }

        // État d'erreur générale
        if (state is MembresError) {
          AppLogger.error('MembersPageConnected: Erreur', error: state.message);
          return Container(
            color: null,
            child: AppErrorWidget(
              message: state.message,
              onRetry: () {
                AppLogger.userAction('Retry load membres after error');
                context.read<MembresBloc>().add(LoadMembres(organisationId: organisationId));
              },
            ),
          );
        }

        // État par défaut (ne devrait jamais arriver)
        AppLogger.warning('MembersPageConnected: État non géré: ${state.runtimeType}');
        return Container(
          color: null,
          child: const Center(
            child: AppLoadingWidget(message: 'Chargement...'),
          ),
        );
        },
      ),
    );
  }

  /// Convertit une liste de MembreCompletModel en List<Map<String, dynamic>>
  /// pour compatibilité avec l'UI existante
  List<Map<String, dynamic>> _convertMembersToMapList(List<MembreCompletModel> membres) {
    return membres.map((membre) => _convertMembreToMap(membre)).toList();
  }

  /// Convertit un MembreCompletModel en Map<String, dynamic>
  Map<String, dynamic> _convertMembreToMap(MembreCompletModel membre) {
    return {
      'id': membre.id ?? '',
      'name': membre.nomComplet,
      'email': membre.email,
      'actif': membre.actif, // flag global désactivation (soft delete)
      'roleCode': membre.role, // code brut ex: ORGADMIN, SUPERADMIN — utilisé pour les checks de permission
      'role': _mapRoleToString(membre.role),
      'status': _mapStatutToString(membre.statut),
      'joinDate': membre.dateAdhesion,
      'lastActivity': membre.derniereActivite ?? DateTime.now(),
      'avatar': membre.photo,
      'phone': membre.telephone ?? '',
      'department': membre.profession ?? '',
      'location': '${membre.ville ?? ''}, ${membre.pays ?? ''}',
      'permissions': 15, // Valeurs par défaut tant que l'API ne fournit pas permissions
      'contributionScore': 0, // Valeurs par défaut tant que l'API ne fournit pas contributionScore
      'eventsAttended': membre.nombreEvenementsParticipes,
      'projectsInvolved': 0, // Valeurs par défaut tant que l'API ne fournit pas projectsInvolved
      
      // Champs supplémentaires du modèle
      'prenom': membre.prenom,
      'nom': membre.nom,
      'dateNaissance': membre.dateNaissance,
      'genre': membre.genre?.name,
      'adresse': membre.adresse,
      'ville': membre.ville,
      'codePostal': membre.codePostal,
      'region': membre.region,
      'pays': membre.pays,
      'profession': membre.profession,
      'nationalite': membre.nationalite,
      'organisationId': membre.organisationId,
      'membreBureau': membre.membreBureau,
      'responsable': membre.responsable,
      'fonctionBureau': membre.fonctionBureau,
      'numeroMembre': membre.numeroMembre,
      'cotisationAJour': membre.cotisationAJour,
      'organisationNom': membre.organisationNom,
      'statutKyc': membre.statutKyc?.name,
      'niveauVigilanceKyc': membre.niveauVigilanceKyc?.name,
      'statutMembre': membre.statut?.name,

      // Propriétés calculées
      'initiales': membre.initiales,
      'age': membre.age,
      'estActifEtAJour': membre.estActifEtAJour,
    };
  }

  /// Mappe le rôle du modèle vers une chaîne lisible
  String _mapRoleToString(String? role) {
    if (role == null) return 'Membre Simple';
    
    switch (role.toLowerCase()) {
      case 'superadmin':
        return 'Super Administrateur';
      case 'orgadmin':
        return 'Administrateur Org';
      case 'moderator':
        return 'Modérateur';
      case 'activemember':
        return 'Membre Actif';
      case 'simplemember':
        return 'Membre Simple';
      case 'visitor':
        return 'Visiteur';
      default:
        return role;
    }
  }

  /// Mappe le statut du modèle vers une chaîne lisible
  String _mapStatutToString(StatutMembre? statut) {
    if (statut == null) return 'Actif';
    
    switch (statut) {
      case StatutMembre.actif:
        return 'Actif';
      case StatutMembre.inactif:
        return 'Inactif';
      case StatutMembre.suspendu:
        return 'Suspendu';
      case StatutMembre.enAttente:
        return 'En attente';
    }
  }
}

