#!/usr/bin/env python3
"""
ReceptionistAI - Telnyx Number Provisioner
==========================================
Provisions Australian phone numbers and configures them for VAPI integration.

Usage:
    python telnyx_provisioner.py --search-numbers
    python telnyx_provisioner.py --provision "+61XXXXXXXXX"
    python telnyx_provisioner.py --connect-to-vapi "+61XXXXXXXXX" "agent_id"
"""

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 TelnyxProvisioner:
    """Provisions and manages Telnyx phone numbers for ReceptionistAI."""

    def __init__(self):
        self.api_key = os.getenv("TELNYX_API_KEY", "2d1dd357-dbe3-4761-8a4a-5e6185252a67")
        self.base_url = "https://api.telnyx.com/v2"
        self.headers = {
            "Authorization": f"Bearer {self.api_key}",
            "Content-Type": "application/json"
        }

        # VAPI credentials for connection
        self.vapi_key = os.getenv("VAPI_API_KEY", "5d7f9c70-7873-4182-93f3-f68db8e3a193")
        self.vapi_base = "https://api.vapi.ai"

    def _telnyx_request(self, method: str, endpoint: str, data: dict = None) -> dict:
        """Make API request to Telnyx."""
        url = f"{self.base_url}{endpoint}"
        try:
            if method == "GET":
                response = requests.get(url, headers=self.headers, params=data, timeout=30)
            elif method == "POST":
                response = requests.post(url, headers=self.headers, json=data, timeout=30)
            elif method == "DELETE":
                response = requests.delete(url, headers=self.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 _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)
            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 search_available_numbers(self, country_code: str = "AU", limit: int = 10) -> dict:
        """Search for available Australian phone numbers."""
        print(f"🔍 Searching for {country_code} numbers...")

        params = {
            "filter[country_code]": country_code,
            "filter[features]": "voice",
            "filter[limit]": limit
        }

        result = self._telnyx_request("GET", "/available_phone_numbers", params)

        if "data" in result:
            numbers = result["data"]
            print(f"✅ Found {len(numbers)} available numbers:")
            for num in numbers:
                phone = num.get("phone_number", "N/A")
                region = num.get("region_information", [{}])[0].get("region_name", "Unknown")
                cost = num.get("cost_information", {}).get("monthly_cost", "N/A")
                print(f"   {phone} | {region} | ${cost}/mo")
        else:
            print(f"❌ Error: {result.get('error', 'Unknown error')}")

        return result

    def purchase_number(self, phone_number: str) -> dict:
        """Purchase a phone number."""
        print(f"💳 Purchasing number: {phone_number}")

        payload = {
            "phone_numbers": [{"phone_number": phone_number}],
            "connection_id": None,  # Will be configured separately
            "messaging_profile_id": None
        }

        result = self._telnyx_request("POST", "/number_orders", payload)

        if "data" in result:
            print(f"✅ Number purchased successfully!")
            print(f"   Order ID: {result['data'].get('id')}")
        else:
            print(f"❌ Purchase failed: {result.get('error')}")

        return result

    def list_owned_numbers(self) -> dict:
        """List all owned phone numbers."""
        print("📞 Fetching owned numbers...")

        result = self._telnyx_request("GET", "/phone_numbers")

        if "data" in result:
            numbers = result["data"]
            print(f"✅ You own {len(numbers)} numbers:")
            for num in numbers:
                phone = num.get("phone_number", "N/A")
                status = num.get("status", "Unknown")
                print(f"   {phone} | Status: {status}")
        else:
            print(f"❌ Error: {result.get('error')}")

        return result

    def import_to_vapi(self, phone_number: str, assistant_id: str = None) -> dict:
        """Import a Telnyx number to VAPI and optionally assign to assistant."""
        print(f"🔗 Importing {phone_number} to VAPI...")

        # Create phone number in VAPI with Telnyx provider
        payload = {
            "provider": "telnyx",
            "number": phone_number,
            "twilioAccountSid": None,  # Not needed for Telnyx
            "twilioAuthToken": None,
            "telnyxApiKey": self.api_key
        }

        if assistant_id:
            payload["assistantId"] = assistant_id

        result = self._vapi_request("POST", "/phone-number", payload)

        if "id" in result:
            print(f"✅ Number imported to VAPI!")
            print(f"   VAPI Phone ID: {result['id']}")
            if assistant_id:
                print(f"   Connected to assistant: {assistant_id}")
        else:
            print(f"❌ Import failed: {result.get('error')}")

        return result

    def provision_for_client(self, client_name: str, area_code: str = None) -> dict:
        """Full provisioning flow for a new client."""
        print(f"\n{'='*50}")
        print(f"🎯 Provisioning number for: {client_name}")
        print(f"{'='*50}\n")

        results = {
            "client": client_name,
            "timestamp": datetime.utcnow().isoformat(),
            "steps": {}
        }

        # Step 1: Search for available numbers
        search_result = self.search_available_numbers("AU", 5)
        results["steps"]["search"] = search_result

        if "data" not in search_result or not search_result["data"]:
            return {"error": "No numbers available", "results": results}

        # Step 2: Select first available number
        selected_number = search_result["data"][0]["phone_number"]
        print(f"\n📌 Selected number: {selected_number}")

        # Step 3: Purchase (commented out for safety)
        # purchase_result = self.purchase_number(selected_number)
        # results["steps"]["purchase"] = purchase_result

        print("\n⚠️  Number purchase requires manual confirmation.")
        print(f"   Run: python telnyx_provisioner.py --provision {selected_number}")

        return results


def main():
    parser = argparse.ArgumentParser(description="Telnyx Number Provisioner for ReceptionistAI")
    parser.add_argument("--search", action="store_true", help="Search for available AU numbers")
    parser.add_argument("--list", action="store_true", help="List owned numbers")
    parser.add_argument("--provision", type=str, help="Provision a specific number")
    parser.add_argument("--import-to-vapi", type=str, help="Import number to VAPI")
    parser.add_argument("--assistant-id", type=str, help="VAPI assistant ID to connect")
    parser.add_argument("--full-provision", type=str, help="Full provisioning for client name")

    args = parser.parse_args()

    provisioner = TelnyxProvisioner()

    if args.search:
        provisioner.search_available_numbers()
    elif args.list:
        provisioner.list_owned_numbers()
    elif args.provision:
        provisioner.purchase_number(args.provision)
    elif args.import_to_vapi:
        provisioner.import_to_vapi(args.import_to_vapi, args.assistant_id)
    elif args.full_provision:
        provisioner.provision_for_client(args.full_provision)
    else:
        parser.print_help()


if __name__ == "__main__":
    main()
