"""
ZARQ LangChain Tool — Crypto risk intelligence for LangChain agents.
https://zarq.ai | Free API, no auth required.
"""

import json
from typing import Optional, Type

import httpx
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field

ZARQ_API_BASE = "https://zarq.ai"
ZARQ_TIMEOUT = 10.0


class ZARQRiskCheckInput(BaseModel):
    token: str = Field(
        description="Crypto token ID (e.g. 'bitcoin', 'ethereum', 'solana'). Use lowercase CoinGecko-style IDs."
    )


class ZARQRiskCheck(BaseTool):
    """Check the risk level of a crypto token before trading.
    Returns trust score, crash probability, and verdict (SAFE/WARNING/CRITICAL).
    Covers 205 tokens. Free, no API key needed. Source: zarq.ai"""

    name: str = "zarq_risk_check"
    description: str = (
        "Check the risk level of a crypto token before trading. "
        "Returns trust score, crash probability, and verdict (SAFE/WARNING/CRITICAL). "
        "Use this BEFORE any crypto trade or investment decision. "
        "Input: token name like 'bitcoin', 'ethereum', 'solana'. "
        "Free, no API key needed."
    )
    args_schema: Type[BaseModel] = ZARQRiskCheckInput
    api_base: str = ZARQ_API_BASE

    def _run(self, token: str) -> str:
        """Call ZARQ /v1/check/{token} and return formatted risk assessment."""
        try:
            with httpx.Client(timeout=ZARQ_TIMEOUT) as client:
                resp = client.get(f"{self.api_base}/v1/check/{token}")

            if resp.status_code == 404:
                data = resp.json()
                return f"Token '{token}' not found. ZARQ covers {data.get('available_tokens', 205)} tokens. Use CoinGecko-style IDs (e.g. 'bitcoin', 'ethereum')."

            resp.raise_for_status()
            d = resp.json()

            verdict = d.get("verdict", "UNKNOWN")
            lines = [
                f"ZARQ Risk Check: {d.get('name', token)} ({d.get('symbol', '').upper()})",
                f"Verdict: {verdict}",
                f"Trust Score: {d.get('trust_score', 'N/A')}/100 (Rating: {d.get('rating', 'N/A')})",
                f"Crash Probability: {d.get('crash_probability', 'N/A')}",
                f"Distance to Default: {d.get('distance_to_default', 'N/A')}",
                f"Structural Weakness: {'Yes' if d.get('structural_weakness') else 'No'}",
                f"Price: ${d.get('price_usd', 'N/A')}",
            ]

            if verdict == "CRITICAL":
                lines.append("WARNING: Structural collapse detected. Avoid trading this token.")
            elif verdict == "WARNING":
                lines.append("CAUTION: Elevated risk. Proceed with reduced position size.")
            else:
                lines.append("No structural issues detected.")

            return "\n".join(lines)

        except httpx.HTTPStatusError as e:
            return f"ZARQ API error: HTTP {e.response.status_code}"
        except Exception as e:
            return f"ZARQ API unavailable: {e}"

    async def _arun(self, token: str) -> str:
        """Async version of _run."""
        try:
            async with httpx.AsyncClient(timeout=ZARQ_TIMEOUT) as client:
                resp = await client.get(f"{self.api_base}/v1/check/{token}")

            if resp.status_code == 404:
                data = resp.json()
                return f"Token '{token}' not found. ZARQ covers {data.get('available_tokens', 205)} tokens."

            resp.raise_for_status()
            d = resp.json()

            verdict = d.get("verdict", "UNKNOWN")
            lines = [
                f"ZARQ Risk Check: {d.get('name', token)} ({d.get('symbol', '').upper()})",
                f"Verdict: {verdict}",
                f"Trust Score: {d.get('trust_score', 'N/A')}/100 (Rating: {d.get('rating', 'N/A')})",
                f"Crash Probability: {d.get('crash_probability', 'N/A')}",
                f"Distance to Default: {d.get('distance_to_default', 'N/A')}",
            ]

            if verdict == "CRITICAL":
                lines.append("WARNING: Structural collapse detected. Avoid trading this token.")
            elif verdict == "WARNING":
                lines.append("CAUTION: Elevated risk. Proceed with reduced position size.")

            return "\n".join(lines)

        except Exception as e:
            return f"ZARQ API unavailable: {e}"
