# 🎭 EventModule: Like a Magic Telephone Central! 

Imagine that EventModule is like a **magic telephone central** in your city! 📞✨

## 🏠 What is an EventModule?

Think of EventModule as **different houses** in your city. Each house (module) can:
- 👂 **Listen** to special phone calls
- 📢 **Send** messages to other houses
- 🔔 **Receive** important notifications

```dart
class LoginEventModule extends EventModule {
  @override
  void listen() {
    // This house listens when someone logs in! 👋
    on<LoginEvent>((event, context) {
      print('🎉 Welcome, ${event.username}!');
      if (context != null) {
        context.go('/home'); // Go to home page
      }
    });
  }
}
```

## 📞 How Does the Telephone Central Work?

### 1. 📢 Sending Messages (Firing Events)

When something important happens, you "shout" to the whole city:

```dart
// 🗣️ "HEY EVERYONE! John just logged in!"
ModularEvent.fire(LoginEvent(username: 'John'));

// 🗣️ "ATTENTION! A new message arrived!"
ModularEvent.fire(NotificationEvent(message: 'You have a gift!'));

// 🗣️ "WATCH OUT! Something went wrong!"
ModularEvent.fire(ErrorEvent(error: 'Slow internet'));
```

### 2. 👂 Listening to Messages (Listening Events)

Each house can choose which types of "shouts" it wants to listen to:

```dart
class NotificationModule extends EventModule {
  @override
  void listen() {
    // 🔔 This house listens to notifications
    on<NotificationEvent>((event, context) {
      showDialog(
        context: context!,
        builder: (context) => AlertDialog(
          title: Text('📬 New Message!'),
          content: Text(event.message),
        ),
      );
    });

    // ❌ This house also listens to errors
    on<ErrorEvent>((event, context) {
      ScaffoldMessenger.of(context!).showSnackBar(
        SnackBar(
          content: Text('💥 Oops! ${event.error}'),
          backgroundColor: Colors.red,
        ),
      );
    });
  }
}
```

## 🎵 The Exclusive System: Like a Special Radio

Imagine you have a **very special radio** that can only play one song at a time! 🎵

### 📻 Normal Mode (Non-Exclusive)
```dart
// 🎶 ALL houses listen to the same song at the same time
on<MusicEvent>((event, context) {
  print('🎵 Playing: ${event.songName}');
}); // exclusive: false (default)
```

**What happens:**
- John's House: 🎵 "Playing: Happy Birthday"
- Maria's House: 🎵 "Playing: Happy Birthday"  
- Peter's House: 🎵 "Playing: Happy Birthday"

### 📻 Exclusive Mode (Radio Queue)
```dart
// 🎯 Only ONE house can listen at a time!
on<MusicEvent>((event, context) {
  print('🎵 Only I listen: ${event.songName}');
}, exclusive: true);
```

**What happens:**
1. 🏠 **John's House** enters queue first → 🎵 He listens to the song
2. 🏠 **Maria's House** enters queue → ⏳ Waits
3. 🏠 **Peter's House** enters queue → ⏳ Waits

```
📋 RADIO QUEUE:
┌─────────────────────────┐
│ 🎵 John (playing now)   │ ← Active
│ ⏳ Maria (waiting)       │ ← Next
│ ⏳ Peter (waiting)       │ ← After
└─────────────────────────┘
```

### 🏃‍♂️ When Someone Leaves the Queue

If John leaves home (dispose), the radio **automatically** goes to Maria:

```
📋 AFTER JOHN LEAVES:
┌─────────────────────────┐
│ 🎵 Maria (playing now)  │ ← Now active!
│ ⏳ Peter (waiting)       │ ← Next
└─────────────────────────┘
```

## 🎪 Real World Examples

### 🔐 Login System
```dart
class LoginModule extends EventModule {
  @override
  void listen() {
    // When someone logs in
    on<LoginEvent>((event, context) {
      print('👋 Hello, ${event.username}!');
      // Go to main screen
      context?.go('/dashboard');
    });

    // When someone logs out  
    on<LogoutEvent>((event, context) {
      print('👋 Bye, ${event.username}!');
      // Go back to login screen
      context?.go('/login');
    });
  }
}

// How to use:
ModularEvent.fire(LoginEvent(username: 'Ana'));
ModularEvent.fire(LogoutEvent(username: 'Ana'));
```

### 🛒 Shopping Cart
```dart
class ShoppingModule extends EventModule {
  @override
  void listen() {
    // When adding product
    on<AddToCartEvent>((event, context) {
      print('🛒 Added: ${event.productName}');
      ScaffoldMessenger.of(context!).showSnackBar(
        SnackBar(content: Text('✅ ${event.productName} in cart!'))
      );
    });

    // When finishing purchase
    on<PurchaseEvent>((event, context) {
      print('💳 Purchase of \$${event.total} completed!');
      context?.go('/success');
    });
  }
}

// How to use:
ModularEvent.fire(AddToCartEvent(productName: 'Bicycle', price: 500.0));
ModularEvent.fire(PurchaseEvent(total: 500.0));
```

