// 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 {
    /// 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).
    #[serde(default)]
    pub use_frozen: bool,
}

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

    /// Create a request that returns validators from the last frozen epoch.
    pub fn with_frozen() -> Self {
        Self { 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>,
}

/// 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 node's public key (the initial authorized withdrawer, base58-encoded).
    pub node_identity: String,
    /// Authority who can withdraw rewards (base58-encoded).
    pub authorized_withdrawer: String,
    /// Amount of token staked for next epoch (from current stakes cache).
    pub stake_next: u64,
    /// Amount of token staked for current epoch (from last frozen snapshot).
    /// None if validator not present in the last frozen snapshot.
    pub stake_current: Option<u64>,
    /// Network address for communicating with the authority (base64-encoded).
    pub address: String,
    /// The authority's hostname, for metrics and logging.
    pub hostname: String,
    /// The authority's public key as Rialo identity (base64-encoded).
    pub authority_key: String,
    /// The authority's public key for verifying blocks (base58-encoded).
    pub protocol_key: String,
    /// The authority'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>,
}
