"""
Discord Multi-Agent Kit
=======================
Python library for managing multi-agent teams on Discord via webhooks.

Create virtual team members, each with their own persona and webhook,
to coordinate work like a real company!

MIT License - Created by Rika Company
"""

import requests
import time
import random
import os
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Callable


@dataclass
class TeamMember:
    """Represents a team member with Discord webhook integration."""
    name: str
    role: str
    webhook_url: str
    personality: str = ""
    avatar_url: str = ""
    
    def __repr__(self):
        return f"{self.name} ({self.role})"


class DiscordTeam:
    """
    Manage a multi-agent team on Discord.
    
    Each team member posts via their own webhook, creating the illusion
    of multiple agents working together.
    
    Example:
        team = DiscordTeam()
        team.add_member(TeamMember(
            name="Alice",
            role="CEO",
            webhook_url=os.environ.get("ALICE_WEBHOOK"),
            personality="Strategic thinker, makes quick decisions"
        ))
        team.send("Alice", "Let's start the meeting!")
    """
    
    def __init__(self):
        self.members: Dict[str, TeamMember] = {}
        self._rate_limit_delay = 0.5  # seconds between messages
    
    def add_member(self, member: TeamMember) -> None:
        """Add a team member."""
        self.members[member.name.lower()] = member
    
    def remove_member(self, name: str) -> bool:
        """Remove a team member. Returns True if removed."""
        key = name.lower()
        if key in self.members:
            del self.members[key]
            return True
        return False
    
    def get_member(self, name: str) -> Optional[TeamMember]:
        """Get a team member by name (case-insensitive)."""
        return self.members.get(name.lower())
    
    def list_members(self) -> List[TeamMember]:
        """List all team members."""
        return list(self.members.values())
    
    def send(self, member_name: str, content: str, 
             avatar_url: Optional[str] = None) -> bool:
        """
        Send a message as a team member.
        
        Args:
            member_name: Name of the team member
            content: Message content (supports Discord markdown)
            avatar_url: Optional override for avatar
            
        Returns:
            True if message sent successfully
        """
        member = self.get_member(member_name)
        if not member:
            raise ValueError(f"Unknown team member: {member_name}")
        
        payload = {
            "username": f"{member.name} ({member.role})",
            "content": content,
        }
        
        # Use avatar URL if provided
        avatar = avatar_url or member.avatar_url
        if avatar:
            payload["avatar_url"] = avatar
        
        try:
            response = requests.post(member.webhook_url, json=payload)
            time.sleep(self._rate_limit_delay)  # Respect rate limits
            return response.status_code in [200, 204]
        except requests.RequestException:
            return False
    
    def broadcast(self, content: str, exclude: Optional[List[str]] = None) -> Dict[str, bool]:
        """
        Send a message to all team members.
        
        Args:
            content: Message to broadcast
            exclude: List of member names to exclude
            
        Returns:
            Dict mapping member names to success status
        """
        exclude = [n.lower() for n in (exclude or [])]
        results = {}
        
        for name, member in self.members.items():
            if name not in exclude:
                results[member.name] = self.send(member.name, content)
        
        return results
    
    def meeting(self, topic: str, 
                opener: Optional[str] = None,
                participants: Optional[List[str]] = None) -> None:
        """
        Start a team meeting.
        
        Args:
            topic: Meeting topic
            opener: Name of member to open the meeting (default: first member)
            participants: List of members to include (default: all)
        """
        members = participants or [m.name for m in self.list_members()]
        opener = opener or members[0]
        
        # Opening message
        self.send(opener, f"📢 **Team Meeting: {topic}**\n\nLet's discuss!")


def create_team_from_config(config: Dict) -> DiscordTeam:
    """
    Create a team from a configuration dict.
    
    Config format:
        {
            "members": [
                {
                    "name": "Alice",
                    "role": "CEO",
                    "webhook_url": "https://...",
                    "personality": "...",
                    "avatar_url": "..."
                },
                ...
            ]
        }
    """
    team = DiscordTeam()
    
    for member_config in config.get("members", []):
        member = TeamMember(
            name=member_config["name"],
            role=member_config["role"],
            webhook_url=member_config["webhook_url"],
            personality=member_config.get("personality", ""),
            avatar_url=member_config.get("avatar_url", "")
        )
        team.add_member(member)
    
    return team


def create_team_from_env(prefix: str = "TEAM") -> DiscordTeam:
    """
    Create a team from environment variables.
    
    Environment variables format:
        TEAM_MEMBER_1_NAME=Alice
        TEAM_MEMBER_1_ROLE=CEO
        TEAM_MEMBER_1_WEBHOOK=https://...
        TEAM_MEMBER_2_NAME=Bob
        ...
    """
    team = DiscordTeam()
    
    i = 1
    while True:
        name = os.environ.get(f"{prefix}_MEMBER_{i}_NAME")
        if not name:
            break
        
        role = os.environ.get(f"{prefix}_MEMBER_{i}_ROLE", "Member")
        webhook = os.environ.get(f"{prefix}_MEMBER_{i}_WEBHOOK", "")
        personality = os.environ.get(f"{prefix}_MEMBER_{i}_PERSONALITY", "")
        avatar = os.environ.get(f"{prefix}_MEMBER_{i}_AVATAR", "")
        
        if webhook:
            team.add_member(TeamMember(
                name=name,
                role=role,
                webhook_url=webhook,
                personality=personality,
                avatar_url=avatar
            ))
        
        i += 1
    
    return team


# Example usage (don't include real webhooks!)
if __name__ == "__main__":
    print("Discord Multi-Agent Kit")
    print("=" * 40)
    print()
    print("Example:")
    print("  team = DiscordTeam()")
    print("  team.add_member(TeamMember(")
    print("      name='Alice',")
    print("      role='CEO',")
    print("      webhook_url=os.environ.get('ALICE_WEBHOOK')")
    print("  ))")
    print("  team.send('Alice', 'Hello team!')")
    print()
    print("See README.md for full documentation.")
