/// Wrapper BLoC pour la page des événements
/// 
/// Ce fichier enveloppe la EventsPage existante avec le EvenementsBloc
/// pour connecter l'UI riche existante à l'API backend réelle.
library events_page_wrapper;

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

import '../../../../shared/widgets/error_widget.dart';
import '../../../../shared/widgets/loading_widget.dart';
import '../../../../core/utils/logger.dart';
import '../../bloc/evenements_bloc.dart';
import '../../bloc/evenements_event.dart';
import '../../bloc/evenements_state.dart';
import '../../data/models/evenement_model.dart';
import 'events_page_connected.dart';

final _getIt = GetIt.instance;

/// Wrapper qui fournit le BLoC à la page des événements
class EventsPageWrapper extends StatelessWidget {
  const EventsPageWrapper({super.key});

  @override
  Widget build(BuildContext context) {
    AppLogger.info('EventsPageWrapper: Création du BlocProvider');
    
    return BlocProvider<EvenementsBloc>(
      create: (context) {
        AppLogger.info('EventsPageWrapper: Initialisation du EvenementsBloc');
        final bloc = _getIt<EvenementsBloc>();
        // Charger les événements au démarrage
        bloc.add(const LoadEvenements());
        return bloc;
      },
      child: const EventsPageConnected(),
    );
  }
}

/// Page des événements connectée au BLoC
///
/// Cette page gère les états du BLoC et affiche l'UI appropriée
class EventsPageConnected extends StatelessWidget {
  const EventsPageConnected({super.key});

  @override
  Widget build(BuildContext context) {
    return BlocListener<EvenementsBloc, EvenementsState>(
      listener: (context, state) {
        // Gestion des erreurs avec SnackBar
        if (state is EvenementsError) {
          ScaffoldMessenger.of(context).showSnackBar(
            SnackBar(
              content: Text(state.message),
              backgroundColor: Colors.red,
              duration: const Duration(seconds: 4),
              action: SnackBarAction(
                label: 'Réessayer',
                textColor: Colors.white,
                onPressed: () {
                  context.read<EvenementsBloc>().add(const LoadEvenements());
                },
              ),
            ),
          );
        }
      },
      child: BlocBuilder<EvenementsBloc, EvenementsState>(
        builder: (context, state) {
          AppLogger.blocState('EvenementsBloc', state.runtimeType.toString());

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

        // État de chargement
        if (state is EvenementsLoading) {
          return Container(
            color: const Color(0xFFF8F9FA),
            child: const Center(
              child: AppLoadingWidget(message: 'Chargement des événements...'),
            ),
          );
        }

        // État de rafraîchissement
        if (state is EvenementsRefreshing) {
          return Container(
            color: const Color(0xFFF8F9FA),
            child: const Center(
              child: AppLoadingWidget(message: 'Actualisation...'),
            ),
          );
        }

        // État chargé avec succès
        if (state is EvenementsLoaded) {
          final evenements = state.evenements;
          AppLogger.info('EventsPageConnected: ${evenements.length} événements chargés');

          // Convertir les événements en format Map pour l'UI existante
          final eventsData = _convertEvenementsToMapList(evenements);

          return EventsPageWithData(
            events: eventsData,
            totalCount: state.total,
            currentPage: state.page,
            totalPages: state.totalPages,
          );
        }

        // État d'erreur réseau
        if (state is EvenementsNetworkError) {
          AppLogger.error('EventsPageConnected: Erreur réseau', error: state.message);
          return Container(
            color: const Color(0xFFF8F9FA),
            child: NetworkErrorWidget(
              onRetry: () {
                AppLogger.userAction('Retry load evenements after network error');
                context.read<EvenementsBloc>().add(const LoadEvenements());
              },
            ),
          );
        }

        // État d'erreur générale
        if (state is EvenementsError) {
          AppLogger.error('EventsPageConnected: Erreur', error: state.message);
          return Container(
            color: const Color(0xFFF8F9FA),
            child: AppErrorWidget(
              message: state.message,
              onRetry: () {
                AppLogger.userAction('Retry load evenements after error');
                context.read<EvenementsBloc>().add(const LoadEvenements());
              },
            ),
          );
        }

        // État par défaut
        AppLogger.warning('EventsPageConnected: État non géré: ${state.runtimeType}');
        return Container(
          color: const Color(0xFFF8F9FA),
          child: const Center(
            child: AppLoadingWidget(message: 'Chargement...'),
          ),
        );
        },
      ),
    );
  }

