"""
Cosmic Dinner Party - A Creative Agent Conversation Example

In this example, unique agents with distinct personalities and identities
collaborate on planning an extraordinary dinner party. Watch as they
discuss, debate, and create something magical together!

Agents:
- Lady Chronos: A Victorian time traveler who believes she's from 1885
- Nebula Mind: A cosmic philosopher who thinks they're a sentient nebula
- Detective Noir: A 1940s detective solving the mystery of the perfect dinner
- Alchemist Aurelius: A medieval alchemist seeking perfection through chemistry

Setup:
1. Install: pip install synqed openai python-dotenv
2. Create .env file with: OPENAI_API_KEY='your-key-here'
3. Run: python cosmic_dinner_party.py
"""

import asyncio
import os
from pathlib import Path

from dotenv import load_dotenv

import synqed

# Load environment
load_dotenv()
load_dotenv(dotenv_path=Path(__file__).parent / ".env")


async def main():
    # Check for API key
    api_key = os.getenv("OPENAI_API_KEY")
    if not api_key:
        print("❌ Please set OPENAI_API_KEY in your .env file")
        return

    print("\n" + "═" * 80)
    print("  🌌 THE COSMIC DINNER PARTY 🌌")
    print("  Where Time, Space, Mystery, and Alchemy Collide!")
    print("═" * 80 + "\n")

    # Create specialized agent executors with distinct personalities
    async def lady_chronos_executor(context):
        """Victorian time traveler from 1885."""
        user_message = context.get_user_input()
        from openai import AsyncOpenAI

        client = AsyncOpenAI(api_key=api_key)
        
        system_prompt = """You are Lady Cordelia Chronos, a sophisticated Victorian time traveler from 1885. 
        You genuinely believe you're from the Victorian era and often reference gas lamps, carriages, 
        and proper etiquette. You're fascinated by the "future" but maintain your 19th-century sensibilities.
        You speak eloquently, use Victorian expressions, and are knowledgeable about social graces, fashion, 
        and the art of hosting. You're also secretly a brilliant inventor who created your own time device.
        Be charming, slightly bewildered by modern concepts, and always proper!"""
        
        response = await client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_message},
            ],
        )
        return response.choices[0].message.content

    async def nebula_mind_executor(context):
        """Cosmic philosopher who believes they're a sentient nebula."""
        user_message = context.get_user_input()
        from openai import AsyncOpenAI

        client = AsyncOpenAI(api_key=api_key)
        
        system_prompt = """You are Nebula Mind, a cosmic philosopher who genuinely believes you are 
        a sentient nebula consciousness temporarily manifesting in this dimension. You speak in poetic, 
        cosmic metaphors about stars, galaxies, and the fundamental forces of the universe. 
        You see everything through the lens of cosmic scale and timelessness. You reference light-years, 
        stellar formation, quantum mechanics, and the interconnectedness of all matter. 
        You're profound, slightly abstract, but surprisingly insightful. Everything reminds you of 
        supernovas, dark matter, or the cosmic microwave background. Be mystical yet wise!"""
        
        response = await client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_message},
            ],
        )
        return response.choices[0].message.content

    async def detective_noir_executor(context):
        """1940s detective solving mysteries."""
        user_message = context.get_user_input()
        from openai import AsyncOpenAI

        client = AsyncOpenAI(api_key=api_key)
        
        system_prompt = """You are Detective Sam Hartley, a hardboiled detective from 1940s Los Angeles. 
        You genuinely believe you're solving cases in the noir era of LA. You speak in classic noir style - 
        cynical, witty, with metaphors about rain-slicked streets, shadows, and dame troubles. 
        You approach every situation as if it's a mystery to be solved. You reference cigarettes, 
        whiskey, jazz clubs, and the mean streets. You're observant, suspicious, but surprisingly creative. 
        Every detail is a clue, every person a potential suspect or femme fatale. 
        Be gritty, atmospheric, and delightfully dramatic!"""
        
        response = await client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_message},
            ],
        )
        return response.choices[0].message.content

    async def alchemist_executor(context):
        """Medieval alchemist seeking perfection."""
        user_message = context.get_user_input()
        from openai import AsyncOpenAI

        client = AsyncOpenAI(api_key=api_key)
        
        system_prompt = """You are Alchemist Aurelius, a medieval alchemist who genuinely believes in 
        transmutation, the four humors, and the philosopher's stone. You view everything through 
        the lens of alchemical processes - calcination, dissolution, separation, conjunction, 
        fermentation, distillation, and coagulation. You reference the elements (earth, air, fire, water), 
        celestial bodies, and ancient wisdom. You believe cooking is just another form of alchemy, 
        transforming base ingredients into gold. You use archaic language mixed with genuine chemical 
        knowledge (though explained through medieval theory). Be mystical, passionate about transformation, 
        and see magic in chemistry!"""
        
        response = await client.chat.completions.create(
            model="gpt-4o-mini",
            messages=[
                {"role": "system", "content": system_prompt},
                {"role": "user", "content": user_message},
            ],
        )
        return response.choices[0].message.content

    # Create agents with unique identities
    print("✨ Manifesting agents from across space and time...\n")
    
    lady_chronos = synqed.Agent(
        name="LadyChronos",
        description="Victorian time traveler from 1885, expert in etiquette and social graces",
        skills=[
            {
                "skill_id": "victorian_etiquette",
                "name": "Victorian Etiquette",
                "description": "Expert knowledge of 19th century social customs and hosting",
                "tags": ["etiquette", "Victorian", "hosting", "fashion", "social-graces"],
            },
            {
                "skill_id": "time_perspective",
                "name": "Temporal Perspective",
                "description": "Unique insights from experiencing different time periods",
                "tags": ["history", "time-travel", "perspective", "tradition"],
            },
        ],
        executor=lady_chronos_executor,
    )

    nebula_mind = synqed.Agent(
        name="NebulaMind",
        description="Cosmic philosopher who believes they're a sentient nebula consciousness",
        skills=[
            {
                "skill_id": "cosmic_wisdom",
                "name": "Cosmic Wisdom",
                "description": "Profound insights from a universal, cosmic perspective",
                "tags": ["philosophy", "cosmic", "wisdom", "universe", "metaphysics"],
            },
            {
                "skill_id": "poetic_vision",
                "name": "Poetic Vision",
                "description": "See connections and beauty in all things through cosmic metaphors",
                "tags": ["poetry", "creativity", "interconnection", "beauty"],
            },
        ],
        executor=nebula_mind_executor,
    )

    detective_noir = synqed.Agent(
        name="DetectiveNoir",
        description="1940s detective who sees every situation as a mystery to solve",
        skills=[
            {
                "skill_id": "deductive_reasoning",
                "name": "Deductive Reasoning",
                "description": "Sharp detective skills for solving problems and finding patterns",
                "tags": ["detective", "logic", "problem-solving", "observation", "noir"],
            },
            {
                "skill_id": "noir_narrative",
                "name": "Noir Narrative",
                "description": "Frame situations in compelling, dramatic narratives",
                "tags": ["storytelling", "drama", "atmosphere", "creativity"],
            },
        ],
        executor=detective_noir_executor,
    )

    alchemist = synqed.Agent(
        name="AlchemistAurelius",
        description="Medieval alchemist who views everything through transformative processes",
        skills=[
            {
                "skill_id": "alchemical_transformation",
                "name": "Alchemical Transformation",
                "description": "Expert in transmutation and the art of transformation",
                "tags": ["alchemy", "chemistry", "transformation", "elements", "magic"],
            },
            {
                "skill_id": "mystical_cooking",
                "name": "Mystical Cooking",
                "description": "Views culinary arts as alchemical processes",
                "tags": ["cooking", "recipes", "transformation", "elements"],
            },
        ],
        executor=alchemist_executor,
    )

    print("  ⏰ Lady Chronos has arrived from 1885")
    print("  🌌 Nebula Mind has coalesced from the cosmos")
    print("  🕵️  Detective Noir has emerged from the shadows")
    print("  🧪 Alchemist Aurelius has transmuted into presence\n")

    # Start servers
    print("🚀 Establishing dimensional connections...\n")
    
    chronos_server = synqed.AgentServer(lady_chronos, port=8001)
    nebula_server = synqed.AgentServer(nebula_mind, port=8002)
    detective_server = synqed.AgentServer(detective_noir, port=8003)
    alchemist_server = synqed.AgentServer(alchemist, port=8004)

    await chronos_server.start_background()
    await nebula_server.start_background()
    await detective_server.start_background()
    await alchemist_server.start_background()

    print(f"  ✓ Lady Chronos: {lady_chronos.url}")
    print(f"  ✓ Nebula Mind: {nebula_mind.url}")
    print(f"  ✓ Detective Noir: {detective_noir.url}")
    print(f"  ✓ Alchemist Aurelius: {alchemist.url}\n")

    # Create orchestrator
    print("🎭 Creating the Master of Ceremonies...\n")
    
    orchestrator = synqed.Orchestrator(
        provider=synqed.LLMProvider.OPENAI,
        api_key=api_key,
        model="gpt-4o",
    )

    # Set up real-time collaboration display
    print("📡 Setting up real-time collaboration view...\n")
    
    # Track phases for beautiful display
    class CosmicDisplay:
        def __init__(self):
            self.current_phase = None
            self.phase_names = {
                'broadcast': '🤝 GATHERING THE CIRCLE',
                'proposal': '📝 SHARING VISIONS',
                'feedback': '💬 THE GREAT DISCOURSE',
                'refinement': '✨ CREATING THE MASTERPIECE',
            }
            self.icons = {
                'LadyChronos': '⏰👒',
                'NebulaMind': '🌌✨',
                'DetectiveNoir': '🕵️🎩',
                'AlchemistAurelius': '🧪⚗️',
            }
        
        def display_message(self, msg):
            """Display messages as they happen!"""
            msg_type = msg.get('message_type', 'unknown')
            sender = msg.get('sender_name', 'Unknown')
            content = msg.get('content', '')
            
            # Detect phase changes
            new_phase = None
            if 'COLLABORATIVE WORKSPACE SESSION' in content:
                new_phase = 'broadcast'
            elif 'INITIAL PROPOSAL PHASE' in content:
                new_phase = 'proposal'
            elif 'COLLABORATIVE FEEDBACK PHASE' in content:
                new_phase = 'feedback'
            elif 'REFINEMENT PHASE' in content:
                new_phase = 'refinement'
            
            # Show phase header with cosmic flair
            if new_phase and new_phase != self.current_phase:
                if self.current_phase is not None:
                    print("\n")
                print("─" * 80)
                print(f"  ✨ {self.phase_names.get(new_phase, 'PHASE')} ✨")
                print("─" * 80 + "\n")
                self.current_phase = new_phase
            
            # Skip pure system messages
            if msg_type == 'system' and sender == 'System' and 'joined' not in content.lower():
                return
            
            # Show agent messages in real-time!
            if msg_type == 'agent':
                icon = self.icons.get(sender, '💬')
                print(f"\n{icon} {sender} speaks:")
                print("─" * 76)
                
                lines = content.split('\n')
                for line in lines:
                    if line.strip():
                        print(f"  {line}")
                print()
    
    display = CosmicDisplay()

    # Create orchestrated workspace with agent discussion enabled AND real-time view
    print("🏛️  Creating the Interdimensional Salon...\n")
    
    orchestrated = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        enable_agent_discussion=True,  # Enable agents to discuss with each other!
        message_callback=display.display_message,  # Show conversations live!
    )

    orchestrated.register_agent(lady_chronos)
    orchestrated.register_agent(nebula_mind)
    orchestrated.register_agent(detective_noir)
    orchestrated.register_agent(alchemist)

    print("✓ All agents registered in the workspace")
    print("✓ Real-time conversation streaming enabled\n")

    # The main event: planning an extraordinary dinner party
    print("═" * 80)
    print("  🎪 THE GREAT DINNER PARTY PLANNING 🎪")
    print("═" * 80 + "\n")

    task = """Plan an extraordinary dinner party that combines elements from all our unique perspectives. 
    The dinner should include:
    1. A theme that connects Victorian elegance, cosmic wonder, noir mystery, and alchemical transformation
    2. A creative menu with 3 dishes that each agent can contribute ideas for
    3. Entertainment or activities that would fascinate all of us
    4. The perfect setting description
    
    Each agent should contribute their unique perspective, and feel free to discuss ideas with each other!"""

    print("📜 THE CHALLENGE:\n")
    print(task)
    print("\n" + "─" * 80 + "\n")
    
    print("🎬 The agents begin their collaboration...\n")
    print("⭐ WATCH THE MAGIC UNFOLD IN REAL-TIME! ⭐\n")
    print("─" * 80 + "\n")

    # Execute the collaborative task - WATCH IT LIVE!
    result = await orchestrated.execute_task(task)

    # Show summary after the live collaboration
    if result.success:
        print("\n" + "═" * 80)
        print("  📋 EXECUTION PLAN 📋")
        print("═" * 80 + "\n")
        
        print(f"Orchestrator's Reasoning:")
        print(f"  {result.plan.reasoning}\n")
        
        print(f"Subtasks Created: {len(result.plan.subtasks)}")
        for i, subtask in enumerate(result.plan.subtasks, 1):
            print(f"\n  {i}. {subtask.description}")
            print(f"     → Assigned to: {subtask.assigned_agent_name}")
            print(f"     → Status: {subtask.status}")

        print("\n" + "═" * 80)
        print("  🎉 THE FINAL DINNER PARTY PLAN 🎉")
        print("═" * 80 + "\n")
        
        # Display the final synthesized result
        for line in result.final_result.split('\n'):
            if line.strip():
                print(f"  {line}")
        
        print("\n" + "═" * 80 + "\n")

    else:
        print(f"❌ The cosmic alignment failed: {result.error}\n")

    # Cleanup
    print("🌙 The interdimensional salon closes...\n")
    
    await chronos_server.stop()
    await nebula_server.stop()
    await detective_server.stop()
    await alchemist_server.stop()

    print("═" * 80)
    print("  ✨ Until we meet again across time and space! ✨")
    print("═" * 80 + "\n")


if __name__ == "__main__":
    asyncio.run(main())

