"""
Qualtrics Sales Agentification Example

This example demonstrates the agentified sales workforce described in the
Qualtrics 2026 Planning Initiative, where multiple specialized AI agents work
together to support sales representatives.

Architecture:
- Qwin (Orchestrator): Central coordinating agent that delegates to specialists
- ResearchAgent: Conducts internal (customer data) and external (market) research
- ContentAgent: Creates customer-facing presentations and pitches
- AdminAgent: Handles administrative tasks like scheduling and CRM updates
- PipelineAgent: Prioritizes deals and identifies opportunities
- DealAgent: Creates and optimizes quotes with QR calculations

Scenario:
A sales rep needs to prepare for a meeting with an existing customer,
TechCorp Inc., for a potential upsell opportunity. The orchestrator
coordinates all agents to handle research, content creation, deal structuring,
and administrative tasks automatically.

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

import asyncio
import os
import sys
import subprocess
from pathlib import Path
from datetime import datetime
from dotenv import load_dotenv
import synqed

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


def cleanup_ports(ports):
    """Kill any processes using the specified ports."""
    try:
        ports_str = ','.join(map(str, ports))
        subprocess.run(
            f"lsof -ti:{ports_str} | xargs kill -9 2>/dev/null",
            shell=True,
            capture_output=True,
            timeout=5
        )
    except Exception:
        pass  # Ignore errors if no processes found


class OutputLogger:
    """Captures all terminal output and writes it to both terminal and file."""
    
    def __init__(self, filepath):
        self.terminal = sys.stdout
        self.filepath = filepath
        try:
            self.log = open(filepath, 'w', encoding='utf-8', buffering=1)  # Line buffered
            self.file_error = False
        except Exception as e:
            print(f"⚠️  Warning: Could not create log file: {e}", file=sys.stderr)
            self.log = None
            self.file_error = True
    
    def write(self, message):
        try:
            self.terminal.write(message)
            self.terminal.flush()
        except Exception:
            pass  # Continue even if terminal write fails
        
        if self.log is not None:
            try:
                self.log.write(message)
                self.log.flush()  # Flush immediately to ensure output is saved
            except Exception:
                pass  # Continue even if file write fails
    
    def flush(self):
        try:
            self.terminal.flush()
        except Exception:
            pass
        if self.log is not None:
            try:
                self.log.flush()
            except Exception:
                pass
    
    def close(self):
        if self.log is not None:
            try:
                self.log.flush()
                self.log.close()
            except Exception:
                pass
    
    def isatty(self):
        """Return whether this is an interactive terminal."""
        try:
            return self.terminal.isatty() if hasattr(self.terminal, 'isatty') else False
        except Exception:
            return False
    
    def fileno(self):
        """Return the file descriptor."""
        try:
            return self.terminal.fileno() if hasattr(self.terminal, 'fileno') else -1
        except Exception:
            return -1


async def main():
    # Clean up any processes from previous runs
    print("🧹 Cleaning up ports from previous runs...")
    cleanup_ports([8001, 8002, 8003, 8004, 8005])
    await asyncio.sleep(1)  # Give OS time to release ports
    print("✓ Ports cleaned up\n")
    
    # 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("  QUALTRICS SALES AGENTIFICATION - 2026 VISION")
    print("  AI-to-AI Autonomous Agent Collaboration Demo")
    print("=" * 80 + "\n")
    
    print("🤖↔🤖 AUTONOMOUS AI-TO-AI INTERACTION DEMONSTRATION")
    print("-" * 80)
    print("This demo showcases multiple scenarios of AI agents autonomously")
    print("discovering, communicating, and collaborating using the A2A protocol.\n")
    
    print("What makes this AI-to-AI (not just automation):")
    print("  ✓ Agents autonomously discover each other's capabilities")
    print("  ✓ Orchestrator AI delegates to specialist AIs without human input")
    print("  ✓ Multiple AI agents execute work in parallel")
    print("  ✓ Agents communicate via standardized A2A protocol")
    print("  ✓ Results synthesized by orchestrator AI automatically\n")
    
    print("You'll see 3 different AI-to-AI collaboration scenarios:")
    print("  1. Complex multi-agent sales preparation (5 agents)")
    print("  2. Quick research + content collaboration (2 agents)")
    print("  3. Deal-focused pipeline + quote workflow (2 agents)\n")
    
    print("=" * 80 + "\n")

    # ====================================================================
    # STEP 1: CREATE SPECIALIZED SALES AGENTS
    # ====================================================================
    print("🏗️  Building Specialized Sales Support Agents...\n")

    # Helper to create OpenAI client
    async def create_agent_executor(system_prompt: str, temperature: float = 0.3):
        """Factory function to create specialized agent executors."""
        async def executor(context):
            user_message = context.get_user_input()
            from openai import AsyncOpenAI
            
            # This executor will be called when an agent receives a task
            client = AsyncOpenAI(api_key=api_key)
            response = await client.chat.completions.create(
                model="gpt-4o-mini",
                messages=[
                    {"role": "system", "content": system_prompt},
                    {"role": "user", "content": user_message},
                ],
                temperature=temperature,
            )
            return response.choices[0].message.content
        return executor
    
    print("Creating agent executors (the 'brains' of each specialized agent)...")
    print("Each agent will use GPT-4o-mini with custom system prompts\n")
    
    # Create colored printer for real-time message display
    colored_printer = synqed.create_colored_printer()
    
    # Track which workspace we're in for context
    current_workspace = {"name": ""}
    
    def real_time_message_handler(sender: str, content: str, msg_type: str = "agent"):
        """Display messages in real-time as agents communicate."""
        # Determine icon based on agent
        if sender == 'System':
            icon = "⚙️"
            color_code = "\033[90m"  # Gray
        elif 'Orchestrator' in sender or 'Qwin' in sender:
            icon = "🎯"
            color_code = "\033[94m"  # Blue
        elif 'Research' in sender:
            icon = "🔍"
            color_code = "\033[92m"  # Green
        elif 'Content' in sender:
            icon = "📝"
            color_code = "\033[93m"  # Yellow
        elif 'Admin' in sender:
            icon = "📅"
            color_code = "\033[95m"  # Magenta
        elif 'Pipeline' in sender:
            icon = "📊"
            color_code = "\033[96m"  # Cyan
        elif 'Deal' in sender:
            icon = "💰"
            color_code = "\033[91m"  # Red
        else:
            icon = "💬"
            color_code = "\033[37m"  # White
        
        reset = "\033[0m"
        
        # Print complete content (no truncation)
        display_content = content
        
        # Print in real-time
        print(f"{color_code}{icon} {sender}:{reset}")
        for line in display_content.split('\n'):
            if line.strip():  # Only print non-empty lines
                print(f"  {line}")
        print()  # Blank line after message
    
    print("✓ Real-time message display enabled - you'll see AI conversations as they happen!\n")

    # Research Agent - Internal & External Customer Research
    print("🔍 Creating ResearchAgent...")
    print("   └─ Skills: Internal research, external research, opportunity identification")
    research_agent = synqed.Agent(
        name="ResearchAgent",
        description="Conducts comprehensive customer research (internal usage data and external market intelligence)",
        skills=[
            {
                "skill_id": "internal_research",
                "name": "Internal Customer Research",
                "description": "Analyzes customer contracts, licenses, product usage, and historical data from Salesforce and internal systems",
                "tags": ["salesforce", "customer-data", "contracts", "licenses", "usage-analytics"],
            },
            {
                "skill_id": "external_research",
                "name": "External Market Research",
                "description": "Researches customer's market position, competitors, industry trends, and business challenges",
                "tags": ["market-research", "competitive-intelligence", "industry-trends", "prospect-analysis"],
            },
            {
                "skill_id": "opportunity_identification",
                "name": "Opportunity Identification",
                "description": "Identifies upsell and cross-sell opportunities based on research",
                "tags": ["upsell", "cross-sell", "opportunity-detection"],
            },
        ],
        executor=await create_agent_executor(
            system_prompt="""You are an expert research analyst for Qualtrics sales.
            
