"""
near_transfer_py — NEAR Protocol transfer management client.
CRUD operations for tracking and managing NEAR token transfers.
Note: Sending transactions requires signing — this client handles tracking and querying.
"""
import json
import base64
import hashlib
import requests
from typing import Any, Dict, List, Optional
from datetime import datetime, timezone

__version__ = "1.0.0"
__all__ = ["NEARTransferManager"]

NEAR_RPC = "https://rpc.mainnet.near.org"


def _rpc(method: str, params: Any) -> Dict:
    """Execute NEAR JSON-RPC call."""
    resp = requests.post(NEAR_RPC, json={"jsonrpc":"2.0","id":"1","method":method,"params":params}, timeout=15)
    resp.raise_for_status()
    data = resp.json()
    if "error" in data:
        raise RuntimeError(f"RPC error: {data['error']}")
    return data.get("result", {})


class NEARTransferManager:
    """NEAR Protocol transfer management client."""

    def __init__(self, network: str = "mainnet"):
        """Initialize. network: 'mainnet' or 'testnet'."""
        self.network = network
        self.rpc_url = NEAR_RPC if network == "mainnet" else "https://rpc.testnet.near.org"
        self._transfers: List[Dict] = []

    def create_transfer_record(self, sender: str, receiver: str,
                                amount_near: float, note: str = "") -> Dict:
        """Create a pending transfer record (CRUD: Create)."""
        record = {"id": hashlib.md5(f"{sender}{receiver}{amount_near}{datetime.now()}".encode()).hexdigest()[:12],
            "sender": sender, "receiver": receiver, "amount_near": amount_near,
            "amount_yocto": str(int(amount_near * 10**24)), "note": note,
            "status": "pending", "created_at": datetime.now(timezone.utc).isoformat(), "tx_hash": None}
        self._transfers.append(record)
        return record

    def get_transfer(self, transfer_id: str) -> Optional[Dict]:
        """Get a transfer record by ID (CRUD: Read)."""
        return next((t for t in self._transfers if t["id"] == transfer_id), None)

    def update_transfer_status(self, transfer_id: str, status: str, tx_hash: str = "") -> bool:
        """Update transfer status: pending/confirmed/failed (CRUD: Update)."""
        for t in self._transfers:
            if t["id"] == transfer_id:
                t.update({"status": status, "tx_hash": tx_hash, "updated_at": datetime.now(timezone.utc).isoformat()})
                return True
        return False

    def delete_transfer(self, transfer_id: str) -> bool:
        """Remove a transfer record (CRUD: Delete)."""
        before = len(self._transfers)
        self._transfers = [t for t in self._transfers if t["id"] != transfer_id]
        return len(self._transfers) < before

    def list_transfers(self, status: str = None) -> List[Dict]:
        """List transfers, optionally filtered by status."""
        return [t for t in self._transfers if not status or t["status"] == status]

    def get_account_balance(self, account_id: str) -> float:
        """Get NEAR balance for an account."""
        r = _rpc("query", {"request_type":"view_account","finality":"final","account_id":account_id})
        return int(r.get("amount", 0)) / 10**24

    def get_transaction_status(self, tx_hash: str, sender_id: str) -> Dict:
        """Check on-chain transaction status by hash."""
        r = _rpc("tx", [tx_hash, sender_id])
        s = r.get("status", {})
        return {"tx_hash": tx_hash, "status": "success" if "SuccessValue" in str(s) else "failure",
                "block_hash": r.get("transaction_outcome", {}).get("block_hash", "")}

    def get_recent_transfers(self, account_id: str, limit: int = 10) -> List[Dict]:
        """Get recent transfers for an account from local log."""
        return [t for t in self._transfers
                if t["sender"] == account_id or t["receiver"] == account_id][:limit]
