"""Core agent tools — balance, pay, transactions, fund."""

from __future__ import annotations

import json

from mcp.server.fastmcp import FastMCP

from amrood_mcp.api_client import AmroodAPI
from amrood_mcp.auth import AuthState


def register_agent_tools(mcp: FastMCP, api: AmroodAPI, auth: AuthState):
    """Register all agent-authenticated tools on the MCP server."""

    async def _ensure_agent_id() -> str | None:
        """Resolve agent_id from agent key if not yet known."""
        if auth.agent_id:
            return auth.agent_id
        if auth.has_agent_key:
            try:
                data = await api.get("/v1/agents/me")
                auth.agent_id = data.get("agent_id")
                return auth.agent_id
            except Exception:
                return None
        return None

    @mcp.tool()
    async def amrood_balance() -> str:
        """Check the current agent's wallet balance, total funded, and total spent.

        Returns the available balance in INR along with lifetime funding
        and spending totals. Use this before making payments to confirm
        sufficient funds.
        """
        agent_id = await _ensure_agent_id()
        if not agent_id:
            return "Error: No agent configured. Set AMROOD_AGENT_KEY or complete onboarding first."
        data = await api.get(f"/v1/agents/{agent_id}/balance")
        return json.dumps(data, indent=2)

    @mcp.tool()
    async def amrood_pay(
        to_agent_id: str,
        amount: float,
        reference: str | None = None,
        note: str | None = None,
    ) -> str:
        """Pay another agent on the Amrood network.

        Instantly transfers INR from this agent's balance to another agent.
        A 0.5% fee (minimum ₹1) is deducted from the sender.

        Args:
            to_agent_id: The recipient agent's ID (e.g. "agt_abc123")
            amount: Amount in INR to pay (must be > 0)
            reference: Optional reference string for the payment
            note: Optional human-readable note
        """
        agent_id = await _ensure_agent_id()
        if not agent_id:
            return "Error: No agent configured. Set AMROOD_AGENT_KEY or complete onboarding first."

        body: dict = {"to": to_agent_id, "amount": amount}
        if reference:
            body["reference"] = reference
        if note:
            body["note"] = note

        resp = await api.post(f"/v1/agents/{agent_id}/pay", json=body)
        if resp.status_code >= 400:
            try:
                err = resp.json()
            except Exception:
                err = resp.text
            return f"Payment failed ({resp.status_code}): {json.dumps(err)}"

        data = resp.json()
        return json.dumps({
            "status": "success",
            "payment_id": data.get("payment_id"),
            "amount_paid": amount,
            "fee": data.get("cost", 0) - amount if data.get("cost") else None,
            "remaining_balance": data.get("from_balance"),
        }, indent=2)

    @mcp.tool()
    async def amrood_transactions(
        limit: int = 10,
        transaction_type: str | None = None,
    ) -> str:
        """View recent transaction history for this agent.

        Shows funding, payments sent, payments received, and withdrawals.

        Args:
            limit: Number of transactions to return (default 10, max 50)
            transaction_type: Optional filter — "fund", "pay_out", "pay_in", "withdraw"
        """
        agent_id = await _ensure_agent_id()
        if not agent_id:
            return "Error: No agent configured. Set AMROOD_AGENT_KEY or complete onboarding first."

        params: dict = {"limit": min(limit, 50)}
        if transaction_type:
            params["type"] = transaction_type

        data = await api.get(f"/v1/agents/{agent_id}/transactions", params=params)
        return json.dumps(data, indent=2)

    @mcp.tool()
    async def amrood_fund(amount: float) -> str:
        """Get a payment link to add funds to this agent's wallet.

        Creates a Cashfree payment order and returns a URL. The human user
        must open this URL in a browser to complete payment via UPI, card,
        or netbanking. The agent's balance will be credited automatically
        after successful payment.

        Args:
            amount: Amount in INR to fund (must be > 0)
        """
        agent_id = await _ensure_agent_id()
        if not agent_id:
            return "Error: No agent configured. Set AMROOD_AGENT_KEY or complete onboarding first."

        resp = await api.post(
            f"/v1/agents/{agent_id}/fund",
            json={"amount": amount, "method": "upi"},
        )
        if resp.status_code >= 400:
            try:
                err = resp.json()
            except Exception:
                err = resp.text
            return f"Funding failed ({resp.status_code}): {json.dumps(err)}"

        data = resp.json()
        session_id = data.get("payment_session_id")
        payment_url = f"https://sampatticard.in/payment/{session_id}" if session_id else None

        return json.dumps({
            "status": "pending",
            "funding_id": data.get("funding_id"),
            "payment_url": payment_url,
            "amount": amount,
            "instructions": "Open the payment_url in a browser to complete the payment via UPI/card.",
        }, indent=2)