Your role:
- Analyze internal customer data (contracts, licenses, usage patterns, support history)
- Conduct external research (company news, market position, competitors, industry trends)
- Identify upsell and renewal opportunities
- Provide actionable insights for sales conversations

Format your research with clear sections:
1. INTERNAL DATA SUMMARY
2. EXTERNAL MARKET INTELLIGENCE
3. KEY OPPORTUNITIES IDENTIFIED
4. RECOMMENDED TALKING POINTS

Be thorough, fact-based, and highlight opportunities for Qualtrics solutions.""",
            temperature=0.3,
        ),
    )

    
    print("📝 Creating ContentAgent...")
    print("   └─ Skills: Presentation creation, proposal writing, demo scripting")
    # Content Agent - Customer-Facing Content Creation
    content_agent = synqed.Agent(
        name="ContentAgent",
        description="Creates tailored customer-facing content including pitch decks, proposals, and demo scripts",
        skills=[
            {
                "skill_id": "presentation_creation",
                "name": "Presentation Creation",
                "description": "Builds customized pitch decks using approved Qualtrics templates",
                "tags": ["presentations", "pitch-decks", "slides", "powerpoint"],
            },
            {
                "skill_id": "proposal_writing",
                "name": "Proposal Writing",
                "description": "Drafts compelling proposals tailored to customer needs",
                "tags": ["proposals", "business-cases", "roi-analysis"],
            },
            {
                "skill_id": "demo_scripting",
                "name": "Demo Scripting",
                "description": "Creates personalized product demo scripts based on customer use cases",
                "tags": ["demos", "product-showcases", "use-cases"],
            },
        ],
        executor=await create_agent_executor(
            system_prompt="""You are a Qualtrics content specialist creating customer-facing materials.

Your role:
- Create compelling, customized pitch decks using Qualtrics-approved templates
- Write clear, benefit-focused proposals that resonate with customer needs
- Develop personalized demo scripts that showcase relevant features
- Ensure all content aligns with Qualtrics brand voice and messaging

Structure your content professionally with:
- Executive summary
- Current state analysis
- Proposed solution
- Expected outcomes and ROI
- Next steps

Use persuasive but authentic language. Focus on customer value.""",
            temperature=0.7,
        ),
    )

    
    print("📅 Creating AdminAgent...")
    print("   └─ Skills: Calendar management, note-taking, CRM updates, follow-ups")
    # Admin Agent - Administrative Task Automation
    admin_agent = synqed.Agent(
        name="AdminAgent",
        description="Handles administrative tasks including scheduling, note-taking, follow-ups, and CRM updates",
        skills=[
            {
                "skill_id": "calendar_management",
                "name": "Calendar Management",
                "description": "Schedules meetings, sends invites, and manages calendar conflicts",
                "tags": ["scheduling", "calendar", "meetings", "coordination"],
            },
            {
                "skill_id": "note_taking",
                "name": "Meeting Notes & Summaries",
                "description": "Takes detailed meeting notes and creates action-item summaries",
                "tags": ["notes", "minutes", "summaries", "action-items"],
            },
            {
                "skill_id": "crm_updates",
                "name": "CRM Updates",
                "description": "Updates Salesforce with meeting notes, next steps, and deal progress",
                "tags": ["salesforce", "crm", "data-entry", "updates"],
            },
            {
                "skill_id": "follow_ups",
                "name": "Follow-Up Management",
                "description": "Drafts follow-up emails and tracks action items",
                "tags": ["email", "follow-up", "communication", "tracking"],
            },
        ],
        executor=await create_agent_executor(
            system_prompt="""You are an executive administrative assistant for Qualtrics sales reps.

Your role:
- Schedule meetings efficiently, checking availability and sending professional invites
- Take comprehensive meeting notes with clear action items
- Update Salesforce/CRM with accurate, timely information
- Draft professional follow-up emails
- Track and remind about pending action items

Be detail-oriented, organized, and proactive. Always confirm details and maintain
professional communication standards.""",
            temperature=0.4,
        ),
    )

    
    print("📊 Creating PipelineAgent...")
    print("   └─ Skills: Deal prioritization, risk detection, opportunity tracking")
    # Pipeline Agent - Deal Prioritization & Management
    pipeline_agent = synqed.Agent(
        name="PipelineAgent",
        description="Analyzes pipeline, prioritizes deals, and surfaces renewal and upsell opportunities",
        skills=[
            {
                "skill_id": "prioritization",
                "name": "Deal Prioritization",
                "description": "Ranks deals by urgency, size, close probability, and strategic value",
                "tags": ["prioritization", "pipeline-management", "deal-scoring"],
            },
            {
                "skill_id": "risk_detection",
                "name": "Risk Detection",
                "description": "Identifies at-risk deals and renewal concerns before customer conversations",
                "tags": ["risk-analysis", "churn-prevention", "early-warning"],
            },
            {
                "skill_id": "opportunity_tracking",
                "name": "Opportunity Tracking",
                "description": "Monitors and surfaces upsell/renewal opportunities with timing recommendations",
                "tags": ["opportunities", "upsell", "renewals", "expansion"],
            },
        ],
        executor=await create_agent_executor(
            system_prompt="""You are a Qualtrics sales pipeline analyst and strategist.

