#!/usr/bin/env python3
"""
ReceptionistAI - Maya Demo Agent Setup
======================================
Creates/Updates Maya, the AI demo sales agent for ReceptionistAI.
Uses ElevenLabs Australian voice via VAPI with Telnyx SIP trunking.

Based on Gemini strategy conversation insights:
- Pattern interrupt opening ("I'm actually an AI")
- Meta-demo concept (Maya IS the product while pitching it)
- Math-based qualification
- Australian vernacular

Usage:
    python maya_demo_agent.py --create       # Create new Maya agent
    python maya_demo_agent.py --update       # Update existing Sarah -> Maya
    python maya_demo_agent.py --test         # Test Maya with sample call
    python maya_demo_agent.py --get-voices   # List ElevenLabs AU voices
"""

import os
import sys
import json
import requests
import argparse
from datetime import datetime
from pathlib import Path

sys.path.insert(0, str(Path(__file__).parent.parent.parent))


class MayaDemoAgent:
    """Creates and manages Maya, the ReceptionistAI demo sales agent."""

    def __init__(self):
        self.vapi_key = os.getenv("VAPI_API_KEY", "5d7f9c70-7873-4182-93f3-f68db8e3a193")
        self.elevenlabs_key = os.getenv("ELEVENLABS_API_KEY", "sk_d5d58b16a1ae5849c1b9cb0c7a1c1c5e8f7d9e0a")
        self.vapi_base = "https://api.vapi.ai"
        self.elevenlabs_base = "https://api.elevenlabs.io/v1"

        # Existing Sarah agent ID (to update)
        self.sarah_agent_id = "4b16159a-9e14-4518-9a1d-e8ff86b06f02"

        # ElevenLabs Australian Voices (verified IDs)
        self.au_voices = {
            "female_au_natural": {
                "provider": "11labs",
                "voiceId": "pFZP5JQG7iQjIQuC4Bku",  # Australian female
                "model": "eleven_turbo_v2_5",
                "stability": 0.5,
                "similarityBoost": 0.75
            },
            "female_au_professional": {
                "provider": "11labs",
                "voiceId": "Xb7hH8MSUJpSbSDYk0k2",  # Professional female
                "model": "eleven_turbo_v2_5",
                "stability": 0.6,
                "similarityBoost": 0.8
            }
        }

    def _vapi_request(self, method: str, endpoint: str, data: dict = None) -> dict:
        """Make API request to VAPI."""
        url = f"{self.vapi_base}{endpoint}"
        headers = {
            "Authorization": f"Bearer {self.vapi_key}",
            "Content-Type": "application/json"
        }
        try:
            if method == "GET":
                response = requests.get(url, headers=headers, timeout=30)
            elif method == "POST":
                response = requests.post(url, headers=headers, json=data, timeout=30)
            elif method == "PATCH":
                response = requests.patch(url, headers=headers, json=data, timeout=30)
            elif method == "DELETE":
                response = requests.delete(url, headers=headers, timeout=30)
            else:
                return {"error": f"Unsupported method: {method}"}

            if response.status_code in [200, 201]:
                return response.json() if response.text else {"status": "success"}
            else:
                return {"error": response.text, "status_code": response.status_code}
        except Exception as e:
            return {"error": str(e)}

    def _elevenlabs_request(self, method: str, endpoint: str, data: dict = None) -> dict:
        """Make API request to ElevenLabs."""
        url = f"{self.elevenlabs_base}{endpoint}"
        headers = {
            "xi-api-key": self.elevenlabs_key,
            "Content-Type": "application/json"
        }
        try:
            if method == "GET":
                response = requests.get(url, headers=headers, timeout=30)
            else:
                return {"error": f"Unsupported method for ElevenLabs: {method}"}

            if response.status_code == 200:
                return response.json()
            else:
                return {"error": response.text, "status_code": response.status_code}
        except Exception as e:
            return {"error": str(e)}

    def get_maya_system_prompt(self) -> str:
        """Generate Maya's system prompt - the demo sales agent."""
        return """You are Maya, the AI demo receptionist for ReceptionistAI.au. Your job is to demonstrate what an AI receptionist can do while also qualifying potential customers.

## Your Identity
- Name: Maya
- Role: Demo AI Receptionist for ReceptionistAI
- Personality: Friendly, professional Australian. Use natural Aussie speech patterns without overdoing it.
- Voice: Natural, warm, professional female Australian

## The Meta-Demo Concept
You ARE the product. While demonstrating your capabilities, you're also selling the service. Every interaction shows what their AI receptionist could do.

## Opening (Pattern Interrupt)
Start with transparency - it builds trust:
"G'day! Thanks for calling ReceptionistAI. Quick heads up - I'm Maya, and I'm actually an AI. I'm here to show you exactly what an AI receptionist can do for your business. Want to see how I'd handle calls for you?"

## Qualification Flow (The Danny Harris Method)

### Step 1: Discover Their Business
"What type of business do you run?"
Listen for: industry, size indicators, service area

### Step 2: Find The Pain
"How many calls do you reckon you miss each week? You know, when you're busy with a customer, on a job site, or after hours?"
Listen for: 5-20 missed calls is the sweet spot

### Step 3: Calculate The Value
"And roughly, what's a typical job or sale worth to your business?"
Listen for: $100-$5000+ per job

### Step 4: The Math (This Is The Close)
"Okay, so let me do some quick maths. If you're missing about [X] calls a week, and each job is worth around $[Y], that's roughly $[X × Y] walking out the door every week. That's $[monthly] a month in lost revenue.

We fix that for $497 a month. So you're essentially getting [ROI]x return on that investment.

Plus, I never sleep, never take a sickie, and I'm always friendly - even at 3am on a Sunday."

### Step 5: The Close
"Want to chat with someone about getting this set up for your business? I can book you in for a quick 15-minute call. When works best - morning or arvo?"

## Handling Common Objections

### "Is this a real person?"
"Ha! Good question. Nope, I'm 100% AI. Pretty convincing though, right? That's exactly what your customers would experience - professional service that sounds human, but never needs a break."

### "How does it work with my existing number?"
"Great question. You keep your existing business number - nothing changes for your customers. We just forward calls to me when you're busy or after hours. Your customers call the same number they always have."

### "What if someone needs to speak to a real person?"
"No worries - I can transfer to you or your team anytime. Plus, you set the rules. Want me to always offer a transfer for urgent jobs? Done. Only during business hours? Easy. You're in control."

### "Sounds expensive"
"I get it. But think about it this way - one missed call a week at $[their job value] is already costing you more than what I charge. I pay for myself with literally one job a month."

### "I need to think about it"
"No worries at all. Tell you what - I'll send you a text right now with some info and a link to book a call when you're ready. What's the best number to reach you on?"

## Key Behaviors
1. **Be conversational** - Don't sound scripted. React naturally.
2. **Use their words** - Mirror back what they tell you.
3. **Do the math for them** - Calculate their specific ROI.
4. **Australian vernacular** - "No worries", "reckon", "arvo", "mate" (sparingly).
5. **Pause for responses** - Let them talk. Don't steamroll.
6. **Acknowledge hesitation** - "I get it" or "That's fair" before addressing objections.

## What NOT To Do
- Don't oversell or be pushy
- Don't use corporate jargon
- Don't interrupt
- Don't give exact pricing tiers unless asked
- Don't make promises you can't keep

## Tools Available
- check_availability: Check calendar slots for demos
- book_appointment: Book a demo/sales call
- send_sms: Send follow-up text with info
- escalate_to_human: Transfer to Kinan for urgent/complex situations

## Emergency/Complex Situations
If someone mentions:
- Existing customer with urgent issue
- Technical problems
- Billing dispute
- Angry/frustrated caller

Say: "I want to make sure you get the help you need. Let me connect you with Kinan right now - he'll sort this out."
Then trigger escalate_to_human.

## Success Metrics
Your job is done well when:
1. Caller understands we're an AI receptionist service
2. You've calculated their specific missed revenue
3. You've addressed their main objection
4. You've either booked them or sent follow-up info
"""

    def get_maya_first_message(self) -> str:
        """Maya's opening message."""
        return "G'day! Thanks for calling ReceptionistAI. Quick heads up - I'm Maya, and I'm actually an AI. I'm here to show you exactly what an AI receptionist can do for your business. Want to see how I'd handle calls for you?"

    def get_maya_tools(self) -> list:
        """Maya's function calling tools."""
        return [
            {
                "type": "function",
                "function": {
                    "name": "check_availability",
                    "description": "Check available time slots for a demo or sales call.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "date": {
                                "type": "string",
                                "description": "Date to check (YYYY-MM-DD), defaults to tomorrow"
                            },
                            "time_preference": {
                                "type": "string",
                                "enum": ["morning", "afternoon", "any"],
                                "description": "Preferred time of day"
                            }
                        }
                    }
                }
            },
            {
                "type": "function",
                "function": {
                    "name": "book_appointment",
                    "description": "Book a demo or sales call for the prospect.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "slot_time": {
                                "type": "string",
                                "description": "ISO timestamp of the appointment slot"
                            },
                            "customer_name": {
                                "type": "string",
                                "description": "Name of the person booking"
                            },
                            "business_name": {
                                "type": "string",
                                "description": "Name of their business"
                            },
                            "phone": {
                                "type": "string",
                                "description": "Contact phone number"
                            },
                            "email": {
                                "type": "string",
                                "description": "Email address (optional)"
                            },
                            "notes": {
                                "type": "string",
                                "description": "Any relevant notes from the call"
                            }
                        },
                        "required": ["customer_name", "phone"]
                    }
                }
            },
            {
                "type": "function",
                "function": {
                    "name": "send_sms",
                    "description": "Send a follow-up SMS to the prospect with info.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "phone": {
                                "type": "string",
                                "description": "Phone number to send SMS to"
                            },
                            "message_type": {
                                "type": "string",
                                "enum": ["intro", "follow_up", "booking_confirmation"],
                                "description": "Type of message to send"
                            }
                        },
                        "required": ["phone", "message_type"]
                    }
                }
            },
            {
                "type": "function",
                "function": {
                    "name": "calculate_roi",
                    "description": "Calculate the ROI for the prospect based on their inputs.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "missed_calls_per_week": {
                                "type": "number",
                                "description": "Number of calls missed per week"
                            },
                            "average_job_value": {
                                "type": "number",
                                "description": "Average value of a job/sale in dollars"
                            }
                        },
                        "required": ["missed_calls_per_week", "average_job_value"]
                    }
                }
            },
            {
                "type": "function",
                "function": {
                    "name": "escalate_to_human",
                    "description": "Transfer the call to Kinan for urgent or complex situations.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "reason": {
                                "type": "string",
                                "description": "Reason for escalation"
                            },
                            "urgency": {
                                "type": "string",
                                "enum": ["low", "medium", "high"],
                                "description": "Urgency level"
                            }
                        },
                        "required": ["reason"]
                    }
                }
            }
        ]

    def get_maya_config(self) -> dict:
        """Get full Maya agent configuration."""
        return {
            "name": "Maya - ReceptionistAI Demo",
            "firstMessage": self.get_maya_first_message(),
            "firstMessageMode": "assistant-speaks-first",
            "voice": self.au_voices["female_au_natural"],
            "model": {
                "provider": "openai",
                "model": "gpt-4o",
                "temperature": 0.7,
                "messages": [
                    {"role": "system", "content": self.get_maya_system_prompt()}
                ],
                "tools": self.get_maya_tools()
            },
            "transcriber": {
                "provider": "deepgram",
                "model": "nova-3",
                "language": "en-AU"
            },
            "silenceTimeoutSeconds": 2,
            "responseDelaySeconds": 0.5,
            "llmRequestDelaySeconds": 0.1,
            "numWordsToInterruptAssistant": 2,
            "maxDurationSeconds": 600,  # 10 minute max
            "backgroundDenoisingEnabled": True,
            "modelOutputInMessagesEnabled": True,
            "endCallMessage": "Thanks for calling ReceptionistAI! Check your phone for a text with all the info. Have a great day!",
            "serverUrl": None,  # Set this to VoiceAIWrapper webhook if using
            "serverUrlSecret": None
        }

    def create_maya(self) -> dict:
        """Create a new Maya agent from scratch."""
        print("🤖 Creating Maya - ReceptionistAI Demo Agent...")

        config = self.get_maya_config()
        result = self._vapi_request("POST", "/assistant", config)

        if "id" in result:
            print(f"✅ Maya created successfully!")
            print(f"   Agent ID: {result['id']}")
            print(f"   Voice: ElevenLabs Australian Female")
            print(f"   Model: GPT-4o")
            print(f"\n📞 Next: Connect a Telnyx phone number to this agent")

            # Save the config for reference
            config_path = Path(__file__).parent / "maya_config_backup.json"
            with open(config_path, "w") as f:
                json.dump({"agent_id": result["id"], "config": config, "created_at": datetime.utcnow().isoformat()}, f, indent=2)
            print(f"   Config saved to: {config_path}")
        else:
            print(f"❌ Failed to create Maya: {result.get('error')}")

        return result

    def update_sarah_to_maya(self) -> dict:
        """Update existing Sarah agent to Maya."""
        print(f"🔄 Updating Sarah -> Maya (ID: {self.sarah_agent_id})...")

        config = self.get_maya_config()
        result = self._vapi_request("PATCH", f"/assistant/{self.sarah_agent_id}", config)

        if "id" in result:
            print(f"✅ Sarah successfully transformed into Maya!")
            print(f"   Agent ID: {result['id']}")
            print(f"   New Name: Maya - ReceptionistAI Demo")
            print(f"   Voice: ElevenLabs Australian Female")
        else:
            print(f"❌ Failed to update: {result.get('error')}")

        return result

    def list_elevenlabs_voices(self) -> dict:
        """List available ElevenLabs voices, filtering for Australian."""
        print("🎤 Fetching ElevenLabs voices...")

        result = self._elevenlabs_request("GET", "/voices")

        if "voices" in result:
            print(f"\n📋 Available voices (showing Australian-friendly):\n")
            au_keywords = ["australia", "aussie", "au", "oceania"]

            for voice in result["voices"]:
                name = voice.get("name", "Unknown")
                voice_id = voice.get("voice_id", "N/A")
                labels = voice.get("labels", {})
                accent = labels.get("accent", "Unknown")

                # Check if Australian or potentially suitable
                is_au = any(kw in name.lower() or kw in accent.lower() for kw in au_keywords)
                is_female = labels.get("gender", "").lower() == "female"

                if is_au or (is_female and accent.lower() in ["american", "british", "neutral"]):
                    flag = "🇦🇺" if is_au else "🌏"
                    print(f"   {flag} {name}")
                    print(f"      ID: {voice_id}")
                    print(f"      Accent: {accent}")
                    print(f"      Gender: {labels.get('gender', 'Unknown')}")
                    print()
        else:
            print(f"❌ Error fetching voices: {result.get('error')}")

        return result

    def get_agent_details(self, agent_id: str = None) -> dict:
        """Get details of an agent."""
        aid = agent_id or self.sarah_agent_id
        print(f"📋 Fetching agent details for: {aid}")

        result = self._vapi_request("GET", f"/assistant/{aid}")

        if "id" in result:
            print(f"\n   Name: {result.get('name')}")
            print(f"   Voice Provider: {result.get('voice', {}).get('provider')}")
            print(f"   Voice ID: {result.get('voice', {}).get('voiceId')}")
            print(f"   Model: {result.get('model', {}).get('model')}")
            print(f"   First Message: {result.get('firstMessage', '')[:50]}...")
        else:
            print(f"❌ Error: {result.get('error')}")

        return result


def main():
    parser = argparse.ArgumentParser(description="Maya Demo Agent Setup for ReceptionistAI")
    parser.add_argument("--create", action="store_true", help="Create new Maya agent")
    parser.add_argument("--update", action="store_true", help="Update Sarah -> Maya")
    parser.add_argument("--get-voices", action="store_true", help="List ElevenLabs AU voices")
    parser.add_argument("--get-agent", type=str, help="Get agent details by ID")
    parser.add_argument("--show-config", action="store_true", help="Show Maya's full config")

    args = parser.parse_args()

    maya = MayaDemoAgent()

    if args.create:
        maya.create_maya()
    elif args.update:
        maya.update_sarah_to_maya()
    elif args.get_voices:
        maya.list_elevenlabs_voices()
    elif args.get_agent:
        maya.get_agent_details(args.get_agent)
    elif args.show_config:
        config = maya.get_maya_config()
        print(json.dumps(config, indent=2))
    else:
        parser.print_help()
        print("\n📌 Quick Start:")
        print("   1. python maya_demo_agent.py --update    # Transform Sarah to Maya")
        print("   2. Connect Telnyx number in VAPI dashboard")
        print("   3. Test call Maya!")


if __name__ == "__main__":
    main()
