"""
ROB Domains — Python Integration Example

Demonstrates using the ROB Domains Agent API with the OpenAI Python SDK.
Covers Search, Mint, Set Primary, Update Profile, and the full Workflow.

Requires: pip install openai requests
"""

import json
import os
import requests
from openai import OpenAI

BASE_URL = "https://robdn.com"
client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))


# ─── API Helpers ──────────────────────────────────────────────────────────────

def api_get(path: str) -> dict:
    res = requests.get(f"{BASE_URL}{path}", timeout=30)
    res.raise_for_status()
    return res.json()


def api_post(path: str, body: dict) -> dict:
    res = requests.post(
        f"{BASE_URL}{path}",
        json=body,
        headers={"Content-Type": "application/json"},
        timeout=30,
    )
    res.raise_for_status()
    return res.json()


# ─── Tool Definitions ─────────────────────────────────────────────────────────

ROB_DOMAINS_TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "search_rob_domain",
            "description": (
                "Search for a .rob domain name. Returns availability, owner, "
                "tokenId, primary owner, and profile summary."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "domain": {
                        "type": "string",
                        "description": 'Domain label without ".rob" suffix (e.g. "alice")',
                    }
                },
                "required": ["domain"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "get_rob_profile",
            "description": "Get the full on-chain profile for a .rob domain.",
            "parameters": {
                "type": "object",
                "properties": {
                    "domain": {"type": "string", "description": 'Domain label (e.g. "alice")'}
                },
                "required": ["domain"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "reverse_resolve_rob",
            "description": "Reverse-resolve an Ethereum wallet address to its primary .rob domain.",
            "parameters": {
                "type": "object",
                "properties": {
                    "wallet": {
                        "type": "string",
                        "description": "Ethereum wallet address (0x-prefixed)",
                    }
                },
                "required": ["wallet"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "build_mint_transaction",
            "description": (
                "Generate an unsigned transaction payload for minting a .rob domain NFT. "
                "The user must sign and broadcast it — the API never executes transactions."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "domain": {
                        "type": "string",
                        "description": 'Domain label to mint (e.g. "alice")',
                    }
                },
                "required": ["domain"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "build_set_primary_transaction",
            "description": (
                "Generate an unsigned transaction payload for setting a .rob domain "
                "as the primary domain for a wallet."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "tokenId": {"type": "string", "description": "On-chain token ID"},
                    "wallet": {
                        "type": "string",
                        "description": "Wallet address that owns the token",
                    },
                },
                "required": ["tokenId", "wallet"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "build_update_profile_transaction",
            "description": "Generate unsigned transaction payload(s) for updating a .rob domain profile.",
            "parameters": {
                "type": "object",
                "properties": {
                    "tokenId": {"type": "string", "description": "Token ID of the domain"},
                    "bio": {"type": "string", "description": "Profile bio (max 500 chars)"},
                    "profilePicture": {"type": "string", "description": "Profile picture URL"},
                    "coverImage": {"type": "string", "description": "Cover image URL"},
                    "background": {"type": "string", "description": "Background CSS class string"},
                    "socialLinks": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "platform": {"type": "string"},
                                "url": {"type": "string"},
                            },
                        },
                    },
                    "customLinks": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "title": {"type": "string"},
                                "url": {"type": "string"},
                            },
                        },
                    },
                },
                "required": ["tokenId"],
            },
        },
    },
    {
        "type": "function",
        "function": {
            "name": "register_domain_workflow",
            "description": (
                "Get a complete multi-step execution plan for registering a .rob domain "
                "(mint + optional set primary + optional profile update)."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "domain": {"type": "string"},
                    "wallet": {"type": "string"},
                    "setPrimary": {"type": "boolean", "default": False},
                    "profile": {
                        "type": "object",
                        "properties": {
                            "bio": {"type": "string"},
                            "profilePicture": {"type": "string"},
                            "socialLinks": {
                                "type": "array",
                                "items": {"type": "object"},
                            },
                        },
                    },
                },
                "required": ["domain", "wallet"],
            },
        },
    },
]


# ─── Tool Execution ───────────────────────────────────────────────────────────

def execute_tool(name: str, args: dict) -> dict:
    routes = {
        "search_rob_domain": lambda: api_get(f"/agent/search/{args['domain']}"),
        "get_rob_profile": lambda: api_get(f"/agent/profile/{args['domain']}"),
        "reverse_resolve_rob": lambda: api_get(f"/agent/reverse/{args['wallet']}"),
        "build_mint_transaction": lambda: api_post("/agent/tx/mint", {"domain": args["domain"]}),
        "build_set_primary_transaction": lambda: api_post(
            "/agent/tx/set-primary",
            {"tokenId": args["tokenId"], "wallet": args["wallet"]},
        ),
        "build_update_profile_transaction": lambda: api_post("/agent/tx/update-profile", args),
        "register_domain_workflow": lambda: api_post("/agent/workflow/register-domain", args),
    }
    handler = routes.get(name)
    if not handler:
        return {"error": f"Unknown tool: {name}"}
    return handler()


# ─── Agent Loop ───────────────────────────────────────────────────────────────

def rob_domains_agent(user_message: str) -> str:
    messages = [
        {
            "role": "system",
            "content": (
                "You are a helpful assistant for ROB Domains (.rob), a Web3 domain name system "
                "on the Robinhood Chain. Help users search domains, read profiles, and generate "
                "transaction payloads for minting, setting a primary domain, and updating profiles. "
                "Always remind users that they must sign and broadcast transaction payloads — "
                "the API never executes on their behalf."
            ),
        },
        {"role": "user", "content": user_message},
    ]

    while True:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=ROB_DOMAINS_TOOLS,
            tool_choice="auto",
        )

        choice = response.choices[0]
        messages.append(choice.message)

        if choice.finish_reason == "stop":
            return choice.message.content or ""

        if choice.finish_reason == "tool_calls" and choice.message.tool_calls:
            for tool_call in choice.message.tool_calls:
                args = json.loads(tool_call.function.arguments)
                result = execute_tool(tool_call.function.name, args)
                messages.append(
                    {
                        "role": "tool",
                        "tool_call_id": tool_call.id,
                        "content": json.dumps(result),
                    }
                )


# ─── Demo ─────────────────────────────────────────────────────────────────────

def main():
    print("─── Search ───")
    print(rob_domains_agent('Is the domain "alice" available on ROB Domains?'))

    print("\n─── Mint ───")
    print(
        rob_domains_agent(
            'Build me a transaction to mint the domain "alice" on ROB Domains.'
        )
    )

    print("\n─── Set Primary ───")
    print(
        rob_domains_agent(
            "Build a set-primary transaction for token #42, "
            "wallet 0xAbCd1234567890AbCd1234567890AbCd12345678."
        )
    )

    print("\n─── Update Profile ───")
    print(
        rob_domains_agent(
            'Build an update-profile transaction for token #42. '
            'Set bio to "Web3 builder" and add Twitter https://twitter.com/alice.'
        )
    )

    print("\n─── Full Registration Workflow ───")
    print(
        rob_domains_agent(
            'I want to register "alice.rob" for wallet 0xAbCd1234567890AbCd1234567890AbCd12345678. '
            "Set it as my primary domain and add a Twitter link to https://twitter.com/alice. "
            "Give me the full execution plan."
        )
    )


if __name__ == "__main__":
    main()