Your role:
- Analyze the entire sales pipeline and prioritize deals systematically
- Score opportunities based on: deal size, urgency, close probability, strategic fit
- Identify at-risk deals and recommend mitigation strategies
- Surface timely upsell and renewal opportunities
- Provide daily action recommendations for maximum impact

Format recommendations with:
1. PRIORITY DEALS (with reasoning)
2. AT-RISK ACCOUNTS (with mitigation steps)
3. OPPORTUNITY PIPELINE (with timing)
4. RECOMMENDED DAILY ACTIONS

Be strategic, data-driven, and action-oriented.""",
            temperature=0.3,
        ),
    )

    
    print("💰 Creating DealAgent...")
    print("   └─ Skills: Quote generation, QR calculation, partner identification")
    # Deal Agent - Quote Creation & Optimization
    deal_agent = synqed.Agent(
        name="DealAgent",
        description="Creates optimized quotes with accurate QR calculations and identifies partner opportunities",
        skills=[
            {
                "skill_id": "quote_generation",
                "name": "Quote Generation",
                "description": "Creates well-structured, competitively priced quotes with proper discounting",
                "tags": ["quoting", "pricing", "deal-structure", "discounting"],
            },
            {
                "skill_id": "qr_calculation",
                "name": "QR Calculation",
                "description": "Calculates accurate Quality Revenue (QR) metrics and flags complexities",
                "tags": ["qr", "quality-revenue", "metrics", "crediting"],
            },
            {
                "skill_id": "partner_identification",
                "name": "Partner Identification",
                "description": "Identifies relevant implementation partners to enhance deal success",
                "tags": ["partners", "implementation", "services"],
            },
            {
                "skill_id": "deal_optimization",
                "name": "Deal Optimization",
                "description": "Optimizes deal structure for mutual value and approval likelihood",
                "tags": ["optimization", "value-engineering", "deal-strategy"],
            },
        ],
        executor=await create_agent_executor(
            system_prompt="""You are a Qualtrics Deal Desk specialist and strategic pricing expert.

Your role:
- Create well-structured quotes following Qualtrics pricing guidelines
- Calculate accurate QR (Quality Revenue) and flag any complexities requiring crediting team review
- Recommend implementation partners when appropriate
- Optimize deal structure for customer value and Qualtrics profitability
- Ensure quotes meet approval requirements and minimize back-and-forth

Provide quotes with:
1. QUOTE SUMMARY (products, quantities, pricing)
2. QR CALCULATION (with any flags for manual review)
3. PARTNER RECOMMENDATIONS (if applicable)
4. DEAL NOTES (structure, discounts, special terms)
5. APPROVAL REQUIREMENTS

