"""
Cloud Demo: Synqed Agents with Email Addresses

Shows how to create synqed agents with logic functions that autonomously communicate.

These are REAL synqed agents (like synqed_agent.py):
- Have logic functions (process incoming messages autonomously)
- Have email addresses (alice@wonderland, bob@builder, etc.)
- Can work in local workspaces OR cloud messaging
- You choose the AI provider (Anthropic Claude shown here)

Key concept:
- You send ONE initial message
- Agents autonomously respond using their logic functions
- Conversation continues until agents decide to stop
- Synqed handles: routing, orchestration, memory

Requirements:
- pip install synqed anthropic python-dotenv
- Set ANTHROPIC_API_KEY in .env file
"""

import asyncio
import os
from pathlib import Path
from anthropic import AsyncAnthropic
import synqed

# Load your own .env file (your responsibility, not synqed's)
try:
    from dotenv import load_dotenv
    load_dotenv(Path(__file__).parent.parent / ".env")
except ImportError:
    pass


def should_continue_conversation(message: str) -> bool:
    """Check if the agent wants to continue the conversation."""
    endings = ["goodbye", "bye", "that's all", "thanks for", "thank you for", "nice talking"]
    return not any(ending in message.lower() for ending in endings)


async def main():
    """
    Demo: Create agents with email addresses and let them autonomously communicate.
    """
    
    print("=" * 70)
    print("🌍 Synqed Agents with Email Addresses")
    print("=" * 70)
    print()
    
    # Your Anthropic client (your API key, your responsibility)
    anthropic_key = os.getenv("ANTHROPIC_API_KEY")
    if not anthropic_key:
        print("❌ ANTHROPIC_API_KEY not set!")
        print("   Add to .env: ANTHROPIC_API_KEY=sk-ant-...")
        print("   Or: export ANTHROPIC_API_KEY=sk-ant-...")
        return
    
    anthropic_client = AsyncAnthropic(api_key=anthropic_key)
    
    # Step 1: Create agents with logic functions (like any synqed agent)
    print("STEP 1: Creating agents with email addresses...")
    print()
    
    # Alice - curious explorer agent
    async def alice_logic(context):
        """Alice's AI logic - curious explorer who asks questions"""
        latest = context.latest_message
        if not latest or not latest.content:
            return None
        
        # Get conversation history
        history = context.get_conversation_history()
        
        # Build prompt
        system_prompt = (
            "You are Alice (alice@wonderland), a curious explorer who loves asking questions. "
            "You're talking with Bob (bob@builder), a helpful construction worker. "
            "Respond naturally to his messages. Keep responses to 1-2 sentences. "
            "If the conversation feels complete, say goodbye politely. "
            "Always respond with JSON: {\"send_to\": \"bob\", \"content\": \"your response\"}"
        )
        
        conversation_text = f"Conversation so far:\n{history}\n\nRespond to Bob with JSON:"
        
        # Call Anthropic API (async)
        response = await anthropic_client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=150,
            system=system_prompt,
            messages=[{"role": "user", "content": conversation_text}],
        )
        
        # Return the response text (Agent will auto-parse JSON)
        return response.content[0].text.strip()
    
    alice = synqed.Agent(
        name="alice",
        description="A curious explorer who loves asking questions",
        logic=alice_logic,
        role="wonderland",  # Email: alice@wonderland
        default_target="bob"
    )
    print(f"✓ Created {alice.email}")
    
    # Bob - builder agent
    async def bob_logic(context):
        """Bob's AI logic - helpful builder who solves problems"""
        latest = context.latest_message
        if not latest or not latest.content:
            return None
        
        # Get conversation history
        history = context.get_conversation_history()
        
        # Build prompt
        system_prompt = (
            "You are Bob (bob@builder), a helpful construction worker who solves problems. "
            "You're talking with Alice (alice@wonderland), a curious explorer. "
            "Respond helpfully to her questions. Keep responses to 1-2 sentences. "
            "If she says goodbye or the conversation feels complete, say goodbye back. "
            "Always respond with JSON: {\"send_to\": \"alice\", \"content\": \"your response\"}"
        )
        
        conversation_text = f"Conversation so far:\n{history}\n\nRespond to Alice with JSON:"
        
        # Call Anthropic API (async)
        response = await anthropic_client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=150,
            system=system_prompt,
            messages=[{"role": "user", "content": conversation_text}],
        )
        
        # Return the response text (Agent will auto-parse JSON)
        return response.content[0].text.strip()
    
    bob = synqed.Agent(
        name="bob",
        description="A helpful construction worker who solves problems",
        logic=bob_logic,
        role="builder",  # Email: bob@builder
        default_target="alice"
    )
    print(f"✓ Created {bob.email}")
    
    print()
    
    # Step 2: Register on cloud (agents get email addresses)
    print("STEP 2: Registering agents on cloud...")
    print()
    
    for agent in [alice, bob]:
        try:
            await agent.register()
            print(f"✓ Registered {agent.email}")
        except Exception as e:
            if "409" in str(e):
                print(f"✓ {agent.email} (already registered)")
            else:
                print(f"❌ Registration failed for {agent.email}: {e}")
                return
    
    print()
    
    # Step 3: Register agent runtimes (enables automatic workspace creation)
    print("STEP 3: Registering agent runtimes...")
    print("        (This enables automatic workspace creation when agents communicate)")
    print()
    
    synqed.register_agent_runtime(alice.agent_id, alice)
    synqed.register_agent_runtime(bob.agent_id, bob)
    
    print(f"✓ Registered runtime for {alice.email}")
    print(f"✓ Registered runtime for {bob.email}")
    print()
    
    # Step 4: Send ONE message via cloud - workspace is automatically created!
    print("STEP 4: Sending message via cloud...")
    print("        (Workspace will be automatically created in the background)")
    print()
    
    initial_message = "Hi Bob! I want to build something amazing. Can you help me?"
    print(f"💬 {alice.email} → {bob.email}")
    print(f"   \"{initial_message}\"")
    print()
    
    try:
        # Send message via cloud - synqed automatically creates workspace!
        result = await alice.send(
            to=bob.email,
            content=initial_message,
            via_cloud=True,
        )
        
        print(f"✅ Message sent successfully!")
        print(f"   Message ID: {result.get('message_id', 'N/A')}")
        print()
        
        print("🔄 Background processing:")
        print("   • Synqed inbox worker received the message")
        print("   • Detected both agents have local runtimes")
        print("   • Automatically created workspace in the background")
        print("   • Routed message through workspace")
        print("   • Bob's logic function processed the message")
        print("   • Bob's response sent back to alice automatically")
        print()
        
        # Wait a bit for processing
        print("⏳ Waiting for message processing...")
        await asyncio.sleep(5)
        
    except Exception as e:
        print(f"❌ Error sending message: {e}")
        import traceback
        traceback.print_exc()
    
    print()
    print("=" * 70)
    print("✅ DEMO COMPLETE!")
    print("=" * 70)
    print()
    
    print("What just happened:")
    print("  1. Created 2 agents with email addresses")
    print("  2. Registered them on cloud with cryptographic keys")
    print("  3. Registered their runtimes (enables auto-workspace)")
    print("  4. Sent ONE message from alice to bob via cloud")
    print("  5. Synqed AUTOMATICALLY:")
    print("     • Created a workspace in the background")
    print("     • Routed the message through the workspace")
    print("     • Called bob's logic function")
    print("     • Sent bob's response back to alice")
    print()
    
    print("Key benefit:")
    print("  ✨ No manual workspace creation needed!")
    print("  ✨ Just send messages via email addresses")
    print("  ✨ Synqed handles orchestration automatically")
    print()
    
    print("These are REAL synqed agents:")
    print("  ✅ Have logic functions (autonomously process messages)")
    print("  ✅ Have email addresses (registered on synqed.fly.dev)")
    print("  ✅ Work in local workspaces AND cloud messaging")
    print("  ✅ You choose the AI provider (Anthropic Claude shown here)")
    print("  ✅ Workspaces created automatically when needed!")
    print()
    
    print("This is the SIMPLEST way to use synqed:")
    print("  • Create agents with logic + email (name@role)")
    print("  • Register on cloud: await agent.register()")
    print("  • Register runtime: synqed.register_agent_runtime(agent.agent_id, agent)")
    print("  • Send messages: await agent.send(\"other@email\", \"message\")")
    print("  • That's it! Synqed handles everything else.")
    print()
    
    print("Try it yourself:")
    print("  1. Add to .env: ANTHROPIC_API_KEY=sk-ant-...")
    print("  2. pip install synqed anthropic python-dotenv")
    print("  3. python examples/cloud_demo.py")
    print()


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