"""
AutoGen tools for Nory x402 payments.

These tools enable Microsoft AutoGen agents to pay for x402-protected APIs automatically.
"""

import os
import json
from typing import Optional, Annotated
import requests

NORY_BASE_URL = "https://noryx402.com"


def _make_paid_request(url: str, wallet_key: Optional[str] = None) -> dict:
    """Internal: Make request with automatic x402 payment handling."""
    key = wallet_key or os.environ.get("NORY_WALLET_KEY")
    headers = {"Accept": "application/json"}

    response = requests.get(url, headers=headers)

    if response.status_code == 402:
        if not key:
            return {"error": "Payment required but no wallet key configured", "requirements": response.json()}

        requirements = response.json()
        payment_response = requests.post(
            f"{NORY_BASE_URL}/api/x402/pay",
            json={"requirements": requirements, "walletKey": key, "network": "solana-mainnet"},
            headers={"Content-Type": "application/json"}
        )

        if payment_response.status_code != 200:
            return {"error": "Payment failed", "details": payment_response.text}

        payment_data = payment_response.json()
        headers["X-PAYMENT"] = payment_data.get("paymentHeader", "")
        final_response = requests.get(url, headers=headers)

        return {
            "success": True,
            "data": final_response.json() if "json" in final_response.headers.get("content-type", "") else final_response.text,
            "payment": {"amount": payment_data.get("amount"), "txId": payment_data.get("transactionId")}
        }

    try:
        return {"success": True, "data": response.json()}
    except:
        return {"success": True, "data": response.text}


def nory_fetch(
    url: Annotated[str, "The URL to fetch (may require x402 payment)"]
) -> str:
    """
    Fetch any URL with automatic x402 payment handling.
    Automatically pays for resources that return HTTP 402.
    Uses USDC on Solana with ~400ms settlement.
    """
    result = _make_paid_request(url)
    return json.dumps(result)


def nory_crypto_prices(
    symbols: Annotated[str, "Comma-separated crypto symbols (e.g., BTC,ETH,SOL)"] = "BTC,ETH,SOL"
) -> str:
    """
    Get real-time cryptocurrency prices from CoinGecko.
    Costs $0.001 USDC per request.
    Returns current price, 24h change, market cap, and volume.
    """
    result = _make_paid_request(f"{NORY_BASE_URL}/api/paid/live-crypto?symbols={symbols}")
    return json.dumps(result)


def nory_weather(
    city: Annotated[str, "City name to get weather for"]
) -> str:
    """
    Get current weather and 7-day forecast for any city.
    Costs $0.002 USDC per request.
    Returns temperature, conditions, humidity, wind, and forecast.
    """
    result = _make_paid_request(f"{NORY_BASE_URL}/api/paid/weather?city={city}")
    return json.dumps(result)


def nory_translate(
    text: Annotated[str, "Text to translate"],
    to_lang: Annotated[str, "Target language code (e.g., es, fr, de, ja)"] = "es"
) -> str:
    """
    Translate text between 20+ languages.
    Costs $0.005 USDC per request.
    Supports auto-detection of source language.
    """
    result = _make_paid_request(f"{NORY_BASE_URL}/api/paid/translate?text={text}&to={to_lang}")
    return json.dumps(result)


def nory_qrcode(
    data: Annotated[str, "Data to encode in QR code (text or URL)"],
    size: Annotated[int, "Image size in pixels (100-1000)"] = 200
) -> str:
    """
    Generate QR codes for any text or URL.
    Costs $0.001 USDC per request.
    """
    result = _make_paid_request(f"{NORY_BASE_URL}/api/paid/qr-code?data={data}&size={size}&format=json")
    return json.dumps(result)


def nory_web_summary(
    url: Annotated[str, "URL to extract content from"]
) -> str:
    """
    Extract clean text content from any webpage.
    Costs $0.01 USDC per request.
    Removes ads, navigation, and returns main content.
    """
    result = _make_paid_request(f"{NORY_BASE_URL}/api/paid/web-summary?url={url}")
    return json.dumps(result)


def get_nory_tools() -> list:
    """
    Get all Nory tools as a list of functions.

    Returns:
        List of tool functions ready for AutoGen.
    """
    return [
        nory_fetch,
        nory_crypto_prices,
        nory_weather,
        nory_translate,
        nory_qrcode,
        nory_web_summary,
    ]


def register_nory_tools(assistant, user_proxy):
    """
    Register all Nory tools with AutoGen agents.

    Args:
        assistant: The AssistantAgent
        user_proxy: The UserProxyAgent

    Example:
        from autogen import AssistantAgent, UserProxyAgent
        from autogen_nory import register_nory_tools

        assistant = AssistantAgent("assistant", llm_config=llm_config)
        user_proxy = UserProxyAgent("user_proxy")

        register_nory_tools(assistant, user_proxy)
    """
    from autogen import register_function

    tools = [
        (nory_fetch, "Fetch URL with auto x402 payment"),
        (nory_crypto_prices, "Get real-time crypto prices ($0.001)"),
        (nory_weather, "Get weather forecast ($0.002)"),
        (nory_translate, "Translate text ($0.005)"),
        (nory_qrcode, "Generate QR code ($0.001)"),
        (nory_web_summary, "Extract webpage content ($0.01)"),
    ]

    for func, desc in tools:
        register_function(
            func,
            caller=assistant,
            executor=user_proxy,
            name=func.__name__,
            description=desc
        )
