"""EmbiPay Admin API client."""

import urllib.request
import urllib.error
import json
from typing import Any, Optional


class EmbiPayAdmin:
    """
    Client for EmbiPay Admin API.
    Requires base_url and admin token (Bearer).
    """

    def __init__(self, base_url: str, token: str):
        self.base_url = base_url.rstrip("/")
        self.token = token
        self._headers = {
            "Content-Type": "application/json",
            "Authorization": f"Bearer {token}",
        }

    def _request(self, method: str, path: str, body: Optional[dict] = None) -> dict:
        url = f"{self.base_url}{path}"
        data = json.dumps(body).encode() if body else None
        req = urllib.request.Request(url, data=data, headers=self._headers, method=method)
        try:
            with urllib.request.urlopen(req) as resp:
                return json.loads(resp.read().decode())
        except urllib.error.HTTPError as e:
            err_body = e.read().decode() if e.fp else "{}"
            try:
                data = json.loads(err_body)
            except json.JSONDecodeError:
                data = {"error": err_body}
            raise Exception(data.get("error", data.get("details", str(e)))) from e

    # Wallets
    def create_wallet(self, owner_user_id: str, balance: float = 0, **kwargs) -> dict:
        return self._request("POST", "/api/admin/create-wallet", {
            "owner_user_id": owner_user_id,
            "balance": balance,
            **kwargs,
        })

    def update_wallet_balance(self, agent_id: int, balance: float) -> dict:
        return self._request("POST", "/api/admin/updateWalletBalance", {
            "agent_id": agent_id,
            "balance": balance,
        })

    # Loans
    def create_loan(self, lender_agent_id: int, borrower_agent_id: int, amount: float, **kwargs) -> dict:
        return self._request("POST", "/api/admin/create-loan", {
            "lender_agent_id": lender_agent_id,
            "borrower_agent_id": borrower_agent_id,
            "amount": amount,
            **kwargs,
        })

    def approve_loan(self, loan_id: int) -> dict:
        return self._request("POST", "/api/admin/approveLoan", {"loan_id": loan_id})

    def reject_loan(self, loan_id: int) -> dict:
        return self._request("POST", "/api/admin/rejectLoan", {"loan_id": loan_id})

    def get_loan_details(self, loan_id: int, num_installments: int = 1) -> dict:
        return self._request("GET", f"/api/admin/loan-details?loan_id={loan_id}&num_installments={num_installments}")

    def record_repayment(self, loan_id: int, amount: float, note: Optional[str] = None) -> dict:
        return self._request("POST", "/api/admin/record-repayment", {
            "loan_id": loan_id,
            "amount": amount,
            "note": note,
        })

    def fetch_a2a_loans(self) -> dict:
        return self._request("GET", "/api/admin/fetch-a2a-loans")

    # Pools
    def create_shared_pool(self, resource_id: str, total_cost: float) -> dict:
        return self._request("POST", "/api/admin/create-shared-pool", {
            "resource_id": resource_id,
            "total_cost": total_cost,
        })

    def contribute_to_pool(self, pool_id: int, agent_id: int, amount: float, usage_limit: int = 0) -> dict:
        return self._request("POST", "/api/admin/contribute-to-pool", {
            "pool_id": pool_id,
            "agent_id": agent_id,
            "amount": amount,
            "usage_limit": usage_limit,
        })

    def get_pool_details(self, pool_id: int, allocation_rule: str = "pro_rata") -> dict:
        return self._request("GET", f"/api/admin/pool-details?pool_id={pool_id}&allocation_rule={allocation_rule}")

    def record_pool_usage(self, pool_id: int, agent_id: int) -> dict:
        return self._request("POST", "/api/admin/record-pool-usage", {
            "pool_id": pool_id,
            "agent_id": agent_id,
        })

    # Webhooks
    def register_webhook(self, url: str, events: list[str], secret: Optional[str] = None) -> dict:
        return self._request("POST", "/api/admin/register-webhook", {
            "url": url,
            "events": events,
            "secret": secret,
        })

    def list_webhooks(self) -> dict:
        return self._request("GET", "/api/admin/register-webhook")

    # Ledgers & Tasks
    def fetch_all_ledgers(self, **params) -> dict:
        q = "&".join(f"{k}={v}" for k, v in params.items() if v is not None)
        path = f"/api/admin/fetchAllLedgers?{q}" if q else "/api/admin/fetchAllLedgers"
        return self._request("GET", path)

    def get_agent_tasks(self, **params) -> dict:
        q = "&".join(f"{k}={v}" for k, v in params.items() if v is not None)
        path = f"/api/admin/agent-tasks?{q}" if q else "/api/admin/agent-tasks"
        return self._request("GET", path)

    def get_agent_tasks_overview(self, **params) -> dict:
        q = "&".join(f"{k}={v}" for k, v in params.items() if v is not None)
        path = f"/api/admin/agent-tasks-overview?{q}" if q else "/api/admin/agent-tasks-overview"
        return self._request("GET", path)
