// Copyright (c) Subzero Labs, Inc.
// SPDX-License-Identifier: Apache-2.0

//! Types for the `getValidatorAccounts` RPC method.

use serde::{Deserialize, Serialize};

use super::rpc_response_context::RpcResponseContext;

/// Request for getValidatorAccounts RPC call.
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)]
pub struct GetValidatorAccountsRequest {
    /// Protocol version for forward compatibility.
    #[serde(default)]
    pub version: u16,
    /// If true, returns validator accounts from the last frozen epoch (current epoch state).
    /// If false (default), returns from pending (next epoch state with all accumulated changes).
    /// Both use layered lookup (frozen → baseline or pending → frozen → baseline).
    pub use_frozen: bool,
}

impl GetValidatorAccountsRequest {
    /// Create a new request with default parameters (use_frozen = false).
    pub fn new() -> Self {
        Self {
            version: 0,
            use_frozen: false,
        }
    }

    /// Create a request that returns validators from the last frozen epoch.
    pub fn with_frozen() -> Self {
        Self {
            version: 0,
            use_frozen: true,
        }
    }
}

/// The response message for a getValidatorAccounts request.
#[derive(Serialize, Deserialize, Debug)]
pub struct GetValidatorAccountsResponse {
    pub context: RpcResponseContext,
    /// List of all validator accounts.
    pub value: Vec<ValidatorAccountInfo>,
    /// The epoch number of the returned snapshot.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub epoch: Option<u64>,
    /// The timestamp (ms) of the returned snapshot's epoch boundary.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub timestamp: Option<u64>,
}

/// Information about a validator account.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ValidatorAccountInfo {
    /// The accumulated commission (kelvins) in the validator account.
    pub commission: u64,
    /// The public key of the validator info account (base58-encoded).
    pub pubkey: String,
    /// The validator's public key for transaction signing (base58-encoded).
    pub signing_key: String,
    /// The validator's public key for withdrawing commission (base58-encoded).
    pub withdrawal_key: String,
    /// Aggregate delegated stake for this validator.
    pub stake: u64,
    /// Network address for consensus communication (base64-encoded).
    pub address: String,
    /// Network address for state synchronization (base64-encoded).
    pub state_sync_address: String,
    /// Human-readable hostname for metrics and logging.
    pub hostname: String,
    /// The validator's identity key (base64-encoded).
    pub authority_key: String,
    /// The validator's public key for verifying blocks (base58-encoded).
    pub protocol_key: String,
    /// The validator's public key for TLS and as network identity (base58-encoded).
    pub network_key: String,
    /// When they registered (Unix timestamp).
    pub registration_time: i64,
    /// Last time info was updated (Unix timestamp).
    pub last_update: i64,
    /// Historical unbonding periods: effective_from_timestamp → unbonding_period_ms.
    /// Set by the runtime (via SetUnbondingPeriod) to punish misbehaving validators.
    /// The first entry contains the default unbonding period from registration.
    pub unbonding_periods: std::collections::BTreeMap<u64, u64>,
    /// The minimum duration in milliseconds that StakeInfo accounts must commit
    /// to delegate for; can be set by the validator to earn increased rewards (bonus).
    /// Note: An activated stake cannot be deactivated until
    /// `current_timestamp >= activation_requested + lockup_period`.
    pub lockup_period: u64,
    /// The validator's commission from the inflation rewards in basis points
    /// (e.g. 835 corresponds to 8.35%).
    pub commission_rate: u16,
    /// New commission_rate to be applied from the next epoch.
    pub new_commission_rate: Option<u16>,
    /// Optional timestamp (ms) after which the validator does not intend to participate
    /// in committees. None means no shutdown is planned.
    pub earliest_shutdown: Option<u64>,
}
