"""VKP Client — unified interface to the Vaultfire Key Protocol.

Connect once, access all three layers: KeyVault, SessionKeys, and Delegations.
"""

from web3 import Web3

from .constants import SUPPORTED_NETWORKS
from .delegation import DelegationManager
from .keyvault import KeyVaultManager
from .session import SessionKeyManager


class VKPClient:
    """Unified client for the Vaultfire Key Protocol.

    Provides access to:
    - ``keyvault`` — On-chain spending policy enforcement
    - ``sessions`` — Time-limited, scoped session keys
    - ``delegations`` — Encrypted key delegation between verified agents

    Example:
        >>> from vkp import VKPClient
        >>>
        >>> client = VKPClient(
        ...     rpc_url="https://mainnet.base.org",
        ...     network_id="base-mainnet",
        ... )
        >>>
        >>> # Check vault status
        >>> status = client.keyvault.get_status("0xMyVault...")
        >>> print(f"Balance: {status.balance_eth} ETH")
        >>> print(f"Frozen: {status.policy.frozen}")
        >>>
        >>> # Create a scoped session key
        >>> tx = client.sessions.create_session(
        ...     from_address="0xMyAgent...",
        ...     session_address="0xTempKey...",
        ...     max_value="0.01",
        ...     duration_hours=24,
        ... )
        >>>
        >>> # Delegate to another verified agent
        >>> tx = client.delegations.create_delegation(
        ...     from_address="0xMyAgent...",
        ...     delegate="0xPartnerAgent...",
        ...     max_value="0.1",
        ...     total_limit="1.0",
        ...     duration_hours=48,
        ...     min_bond="0.01",
        ...     min_reputation=50,
        ... )
    """

    def __init__(
        self,
        rpc_url: str,
        network_id: str,
        factory_address: str | None = None,
        session_manager_address: str | None = None,
        delegation_registry_address: str | None = None,
    ):
        """Initialize the VKP client.

        Args:
            rpc_url: The RPC endpoint for the chain.
            network_id: Network identifier (e.g. 'base-mainnet').
            factory_address: Address of the deployed VKPFactory contract.
            session_manager_address: Address of the deployed SessionKeyManager.
            delegation_registry_address: Address of the deployed DelegationRegistry.
        """
        if network_id not in SUPPORTED_NETWORKS:
            raise ValueError(
                f"Unsupported network: {network_id}. "
                f"Supported: {', '.join(SUPPORTED_NETWORKS)}"
            )

        self._w3 = Web3(Web3.HTTPProvider(rpc_url))
        self._network_id = network_id

        self.keyvault = KeyVaultManager(self._w3, network_id, factory_address)
        self.sessions = SessionKeyManager(self._w3, network_id, session_manager_address)
        self.delegations = DelegationManager(
            self._w3, network_id, delegation_registry_address
        )

    @property
    def network_id(self) -> str:
        """The network this client is connected to."""
        return self._network_id

    @property
    def is_connected(self) -> bool:
        """Check if the client is connected to the RPC endpoint."""
        return self._w3.is_connected()

    @property
    def chain_id(self) -> int:
        """The chain ID of the connected network."""
        return self._w3.eth.chain_id

    @property
    def w3(self) -> Web3:
        """Direct access to the Web3 instance."""
        return self._w3