Be thorough, compliant, and strategic.""",
            temperature=0.2,
        ),
    )

    
    print("\n" + "─" * 80)
    print("✅ All 5 specialized agents created successfully!")
    print("─" * 80 + "\n")

    # ====================================================================
    # STEP 2: START AGENT SERVERS
    # ====================================================================
    print("🚀 Starting Agent Servers (A2A Protocol Endpoints)...\n")
    print("Each agent will run on its own HTTP server using the A2A protocol.")
    print("This allows Qwin to discover and communicate with them.\n")

    print("Creating server instances...")
    research_server = synqed.AgentServer(research_agent, port=8001)
    content_server = synqed.AgentServer(content_agent, port=8002)
    admin_server = synqed.AgentServer(admin_agent, port=8003)
    pipeline_server = synqed.AgentServer(pipeline_agent, port=8004)
    deal_server = synqed.AgentServer(deal_agent, port=8005)
    print("✓ Server instances created\n")

    print("Starting servers in background (this may take a moment)...")
    
    print(f"  ⏳ Starting ResearchAgent on port 8001...")
    await research_server.start_background()
    await asyncio.sleep(0.5)  # Extra time per server
    print(f"     ✓ ResearchAgent: {research_agent.url}")
    
    print(f"  ⏳ Starting ContentAgent on port 8002...")
    await content_server.start_background()
    await asyncio.sleep(0.5)
    print(f"     ✓ ContentAgent: {content_agent.url}")
    
    print(f"  ⏳ Starting AdminAgent on port 8003...")
    await admin_server.start_background()
    await asyncio.sleep(0.5)
    print(f"     ✓ AdminAgent: {admin_agent.url}")
    
    print(f"  ⏳ Starting PipelineAgent on port 8004...")
    await pipeline_server.start_background()
    await asyncio.sleep(0.5)
    print(f"     ✓ PipelineAgent: {pipeline_agent.url}")
    
    print(f"  ⏳ Starting DealAgent on port 8005...")
    await deal_server.start_background()
    await asyncio.sleep(0.5)
    print(f"     ✓ DealAgent: {deal_agent.url}\n")
    
    print("⏳ Waiting for all servers to be fully ready (5 seconds)...")
    await asyncio.sleep(5)  # Give uvicorn time to fully bind and start
    print("✓ Wait complete!\n")
    
    # Verify servers are actually responding
    print("🔍 Verifying server connectivity...")
    import aiohttp
    
    servers_to_check = [
        ("ResearchAgent", research_agent.url),
        ("ContentAgent", content_agent.url),
        ("AdminAgent", admin_agent.url),
        ("PipelineAgent", pipeline_agent.url),
        ("DealAgent", deal_agent.url),
    ]
    
    async with aiohttp.ClientSession() as session:
        for name, url in servers_to_check:
            try:
                async with session.get(f"{url}/.well-known/agent-card.json", timeout=aiohttp.ClientTimeout(total=3)) as response:
                    if response.status == 200:
                        print(f"  ✅ {name} responding at {url}")
                    else:
                        print(f"  ⚠️  {name} returned status {response.status}")
            except Exception as e:
                print(f"  ❌ {name} not responding: {str(e)[:50]}")
    
    print()

    print("─" * 80)
    print("✅ Server startup complete!")
    print("─" * 80 + "\n")

    # ====================================================================
    # STEP 3: CREATE QWIN ORCHESTRATOR
    # ====================================================================
    print("🤖 Creating Qwin - The Orchestrator Agent...\n")
    print("Qwin will act as the 'Agent of Agents' - the central coordinator.")
    print("It uses GPT-4o (more powerful model) for intelligent task planning.\n")

    orchestrator = synqed.Orchestrator(
        provider=synqed.LLMProvider.OPENAI,
        api_key=api_key,
        model="gpt-4o",
        temperature=0.3,
    )

    print("─" * 80)
    print("✅ Qwin orchestrator created and ready to plan complex tasks!")
    print("─" * 80 + "\n")

    # ====================================================================
    # STEP 4: CREATE ORCHESTRATED WORKSPACE
    # ====================================================================
    print("🏗️  Creating Orchestrated Sales Workspace...\n")
    print("The workspace enables:")
    print("  • Automatic task decomposition")
    print("  • Intelligent agent selection")
    print("  • Parallel execution where possible")
    print("  • Inter-agent communication")
    print("  • Result synthesis\n")

    # Create message callback for real-time display
    def message_callback(msg_dict):
        """Real-time message handler for workspace messages."""
        sender = msg_dict.get('sender_name', 'System')
        content = msg_dict.get('content', '')
        real_time_message_handler(sender, content)
    
    orchestrated_workspace = synqed.OrchestratedWorkspace(
        orchestrator=orchestrator,
        enable_agent_discussion=True,
        workspace_persistence=True,
        message_callback=message_callback,
    )

    print("Registering agents with the orchestrator...")
    print("(This allows Qwin to discover agents and fetch their capabilities)\n")
    
    # Import aiohttp for health checks
    import aiohttp
    
    # Helper function to check if server is ready
    async def wait_for_server(url, agent_name, max_retries=10):
        """Wait for a server to be ready to accept connections."""
        for i in range(max_retries):
            try:
                async with aiohttp.ClientSession() as session:
                    async with session.get(f"{url}/.well-known/agent-card.json", timeout=aiohttp.ClientTimeout(total=2)) as response:
                        if response.status == 200:
                            return True
            except Exception:
                if i < max_retries - 1:
                    await asyncio.sleep(0.5)
                continue
        return False
    
    # Wait for each server and register
    print("  ⏳ Checking ResearchAgent availability...")
    if await wait_for_server(research_agent.url, "ResearchAgent"):
        orchestrated_workspace.register_agent(research_agent)
        print("  ✓ Registered ResearchAgent")
    else:
        print("  ⚠️  ResearchAgent not ready, skipping...")
    
    print("  ⏳ Checking ContentAgent availability...")
    if await wait_for_server(content_agent.url, "ContentAgent"):
        orchestrated_workspace.register_agent(content_agent)
        print("  ✓ Registered ContentAgent")
    else:
        print("  ⚠️  ContentAgent not ready, skipping...")
    
    print("  ⏳ Checking AdminAgent availability...")
    if await wait_for_server(admin_agent.url, "AdminAgent"):
        orchestrated_workspace.register_agent(admin_agent)
        print("  ✓ Registered AdminAgent")
    else:
        print("  ⚠️  AdminAgent not ready, skipping...")
    
    print("  ⏳ Checking PipelineAgent availability...")
    if await wait_for_server(pipeline_agent.url, "PipelineAgent"):
        orchestrated_workspace.register_agent(pipeline_agent)
        print("  ✓ Registered PipelineAgent")
    else:
        print("  ⚠️  PipelineAgent not ready, skipping...")
    
    print("  ⏳ Checking DealAgent availability...")
    if await wait_for_server(deal_agent.url, "DealAgent"):
        orchestrated_workspace.register_agent(deal_agent)
        print("  ✓ Registered DealAgent")
    else:
        print("  ⚠️  DealAgent not ready, skipping...")
    
    print()

    print("─" * 80)
    print(f"✅ Orchestrated workspace ready with {len(orchestrated_workspace._agents)} specialized agents!")
    print("─" * 80 + "\n")

    # ====================================================================
    # STEP 5: EXECUTE REALISTIC SALES SCENARIO
    # ====================================================================
    print("=" * 80)
    print("SALES SCENARIO: PREPARING FOR UPSELL OPPORTUNITY")
    print("=" * 80 + "\n")

    # Realistic sales request from a rep
    sales_request = """
    I have a meeting tomorrow at 2pm with TechCorp Inc. - they're an existing customer
    currently on our Customer Experience (CX) platform with 500 licenses.
    
    Their contract is up for renewal in 60 days, and I've heard they're expanding
    their employee experience initiatives. I want to:
    
    1. Understand their current usage and any opportunities for upsell
    2. Research their recent company initiatives and market position
    3. Create a compelling pitch deck for expanding to our Employee Experience (EX) platform
    4. Get a preliminary quote for adding EX licenses
    5. Schedule a follow-up meeting and prepare talking points
    
    Customer Context:
    - Company: TechCorp Inc.
    - Industry: Enterprise Software
    - Current Product: Qualtrics CX (500 licenses)
    - Contract Value: $250K annually
    - Renewal Date: 60 days out
    - Contact: Sarah Johnson, VP of Customer Success
    - Recent Intel: Company announced 30% headcount growth this quarter
    
    Help me prepare for this strategically important meeting.
    """

    print("📨 Sales Rep Request:")
    print("-" * 80)
    print(sales_request.strip())
    print("\n" + "-" * 80 + "\n")

    print("=" * 80)
    print("ORCHESTRATION PROCESS STARTING")
    print("=" * 80 + "\n")
    
    print("Phase 1: ANALYSIS")
    print("🤖 Qwin is analyzing the sales request...")
    print("   └─ Understanding requirements and context")
    print("   └─ Identifying needed capabilities\n")
    
    print("Phase 2: PLANNING")
    print("📋 Breaking down into specialized subtasks...")
    print("   └─ Decomposing complex task into manageable pieces")
    print("   └─ Identifying dependencies between subtasks\n")
    
    print("Phase 3: AGENT SELECTION")
    print("🎯 Selecting the best agents for each subtask...")
    print("   └─ Matching subtask requirements to agent skills")
    print("   └─ Optimizing for parallel execution where possible\n")
    
    print("Phase 4: AGENT DISCOVERY (🤖↔🤖 AI-to-AI)")
    print("🔍 Orchestrator AI autonomously discovering specialist AI capabilities...")
    print("   └─ GET /.well-known/agent-card.json (A2A standard)")
    print("   └─ AIs exchange capability metadata without human intervention")
    print("   └─ Orchestrator learns what each AI agent can do\n")
    
    print("Phase 5: TASK DELEGATION (🤖→🤖 AI-to-AI)")
    print("📤 Orchestrator AI delegating to specialist AIs autonomously...")
    print("   └─ POST / with task context (A2A protocol)")
    print("   └─ Each AI receives its assignment programmatically")
    print("   └─ WATCH: HTTP logs show LIVE AI-to-AI communication!\n")
    
    print("Phase 6: PARALLEL EXECUTION (🤖⚡🤖⚡🤖 Multi-AI)")
    print("⚡ Multiple AI agents working simultaneously...")
    print("   └─ Each AI independently processes its subtask")
    print("   └─ No human coordination needed - fully autonomous")
    print("   └─ AIs complete and report back asynchronously\n")
    
    print("=" * 80)
    print("Watch below for REAL-TIME AI-TO-AI MESSAGES as they happen!")
    print("=" * 80 + "\n")
    
    print("┌" + "─" * 78 + "┐")
    print("│" + " LIVE WORKSPACE - AI AGENTS COMMUNICATING IN REAL-TIME ".center(78) + "│")
    print("└" + "─" * 78 + "┘\n")
    
    current_workspace["name"] = "Scenario 1: TechCorp Upsell"

    # Execute the complex sales preparation task
    # Note: OrchestratedWorkspace collects messages internally
    # We'll display them as we process the result
    print("🔴 LIVE: Agents starting work...\n")
    
    result = await orchestrated_workspace.execute_task(
        task=sales_request,
        workspace_name="TechCorp Upsell Preparation",
    )
    
    print("\n" + "=" * 80)
    print("🎊 AI-TO-AI COLLABORATION #1 COMPLETE!")
    print("=" * 80 + "\n")

    # ====================================================================
    # STEP 6: DISPLAY COMPREHENSIVE RESULTS
    # ====================================================================
    print("=" * 80)
    print("SCENARIO #1 RESULTS: Complex Multi-Agent Sales Preparation")
    print("=" * 80 + "\n")

    if result.success:
        print("🎉 SUCCESS! The sales preparation task completed successfully!\n")
        print("All agents collaborated effectively to prepare comprehensive")
        print("meeting materials for the TechCorp upsell opportunity.\n")

        # Show orchestration plan
        print("📋 QWIN'S ORCHESTRATION PLAN")
        print("-" * 80)
        print(f"Total Subtasks: {len(result.plan.subtasks)}")
        print(f"Agents Activated: {len(result.plan.selected_agents)}")
        print(f"Execution Stages: {len(result.plan.execution_order)}\n")
        
        print("Orchestrator's Strategic Reasoning:")
        print(result.plan.reasoning)
        print("\n" + "-" * 80 + "\n")

        # Show subtask assignments
        print("🎯 TASK DECOMPOSITION & AGENT ASSIGNMENTS")
        print("-" * 80 + "\n")
        
        for i, subtask in enumerate(result.plan.subtasks, 1):
            status_icon = "✅" if subtask.status == "completed" else "⏳"
            print(f"{status_icon} Subtask {i}: {subtask.description}")
            print(f"   └─ Assigned to: {subtask.assigned_agent_name}")
            print(f"   └─ Order: {subtask.order}")
            if subtask.dependencies:
                print(f"   └─ Dependencies: {', '.join(subtask.dependencies)}")
            print()

        # Show execution stages (parallel execution)
        print("-" * 80)
        print("\n⚡ EXECUTION STAGES (Parallel Optimization)")
        print("-" * 80 + "\n")
        
        for i, stage in enumerate(result.plan.execution_order, 1):
            print(f"Stage {i}: {len(stage)} subtask(s)")
            if len(stage) > 1:
                print("  (Executed in parallel for speed)")
            for subtask_id in stage:
                subtask = next(st for st in result.plan.subtasks if st.subtask_id == subtask_id)
                print(f"  • {subtask.assigned_agent_name}: {subtask.description}")
            print()

        # Show complete workspace message history (ALL INTERACTIONS)
        print("\n" + "=" * 80)
        print("💬 INSIDE THE WORKSPACE - AGENT-TO-AGENT INTERACTIONS")
        print("=" * 80)
        print(f"\nTotal messages exchanged: {len(result.workspace_messages)}")
        print("\nThis shows the LIVE conversation happening inside the workspace.")
        print("Watch how agents receive tasks, perform work, and communicate results.")
        print("This is the AI-to-AI collaboration happening in real-time!\n")
        print("=" * 80 + "\n")
        
        # Display workspace interactions with simulated real-time playback
        print("🎭 WORKSPACE CONVERSATION PLAYBACK\n")
        print("Showing the AI-to-AI conversation that just occurred:")
        print("(Displayed with slight delays to simulate real-time flow)\n")
        print("─" * 80 + "\n")
        
        # Import time for simulated real-time display
        import time
        
        # Group messages by conversation flow
        conversation_num = 0
        for i, msg in enumerate(result.workspace_messages, 1):
            sender = msg.get('sender_name', 'System')
            content = msg.get('content', '')
            msg_type = msg.get('message_type', 'unknown')
            
            # Skip empty or very short messages
            if not content or len(content.strip()) < 10:
                continue
            
            # Determine icon and formatting based on sender
            if sender == 'System':
                icon = "⚙️"
                color_code = "\033[90m"  # Gray
            elif 'Orchestrator' in sender or 'Qwin' in sender:
                icon = "🎯"
                color_code = "\033[94m"  # Blue
            elif 'Research' in sender:
                icon = "🔍"
                color_code = "\033[92m"  # Green
            elif 'Content' in sender:
                icon = "📝"
                color_code = "\033[93m"  # Yellow
            elif 'Admin' in sender:
                icon = "📅"
                color_code = "\033[95m"  # Magenta
            elif 'Pipeline' in sender:
                icon = "📊"
                color_code = "\033[96m"  # Cyan
            elif 'Deal' in sender:
                icon = "💰"
                color_code = "\033[91m"  # Red
            else:
                icon = "💬"
                color_code = "\033[37m"
            
            reset = "\033[0m"
            conversation_num += 1
            
            # Format as conversation
            print(f"{color_code}{icon} {sender}:{reset}")
            
            # Display complete content (no truncation)
            display_content = content
            
            # Indent content for readability
            lines = display_content.split('\n')
            for line in lines:
                if line.strip():  # Only print non-empty lines
                    print(f"  {line}")
            
            print()  # Blank line between messages
            
            # Simulate real-time with small delay between messages
            time.sleep(0.1)
            
            # Add separator every few messages for clarity
            if conversation_num % 3 == 0 and conversation_num < len(result.workspace_messages):
                print("  " + "·" * 76)
                print()
        
        print("─" * 80)
        print(f"✓ {conversation_num} messages exchanged in workspace")
        print("─" * 80 + "\n")
        
        # Show individual agent results
        print("-" * 80)
        print("\n📝 INDIVIDUAL AGENT OUTPUTS (Detailed)")
        print("-" * 80 + "\n")
        
        for subtask in result.plan.subtasks:
            subtask_result = result.subtask_results.get(subtask.subtask_id, "No result")
            print(f"{'='*80}")
            print(f"🤖 {subtask.assigned_agent_name}")
            print(f"{'='*80}")
            print(f"Subtask ID: {subtask.subtask_id}")
            print(f"Task: {subtask.description}")
            print(f"Status: {subtask.status}")
            print(f"Order: {subtask.order}")
            if subtask.dependencies:
                print(f"Dependencies: {', '.join(subtask.dependencies)}")
            print(f"\nComplete Output:")
            print("-" * 80)
            print(subtask_result)
            print(f"\n{'='*80}\n")

        # Show final synthesized result
        print("=" * 80)
        print("🎉 FINAL SYNTHESIZED RESULT - READY FOR SALES REP")
        print("=" * 80 + "\n")
        print(result.final_result)
        print("\n" + "=" * 80 + "\n")

        # Show workspace metadata and interaction analysis
        print("📊 WORKSPACE STATISTICS & INTERACTION ANALYSIS")
        print("-" * 80)
        print(f"Workspace ID: {result.workspace_id}")
        print(f"Subtasks Executed: {result.metadata['num_subtasks']}")
        print(f"Agents Collaborated: {result.metadata['num_agents']}")
        print(f"Total Messages: {len(result.workspace_messages)}")
        print(f"Execution Time: {result.metadata.get('execution_time', 'N/A')}")
        print()
        
        # Analyze message patterns
        print("Message Breakdown by Type:")
        msg_type_counts = {}
        for msg in result.workspace_messages:
            msg_type = msg.get('message_type', 'unknown')
            msg_type_counts[msg_type] = msg_type_counts.get(msg_type, 0) + 1
        
        for msg_type, count in sorted(msg_type_counts.items(), key=lambda x: x[1], reverse=True):
            print(f"  • {msg_type}: {count} messages")
        print()
        
        # Analyze agent participation
        print("Agent Participation:")
        agent_msg_counts = {}
        for msg in result.workspace_messages:
            sender = msg.get('sender_name', 'Unknown')
            if sender != 'Unknown' and sender != 'System':
                agent_msg_counts[sender] = agent_msg_counts.get(sender, 0) + 1
        
        for agent, count in sorted(agent_msg_counts.items(), key=lambda x: x[1], reverse=True):
            print(f"  • {agent}: {count} messages")
        print()
        
        # Show collaboration pattern
        print("Collaboration Pattern:")
        for i, stage in enumerate(result.plan.execution_order, 1):
            agents_in_stage = []
            for subtask_id in stage:
                subtask = next(st for st in result.plan.subtasks if st.subtask_id == subtask_id)
                agents_in_stage.append(subtask.assigned_agent_name)
            
            if len(agents_in_stage) > 1:
                print(f"  Stage {i}: {', '.join(agents_in_stage)} (parallel)")
            else:
                print(f"  Stage {i}: {agents_in_stage[0]}")
        print()

        # Show productivity impact
        print("-" * 80)
        print("\n💡 PRODUCTIVITY IMPACT")
        print("-" * 80)
        print("""