### 🎮 Game System
```dart
class GameModule extends EventModule {
  @override
  void listen() {
    // Score system (exclusive - only one counter)
    on<ScoreEvent>((event, context) {
      print('🏆 New score: ${event.points}');
      updateScoreboard(event.points);
    }, exclusive: true);

    // Sound effects (normal - everyone listens)
    on<SoundEvent>((event, context) {
      print('🔊 Sound: ${event.soundName}');
      playSound(event.soundName);
    });
  }
}

// How to use:
ModularEvent.fire(ScoreEvent(points: 1000));
ModularEvent.fire(SoundEvent(soundName: 'coin.wav'));
```

## 🎯 Important Rules

### 1. 🏠 Automatic Cleanup
When a house is demolished (`dispose()`), it **automatically**:
- 🧹 Stops listening to all events
- 🗑️ Cleans all memory
- 📻 If it was on exclusive radio, passes to the next

### 2. 🌐 Magic Context
The `context` is like a **magic GPS** that shows you where you are:
```dart
on<NavigationEvent>((event, context) {
  if (context != null) {
    // 🗺️ You know where you are! Can navigate
    context.go('/new-page');
  } else {
    // 🤷‍♂️ You don't know where you are... 
    print('Oops! I don't know where I am');
  }
});
```

### 3. 🔄 AutoDispose
```dart
// 🔒 This listener goes away when the house is demolished
on<MyEvent>((event, context) {
  // do something...
}, autoDispose: true); // default

// 🔓 This listener stays forever (careful!)
on<MyEvent>((event, context) {
  // do something...
}, autoDispose: false); // dangerous!
```

## 🎨 Creating Your Own Events

```dart
// 🎂 Birthday event
class BirthdayEvent {
  final String personName;
  final int age;
  
  BirthdayEvent({required this.personName, required this.age});
}

// 🌟 Module that listens to birthdays
class BirthdayModule extends EventModule {
  @override
  void listen() {
    on<BirthdayEvent>((event, context) {
      print('🎉 Happy Birthday ${event.personName}! ${event.age} years old!');
      
      if (context != null) {
        showDialog(
          context: context,
          builder: (context) => AlertDialog(
            title: Text('🎂 Birthday!'),
            content: Text('${event.personName} is ${event.age} years old!'),
            actions: [
              TextButton(
                onPressed: () => Navigator.of(context).pop(),
                child: Text('🎁 Cool!'),
              ),
            ],
          ),
        );
      }
    });
  }
}

// How to use:
ModularEvent.fire(BirthdayEvent(personName: 'Maria', age: 10));
```

## 🚀 Golden Tips

### ✨ Best Practices
```dart
// ✅ GOOD: Always check context
on<NavigationEvent>((event, context) {
  if (context != null) {
    context.go(event.route);
  }
});

// ✅ GOOD: Clear names for events
class UserLoginSuccessEvent { ... }
class ShoppingCartUpdatedEvent { ... }
class GameOverEvent { ... }

// ❌ BAD: Don't check context
on<NavigationEvent>((event, context) {
  context!.go(event.route); // Can cause error!
});
```

### 🎪 Complete Example: Shop App
```dart
// 📱 Complete app with events
class ShopApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return GoRouterModularApp(
      title: '🛍️ My Shop',
      modules: [
        LoginModule(),      // Handles login
        ShoppingModule(),   // Handles shopping  
        NotificationModule(), // Handles notifications
      ],
    );
  }
}

// 🏪 Shop module
class ShoppingModule extends EventModule {
  @override
  List<ModularRoute> get routes => [
    ChildRoute('/shop', child: (context, state) => ShopPage()),
    ChildRoute('/cart', child: (context, state) => CartPage()),
  ];

  @override
  void listen() {
    // When adding to cart
    on<AddToCartEvent>((event, context) {
      print('🛒 ${event.productName} added!');
      
      // Show notification
      ModularEvent.fire(NotificationEvent(
        message: '${event.productName} in your cart!'
      ));
    });

    // When removing from cart
    on<RemoveFromCartEvent>((event, context) {
      print('🗑️ ${event.productName} removed!');
    });

    // When finishing purchase (exclusive - only one at a time)
    on<CheckoutEvent>((event, context) {
      print('💳 Processing purchase...');
      // Go to success page
      context?.go('/success');
    }, exclusive: true);
  }
}
```

## 🎊 Conclusion

EventModule is like a **magic city** where:
- 🏠 **Houses** (modules) can listen to events
- 📢 **Shouts** (events) spread information
- 📞 **Telephone central** (EventBus) connects everything
- 📻 **Exclusive radio** ensures order in queues
- 🧹 **Automatic cleanup** prevents mess

**Now you can create your own events and make your app talk like a happy city!** 🏙️✨

---

*"With great power comes great responsibility... always dispose your modules!"* 🕷️