  /// Convertit une liste de EvenementModel en List<Map<String, dynamic>>
  List<Map<String, dynamic>> _convertEvenementsToMapList(List<EvenementModel> evenements) {
    return evenements.map((evenement) => _convertEvenementToMap(evenement)).toList();
  }

  /// Convertit un EvenementModel en Map<String, dynamic>
  Map<String, dynamic> _convertEvenementToMap(EvenementModel evenement) {
    return {
      'id': evenement.id ?? '',
      'title': evenement.titre,
      'description': evenement.description ?? '',
      'startDate': evenement.dateDebut,
      'endDate': evenement.dateFin,
      'location': evenement.lieu ?? '',
      'address': evenement.adresse ?? '',
      'type': _mapTypeToString(evenement.type),
      'status': _mapStatutToString(evenement.statut),
      'maxParticipants': evenement.maxParticipants,
      'currentParticipants': evenement.participantsActuels,
      'organizer': 'Organisateur', // TODO: Récupérer depuis organisateurId
      'priority': _mapPrioriteToString(evenement.priorite),
      'isPublic': evenement.estPublic,
      'requiresRegistration': evenement.inscriptionRequise,
      'cost': evenement.cout,
      'tags': evenement.tags,
      'createdBy': 'Créateur', // TODO: Récupérer depuis organisateurId
      'createdAt': DateTime.now(), // TODO: Ajouter au modèle
      'lastModified': DateTime.now(), // TODO: Ajouter au modèle
      
      // Champs supplémentaires du modèle
      'ville': evenement.ville,
      'codePostal': evenement.codePostal,
      'organisateurId': evenement.organisateurId,
      'organisationId': evenement.organisationId,
      'devise': evenement.devise,
      'imageUrl': evenement.imageUrl,
      'documentUrl': evenement.documentUrl,
      
      // Propriétés calculées
      'dureeHeures': evenement.dureeHeures,
      'joursAvantEvenement': evenement.joursAvantEvenement,
      'estAVenir': evenement.estAVenir,
      'estEnCours': evenement.estEnCours,
      'estPasse': evenement.estPasse,
      'placesDisponibles': evenement.placesDisponibles,
      'estComplet': evenement.estComplet,
      'peutSinscrire': evenement.peutSinscrire,
    };
  }

  /// Mappe le type du modèle vers une chaîne lisible
  String _mapTypeToString(TypeEvenement? type) {
    if (type == null) return 'Autre';

    switch (type) {
      case TypeEvenement.assembleeGenerale:
        return 'Assemblée Générale';
      case TypeEvenement.reunion:
        return 'Réunion';
      case TypeEvenement.formation:
        return 'Formation';
      case TypeEvenement.conference:
        return 'Conférence';
      case TypeEvenement.atelier:
        return 'Atelier';
      case TypeEvenement.seminaire:
        return 'Séminaire';
      case TypeEvenement.evenementSocial:
        return 'Événement Social';
      case TypeEvenement.manifestation:
        return 'Manifestation';
      case TypeEvenement.celebration:
        return 'Célébration';
      case TypeEvenement.autre:
        return 'Autre';
    }
  }

  /// Mappe le statut du modèle vers une chaîne lisible
  String _mapStatutToString(StatutEvenement? statut) {
    if (statut == null) return 'Planifié';

    switch (statut) {
      case StatutEvenement.planifie:
        return 'Planifié';
      case StatutEvenement.confirme:
        return 'Confirmé';
      case StatutEvenement.enCours:
        return 'En cours';
      case StatutEvenement.termine:
        return 'Terminé';
      case StatutEvenement.annule:
        return 'Annulé';
      case StatutEvenement.reporte:
        return 'Reporté';
    }
  }

  /// Mappe la priorité du modèle vers une chaîne lisible
  String _mapPrioriteToString(PrioriteEvenement? priorite) {
    if (priorite == null) return 'Moyenne';
    
    switch (priorite) {
      case PrioriteEvenement.basse:
        return 'Basse';
      case PrioriteEvenement.moyenne:
        return 'Moyenne';
      case PrioriteEvenement.haute:
        return 'Haute';
    }
  }
}

