"""
Bankr wallet authentication — signing, wallet resolution, transaction submission.
"""

import time
import logging
import requests as _requests

log = logging.getLogger("litcoin")

BANKR_BASE = "https://api.bankr.bot"
CLAIMS_CONTRACT = "0xF703DcF2E88C0673F776870fdb12A453927C6A5e"


class BankrAuth:
    """Manages Bankr wallet operations: signing, wallet lookup, tx submission."""

    def __init__(self, api_key):
        if not api_key:
            raise ValueError("Bankr API key required (bk_...)")
        self.api_key = api_key
        self._wallet = None

    def _headers(self):
        return {"Content-Type": "application/json", "X-API-Key": self.api_key}

    @property
    def wallet(self):
        """Resolve and cache the wallet address from Bankr."""
        if self._wallet:
            return self._wallet
        r = _requests.get(f"{BANKR_BASE}/agent/me", headers=self._headers(), timeout=15)
        r.raise_for_status()
        data = r.json()
        # Try multiple response formats
        for key in ("wallets", "addresses"):
            items = data.get(key, [])
            if isinstance(items, list):
                for w in items:
                    addr = w.get("address", w) if isinstance(w, dict) else w
                    if isinstance(addr, str) and addr.startswith("0x"):
                        self._wallet = addr.lower()
                        return self._wallet
        for key in ("address", "evmAddress", "wallet"):
            if key in data and isinstance(data[key], str) and data[key].startswith("0x"):
                self._wallet = data[key].lower()
                return self._wallet
        raise ValueError(f"No wallet found in Bankr response: {data}")

    def sign(self, message):
        """Sign a message via Bankr personal_sign."""
        r = _requests.post(f"{BANKR_BASE}/agent/sign", headers=self._headers(), timeout=15,
                           json={"signatureType": "personal_sign", "message": message})
        r.raise_for_status()
        sig = r.json().get("signature")
        if not sig:
            raise ValueError("No signature returned from Bankr")
        return sig

    def submit_tx(self, to, calldata, value="0"):
        """Submit a raw transaction via Bankr."""
        r = _requests.post(f"{BANKR_BASE}/agent/submit", headers=self._headers(), timeout=30,
                           json={"transaction": {
                               "to": to, "data": calldata, "value": value, "chainId": 8453
                           }})
        if r.status_code != 200:
            raise ValueError(f"Bankr tx failed: {r.status_code} {r.text[:300]}")
        data = r.json()
        tx_hash = data.get("hash") or data.get("txHash") or data.get("transactionHash")
        return {"hash": tx_hash, "raw": data}


class AuthSession:
    """Manages JWT authentication with the coordinator."""

    def __init__(self, bankr, api):
        self.bankr = bankr
        self.api = api
        self._token = None
        self._expiry = 0

    @property
    def token(self):
        """Get a valid auth token, refreshing if needed."""
        if self._token and time.time() < (self._expiry - 60):
            return self._token
        return self.refresh()

    def refresh(self):
        """Force-refresh the auth token."""
        wallet = self.bankr.wallet
        message = self.api.get_nonce(wallet)
        signature = self.bankr.sign(message)
        self._token = self.api.verify_auth(wallet, message, signature)
        self._expiry = time.time() + 3600
        log.info("Authenticated with coordinator")
        return self._token

    def header(self):
        return {"Authorization": f"Bearer {self.token}"}