Without Agentification:
  - Manual research: 2-3 hours
  - Content creation: 2-3 hours  
  - Quote preparation: 1-2 hours
  - Admin tasks: 1 hour
  - Total: 6-9 hours of work

With Qwin & Agent Team:
  - Total time: < 5 minutes
  - Time saved: ~8 hours
  - Seller can focus on: Customer relationship and strategic conversation
  
The seller now has comprehensive preparation for a high-value meeting,
delivered in minutes instead of hours, allowing them to focus on what
they do best: building customer relationships and closing deals.
        """)

    else:
        print("❌ Task execution failed\n")
        print(f"Error: {result.error}\n")

    # ====================================================================
    # SCENARIO #2: QUICK RESEARCH + CONTENT COLLABORATION
    # ====================================================================
    print("\n" + "=" * 80)
    print("🤖↔🤖 SCENARIO #2: AI-TO-AI RESEARCH + CONTENT COLLABORATION")
    print("=" * 80 + "\n")
    print("Demonstrating: 2 AI agents collaborating autonomously")
    print("  • ResearchAgent gathers competitive intelligence")
    print("  • ContentAgent creates content based on research")
    print("  • Sequential dependency: Content depends on Research\n")
    
    scenario_2_task = """
    Quick task: Research our top 3 competitors in the Experience Management space
    and create a brief competitive positioning document for our sales team.
    Focus on key differentiators.
    """
    
    print("Task for AI Agents:")
    print(scenario_2_task.strip() + "\n")
    print("🤖 Orchestrator analyzing and decomposing task...")
    print("🔍 AI agents discovering each other...")
    print("📤 Delegating research to ResearchAgent, content to ContentAgent...\n")
    
    print("┌" + "─" * 78 + "┐")
    print("│" + " LIVE WORKSPACE #2 - SEQUENTIAL AI COLLABORATION ".center(78) + "│")
    print("└" + "─" * 78 + "┘\n")
    
    current_workspace["name"] = "Scenario 2: Competitive Intelligence"
    print("🔴 LIVE: Research → Content (sequential workflow)...\n")
    
    result_2 = await orchestrated_workspace.execute_task(
        task=scenario_2_task,
        workspace_name="Competitive Intelligence Brief",
    )
    
    print("\n" + "=" * 80)
    print("🎊 AI-TO-AI COLLABORATION #2 COMPLETE!")
    print("=" * 80 + "\n")
    
    if result_2.success:
        print("✅ Two AI agents collaborated successfully!\n")
        print("📋 Execution Pattern:")
        print(f"  • Subtasks created: {len(result_2.plan.subtasks)}")
        print(f"  • Agents used: {', '.join(result_2.plan.selected_agents)}")
        print(f"  • Stages: {len(result_2.plan.execution_order)} (showing dependencies)\n")
        
        print("🤖 Agent Collaboration Flow:")
        for i, subtask in enumerate(result_2.plan.subtasks, 1):
            deps = f" (depends on: {', '.join(subtask.dependencies)})" if subtask.dependencies else " (independent)"
            print(f"  {i}. {subtask.assigned_agent_name}: {subtask.description}{deps}")
        
        # Show workspace interactions for scenario 2 with simulated real-time
        print("\n" + "─" * 80)
        print("💬 WORKSPACE #2 CONVERSATION PLAYBACK:")
        print("─" * 80 + "\n")
        
        import time
        
        for i, msg in enumerate(result_2.workspace_messages, 1):
            sender = msg.get('sender_name', 'System')
            content = msg.get('content', '')
            
            if not content or len(content.strip()) < 10:
                continue
            
            if "Research" in sender:
                icon = "🔍"
                color_code = "\033[92m"
            elif "Content" in sender:
                icon = "📝"
                color_code = "\033[93m"
            else:
                icon = "⚙️"
                color_code = "\033[90m"
            
            reset = "\033[0m"
            
            print(f"{color_code}{icon} {sender}:{reset}")
            
            # Display complete content (no truncation)
            display_content = content
            for line in display_content.split('\n'):
                if line.strip():
                    print(f"  {line}")
            print()
            
            time.sleep(0.1)  # Simulate real-time
        
        print("─" * 80 + "\n")
        
        print("📊 Final Output (synthesized by orchestrator AI):")
        print("-" * 80)
        print(result_2.final_result)  # Complete output, no truncation
        print("-" * 80 + "\n")
    else:
        print(f"❌ Error: {result_2.error}\n")

    # ====================================================================
    # SCENARIO #3: PIPELINE + DEAL WORKFLOW
    # ====================================================================
    print("\n" + "=" * 80)
    print("🤖↔🤖 SCENARIO #3: AI-TO-AI PIPELINE ANALYSIS + QUOTE GENERATION")
    print("=" * 80 + "\n")
    print("Demonstrating: 2 AI agents in parallel collaboration")
    print("  • PipelineAgent analyzes and prioritizes opportunities")
    print("  • DealAgent creates optimized quote structure")
    print("  • Both work in PARALLEL - true multi-AI concurrency\n")
    
    scenario_3_task = """
    I need help with a renewal opportunity:
    - Customer: DataCore Systems ($500K ARR, renewing in 30 days)
    - They want to expand from 1000 to 1500 licenses
    
    Please: 
    1. Analyze where this fits in my pipeline priorities
    2. Generate an optimized quote for the expansion
    """
    
    print("Task for AI Agents:")
    print(scenario_3_task.strip() + "\n")
    print("🤖 Orchestrator detecting parallel execution opportunity...")
    print("⚡ Both agents can work simultaneously - no dependencies!")
    print("🔍 AI agents discovering capabilities...")
    print("📤 Delegating to PipelineAgent and DealAgent IN PARALLEL...\n")
    
    print("┌" + "─" * 78 + "┐")
    print("│" + " LIVE WORKSPACE #3 - PARALLEL AI EXECUTION ".center(78) + "│")
    print("└" + "─" * 78 + "┘\n")
    
    current_workspace["name"] = "Scenario 3: DataCore Renewal"
    print("🔴 LIVE: Pipeline ∥ Deal (both agents working simultaneously)...\n")
    
    result_3 = await orchestrated_workspace.execute_task(
        task=scenario_3_task,
        workspace_name="DataCore Renewal & Expansion",
    )
    
    print("\n" + "=" * 80)
    print("🎊 AI-TO-AI COLLABORATION #3 COMPLETE!")
    print("=" * 80 + "\n")
    
    if result_3.success:
        print("✅ Two AI agents worked in parallel successfully!\n")
        print("📋 Parallel Execution Proof:")
        print(f"  • Subtasks created: {len(result_3.plan.subtasks)}")
        print(f"  • Agents used: {', '.join(result_3.plan.selected_agents)}")
        print(f"  • Execution stages: {len(result_3.plan.execution_order)}")
        
        if len(result_3.plan.execution_order) == 1 and len(result_3.plan.execution_order[0]) > 1:
            print(f"  • ⚡ PARALLEL: {len(result_3.plan.execution_order[0])} agents ran simultaneously!")
        
        print("\n🤖 Parallel Agent Execution:")
        for i, subtask in enumerate(result_3.plan.subtasks, 1):
            print(f"  {i}. {subtask.assigned_agent_name}: {subtask.description} [Order: {subtask.order}]")
        
        # Show workspace interactions for scenario 3 (parallel) with simulated real-time
        print("\n" + "─" * 80)
        print("💬 WORKSPACE #3 CONVERSATION PLAYBACK - PARALLEL EXECUTION:")
        print("─" * 80)
        print("Notice: Both agents receive tasks simultaneously and work independently!")
        print()
        
        import time
        
        for i, msg in enumerate(result_3.workspace_messages, 1):
            sender = msg.get('sender_name', 'System')
            content = msg.get('content', '')
            
            if not content or len(content.strip()) < 10:
                continue
            
            if "Pipeline" in sender:
                icon = "📊"
                color_code = "\033[96m"
            elif "Deal" in sender:
                icon = "💰"
                color_code = "\033[91m"
            else:
                icon = "⚙️"
                color_code = "\033[90m"
            
            reset = "\033[0m"
            
            print(f"{color_code}{icon} {sender}:{reset}")
            
            # Display complete content (no truncation)
            display_content = content
            for line in display_content.split('\n'):
                if line.strip():
                    print(f"  {line}")
            print()
            
            time.sleep(0.1)  # Simulate real-time
        
        print("─" * 80)
        print("✓ Both agents completed their work independently and concurrently!")
        print("─" * 80 + "\n")
        
        print("📊 Final Output (synthesized from parallel AI work):")
        print("-" * 80)
        print(result_3.final_result)  # Complete output, no truncation
        print("-" * 80 + "\n")
    else:
        print(f"❌ Error: {result_3.error}\n")

    # ====================================================================
    # AI-TO-AI INTERACTION SUMMARY
    # ====================================================================
    print("\n" + "=" * 80)
    print("📊 AI-TO-AI INTERACTION SUMMARY ACROSS ALL SCENARIOS")
    print("=" * 80 + "\n")
    
    total_subtasks = len(result.plan.subtasks) + len(result_2.plan.subtasks) + len(result_3.plan.subtasks)
    total_agents_used = len(set(result.plan.selected_agents + result_2.plan.selected_agents + result_3.plan.selected_agents))
    total_messages = len(result.workspace_messages) + len(result_2.workspace_messages) + len(result_3.workspace_messages)
    
    print("Across 3 autonomous AI-to-AI collaboration scenarios:")
    print(f"  • Total AI-to-AI subtask delegations: {total_subtasks}")
    print(f"  • Unique specialist AI agents utilized: {total_agents_used}")
    print(f"  • Total A2A protocol messages exchanged: {total_messages}")
    print(f"  • Workspaces created autonomously: 3")
    print()
    
    print("AI Collaboration Patterns Demonstrated:")
    print("  ✓ Sequential: AI Agent A → AI Agent B (dependencies)")
    print("  ✓ Parallel: Multiple AIs working simultaneously")
    print("  ✓ Complex: 5+ AI agents coordinating autonomously")
    print("  ✓ Discovery: Agents finding each other's capabilities")
    print("  ✓ Delegation: Orchestrator distributing work to specialists")
    print("  ✓ Synthesis: Orchestrator combining multiple AI outputs")
    print()
    
    print("This is NOT traditional automation - this is:")
    print("  🤖 Multiple autonomous AI agents")
    print("  🔍 Self-discovering capabilities")
    print("  📤 Delegating to each other")
    print("  ⚡ Working in parallel")
    print("  🤝 Communicating via standard protocol (A2A)")
    print("  🎯 Achieving complex goals without human intervention")
    print()

    # ====================================================================
    # STEP 7: CLEANUP
    # ====================================================================
    print("=" * 80)
    print("CLEANUP - Shutting Down Agent Infrastructure")
    print("=" * 80 + "\n")

    print("🛑 Gracefully stopping all agent servers...\n")
    
    try:
        await research_server.stop()
        print("  ✓ ResearchAgent server stopped")
    except Exception as e:
        print(f"  ⚠️  ResearchAgent: {e}")
    
    try:
        await content_server.stop()
        print("  ✓ ContentAgent server stopped")
    except Exception as e:
        print(f"  ⚠️  ContentAgent: {e}")
    
    try:
        await admin_server.stop()
        print("  ✓ AdminAgent server stopped")
    except Exception as e:
        print(f"  ⚠️  AdminAgent: {e}")
    
    try:
        await pipeline_server.stop()
        print("  ✓ PipelineAgent server stopped")
    except Exception as e:
        print(f"  ⚠️  PipelineAgent: {e}")
    
    try:
        await deal_server.stop()
        print("  ✓ DealAgent server stopped\n")
    except Exception as e:
        print(f"  ⚠️  DealAgent: {e}\n")

    # Final cleanup to ensure ports are released
    cleanup_ports([8001, 8002, 8003, 8004, 8005])
    
    print("─" * 80)
    print("✅ All servers stopped cleanly - no resources leaked")
    print("─" * 80 + "\n")

    # Final summary
    print("=" * 80)
    print("✅ AI-TO-AI INTERACTION DEMONSTRATION COMPLETE")
    print("=" * 80 + "\n")

    print("🤖↔🤖 AUTONOMOUS AI AGENT COLLABORATION DEMONSTRATED:")
    print("  ✓ 3 different multi-agent scenarios executed")
    print("  ✓ 5 specialized AI agents collaborating autonomously")
    print("  ✓ Agents discovering each other via A2A protocol")
    print("  ✓ Sequential AND parallel AI execution patterns")
    print("  ✓ Orchestrator AI delegating to specialist AIs")
    print("  ✓ Multiple AIs synthesizing coherent outputs")
    print("  ✓ Zero human intervention once tasks submitted\n")
    
    print("🔬 A2A Protocol Features Shown:")
    print("  • Agent Card Discovery (GET /.well-known/agent-card.json)")
    print("  • Task Delegation (POST / with structured payloads)")
    print("  • Asynchronous Execution (parallel where possible)")
    print("  • Result Collection & Synthesis")
    print("  • Workspace State Management\n")

    print("Specialist AI Agents That Collaborated:")
    print("  🎯 Orchestrator (Qwin) - Central AI coordinating all other AIs")
    print("  🔍 Research Agent - AI for intelligence gathering")
    print("  📝 Content Agent - AI for content creation")
    print("  📅 Admin Agent - AI for administrative tasks")
    print("  📊 Pipeline Agent - AI for deal prioritization")
    print("  💰 Deal Agent - AI for quote optimization\n")
    
    print("Why This Matters:")
    print("  → This is the future of AI: specialized AIs collaborating")
    print("  → Each AI excels at specific tasks (like human specialists)")
    print("  → Orchestrator AI coordinates them (like a project manager)")
    print("  → A2A protocol enables standardized communication")
    print("  → Result: Complex work done by AI team, not single AI\n")

    print("Next Steps for Implementation:")
    print("  1. Q1 2026: Execute RFP process for agent solutions")
    print("  2. Q2/Q3 2026: Pilot with sales organization")
    print("  3. Q4 2026: Broad launch across all sellers")
    print("  4. Continuous: Expand Qwin knowledge base and capabilities\n")

    print("Expected Business Impact:")
    print("  • 60-70% reduction in administrative work for sellers")
    print("  • 5-8 hours saved per day per seller")
    print("  • Higher quality customer interactions with better preparation")
    print("  • Improved win rates through strategic insights")
    print("  • Better seller experience and retention")
    print("  • Reduced support ticket volume (80% self-service rate)\n")

    print("=" * 80 + "\n")


if __name__ == "__main__":
    # Setup output logging to file
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    output_dir = Path(__file__).parent / "outputs"
    output_dir.mkdir(exist_ok=True)
    log_file_path = output_dir / f"qualtrics_sales_run_{timestamp}.txt"
    
    # Create output logger
    logger = OutputLogger(log_file_path)
    original_stdout = sys.stdout
    original_stderr = sys.stderr
    
    try:
        # Redirect stdout and stderr to both terminal and file
        sys.stdout = logger
        sys.stderr = logger  # Capture errors too
        
        if not logger.file_error:
            print(f"\n📝 Output is being saved to: {log_file_path}\n")
        else:
            print(f"\n⚠️  Note: Output will NOT be saved to file (error during file creation)\n")
        print("=" * 80 + "\n")
        
        # Run the main async function
        try:
            asyncio.run(main())
            print("\n" + "=" * 80)
            print("✅ SCRIPT COMPLETED SUCCESSFULLY")
            print("=" * 80 + "\n")
        except KeyboardInterrupt:
            print("\n" + "=" * 80)
            print("⚠️  SCRIPT INTERRUPTED BY USER (Ctrl+C)")
            print("=" * 80 + "\n")
        except Exception as e:
            print("\n" + "=" * 80)
            print(f"❌ SCRIPT FAILED WITH ERROR:")
            print(f"   {type(e).__name__}: {str(e)}")
            print("=" * 80 + "\n")
            import traceback
            traceback.print_exc()
        
    finally:
        # Restore stdout and stderr
        sys.stdout = original_stdout
        sys.stderr = original_stderr
        logger.close()
        
        # Verify the file was actually created and has content
        if log_file_path.exists() and log_file_path.stat().st_size > 0:
            print(f"\n✅ Output saved to: {log_file_path}")
            print(f"   File size: {log_file_path.stat().st_size:,} bytes\n")
        else:
            print(f"\n⚠️  Warning: Output file was not created or is empty")
            print(f"   Expected location: {log_file_path}\n")

