# Bot Module Documentation

## Overview
The bot module contains all the Telegram bot logic for "Echoes of the Ashes" RPG game.

## Module Structure

### Core Modules
- **`handlers.py`** (14KB) - Main message router and utility functions
- **`database.py`** - Database operations and queries
- **`keyboards.py`** - Telegram keyboard layouts
- **`logic.py`** - Game logic and calculations
- **`combat.py`** (17KB) - Combat system implementation
- **`spawn_manager.py`** - Enemy spawning system
- **`utils.py`** - Utility functions and decorators

### Handler Modules (Refactored)
Organized by functionality for better maintainability:

#### **`action_handlers.py`** (14KB, 367 lines)
World interaction and inspection
- `get_player_status_text()` - Player status display
- `handle_inspect_area()` - Inspect locations
- `handle_attack_wandering()` - Attack wandering enemies
- `handle_inspect_interactable()` - Inspect objects
- `handle_action()` - Perform actions
- `handle_main_menu()` - Main menu navigation
- `handle_move_menu()` - Movement menu
- `handle_move()` - Travel between locations

#### **`inventory_handlers.py`** (13KB, 355 lines)
Inventory management system
- `handle_inventory_menu()` - Show inventory
- `handle_inventory_item()` - Item details
- `handle_inventory_use()` - Use consumables
- `handle_inventory_drop()` - Drop items
- `handle_inventory_equip()` - Equip gear
- `handle_inventory_unequip()` - Unequip gear

#### **`pickup_handlers.py`** (5.1KB, 135 lines)
Item collection from world
- `handle_pickup_menu()` - Pickup options
- `handle_pickup()` - Pick up items

#### **`combat_handlers.py`** (6.3KB, 171 lines)
Combat action handlers
- `handle_combat_attack()` - Attack enemy
- `handle_combat_flee()` - Flee combat
- `handle_combat_use_item_menu()` - Combat items menu
- `handle_combat_use_item()` - Use item in combat
- `handle_combat_back()` - Return to combat menu

#### **`profile_handlers.py`** (6.0KB, 147 lines)
Character progression
- `handle_profile()` - View profile
- `handle_spend_points_menu()` - Stat points menu
- `handle_spend_point()` - Allocate stat points

#### **`corpse_handlers.py`** (8.2KB, 234 lines)
Looting system
- `handle_loot_player_corpse()` - Loot player corpses
- `handle_take_corpse_item()` - Take items from player corpse
- `handle_scavenge_npc_corpse()` - Scavenge NPC corpses
- `handle_scavenge_corpse_item()` - Take items from NPC corpse

## Architecture

### Message Flow
```
Telegram Update
    ↓
main.py (Application setup)
    ↓
handlers.py::button_handler (Router)
    ↓
Specialized Handler (action_handlers, combat_handlers, etc.)
    ↓
database.py (Data operations)
    ↓
keyboards.py (UI response)
    ↓
Response to User
```

### Handler Pattern
All handlers follow a consistent pattern:

```python
async def handle_action(query, user_id: int, player: dict, data: list = None):
    """
    Handle specific action.
    
    Args:
        query: Telegram callback query object
        user_id: Telegram user ID
        player: Player data dict
        data: Optional list of parameters from callback_data
    """
    # 1. Validate input
    # 2. Perform action
    # 3. Update database
    # 4. Send response with send_or_edit_with_image()
```

### Shared Utilities

#### `send_or_edit_with_image()`
Central function for sending/editing messages with images:
```python
await send_or_edit_with_image(
    query,
    text="Message text",
    reply_markup=keyboard,
    image_path="/path/to/image.png"  # Optional
)
```

Features:
- Smooth image transitions
- Image caching for performance
- Automatic fallback to text-only
- Edit vs. send detection

## Design Principles

### 1. Separation of Concerns
Each module handles a specific domain:
- Handlers → User interaction
- Database → Data persistence
- Logic → Game rules
- Combat → Battle mechanics

### 2. Single Responsibility
Each function has one clear purpose:
- ✅ `handle_inventory_use()` - Use items
- ✅ `handle_combat_attack()` - Attack in combat
- ❌ ~~One giant function that does everything~~

### 3. Consistency
All handlers:
- Accept same parameter pattern
- Use async/await
- Handle errors gracefully
- Log important actions

### 4. Error Handling
Centralized in `button_handler`:
```python
try:
    await handle_specific_action(...)
except Exception as e:
    logger.error(f"Error: {e}", exc_info=True)
    await query.answer("An error occurred.", show_alert=True)
```

## Adding New Handlers

### Step 1: Create Handler Function
```python
# In appropriate *_handlers.py module
async def handle_new_action(query, user_id: int, player: dict, data: list):
    """Handle new action."""
    await query.answer()
    
    # Your logic here
    
    from .handlers import send_or_edit_with_image
    await send_or_edit_with_image(
        query,
        text="Action result",
        reply_markup=some_keyboard()
    )
```

### Step 2: Import in handlers.py
```python
from .your_handlers import handle_new_action
```

### Step 3: Add Route
```python
# In button_handler()
elif action_type == "new_action":
    await handle_new_action(query, user_id, player, data)
```

### Step 4: Create Keyboard Button
```python
# In keyboards.py
InlineKeyboardButton(
    "New Action",
    callback_data="new_action:param1:param2"
)
```

## Testing

### Manual Testing
1. Start the bot: `python main.py`
2. Send `/start` to the bot
3. Test each button action
4. Check logs for errors

### Unit Testing (Future)
```python
# tests/test_handlers.py
async def test_handle_inventory_use():
    result = await handle_inventory_use(
        mock_query,
        user_id=123,
        player=mock_player,
        data=['inventory_use', '1']
    )
    assert result is not None
```

## Performance Considerations

### Image Caching
Images are cached after first upload:
```python
cached_file_id = await database.get_cached_image(image_path)
if not cached_file_id:
    # Upload and cache
    await database.cache_image(image_path, file_id)
```

### Database Queries
- Use indexed lookups (user_id, location_id)
- Batch operations where possible
- Async all the way

### Memory
- Don't store large objects in memory
- Use database for persistence
- Clean up old data periodically

## Debugging

### Enable Debug Logging
```python
# In main.py
logging.basicConfig(
    level=logging.DEBUG,  # Change from INFO
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
```

### Common Issues

**Issue:** Handler not being called
- Check callback_data format: `"action_type:param1:param2"`
- Verify route exists in `button_handler()`
- Check import statement

**Issue:** Image not showing
- Verify image path exists
- Check image cache
- Look for upload errors in logs

**Issue:** Database errors
- Check player exists
- Verify foreign key relationships
- Look at database schema

## Migration Guide

### From Old handlers.py
Old code in backup files:
- `backups/handlers_original.py`
- `backups/handlers.py.old`

All functionality preserved, just reorganized into modules.

## Future Enhancements

1. **Type Hints** - Add proper type annotations
2. **Unit Tests** - Test coverage for all handlers
3. **Decorators** - Common validations (requires_combat, requires_stamina)
4. **Base Classes** - Handler base class with common functionality
5. **Event System** - Decouple actions from responses

## Contributing

When adding new features:
1. Choose the appropriate handler module (or create new one)
2. Follow the existing pattern
3. Add docstrings
4. Log important actions
5. Handle errors gracefully
6. Update this documentation

## Questions?

See also:
- `REFACTORING_NOTES.md` - Refactoring details
- `HANDLER_REFACTORING_SUMMARY.md` - Before/after comparison
- `README.md` - Project overview
