"""Minimal Crypto Pay API client for @CryptoBot (https://help.crypt.bot/crypto-pay-api)."""
from __future__ import annotations

import httpx

from app import runtime
from app.config import get_settings


async def _request(method: str, http_method: str = "POST", **params) -> dict:
    settings = get_settings()
    url = settings.crypto_pay_api_url.rstrip("/") + "/" + method
    headers = {"Crypto-Pay-API-Token": runtime.crypto_token()}
    async with httpx.AsyncClient(timeout=20) as client:
        if http_method == "GET":
            resp = await client.get(url, headers=headers, params=params)
        else:
            resp = await client.post(url, headers=headers, json=params)
    data = resp.json()
    if not data.get("ok"):
        raise RuntimeError(f"Crypto Pay error: {data.get('error')}")
    return data["result"]


async def create_invoice(
    amount: float, asset: str, description: str, payload: str
) -> dict:
    """Creates an invoice. Returns dict with invoice_id, bot_invoice_url, status, ..."""
    return await _request(
        "createInvoice",
        asset=asset,
        amount=f"{amount:.2f}",
        description=description[:1024],
        payload=payload,
        allow_comments=False,
        allow_anonymous=True,
    )


async def get_invoice(invoice_id: str) -> dict | None:
    """Returns the invoice dict (status 'active' | 'paid' | 'expired') or None."""
    result = await _request("getInvoices", http_method="GET", invoice_ids=str(invoice_id))
    items = result.get("items", [])
    return items[0] if items else None


async def transfer(
    user_id: int, amount: float, asset: str, spend_id: str, comment: str = ""
) -> dict:
    """Send funds to a Telegram user via Crypto Pay transfer."""
    return await _request(
        "transfer",
        user_id=user_id,
        asset=asset,
        amount=f"{amount:.2f}",
        spend_id=spend_id,
        comment=comment[:1024],
        disable_send_notification=False,
    )
