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

use rialo_shared_types::AccountInfoResponseValue;
use serde::{Deserialize, Serialize};
use validator::Validate;

use super::rpc_response_context::RpcResponseContext;

/// Request parameters for the `getAccountInfo` RPC method
///
/// Gets account information for a given public key. Returns detailed information
/// about the account including kelvin balance, data, owner program, and executable status.
///
/// Solana specification: <https://solana.com/docs/rpc/http/getaccountinfo>
///
/// ## JSON-RPC Request Format
/// ```json
/// {
///   "jsonrpc": "2.0",
///   "id": 1,
///   "method": "getAccountInfo",
///   "params": [
///     "7xB9i2AcjLNJ6M8iZ3LZJvLm7xpSmH7T5uZzR3DeVXWi"
///   ]
/// }
/// ```
///
/// ## Example Response
/// ```json
/// {
///   "jsonrpc": "2.0",
///   "id": 1,
///   "result": {
///     "context": {
///       "slot": 1234567
///     },
///     "value": {
///       "data": ["SGVsbG8gV29ybGQ=", "base64"],
///       "executable": false,
///       "kelvins": 1000000000,
///       "owner": "11111111111111111111111111111111",
///       "rentEpoch": 200
///     }
///   }
/// }
/// ```
///
/// ## Usage Example
/// ```rust
/// use rialo_api_types::messages::get_account_info::{GetAccountInfoRequest, GetAccountInfoConfig};
///
/// let request = GetAccountInfoRequest {
///     address: "7xB9i2AcjLNJ6M8iZ3LZJvLm7xpSmH7T5uZzR3DeVXWi".to_string(),
///     config: Some(GetAccountInfoConfig {
///         data_slice: None,
///         min_context_slot: None,
///     })
/// };
/// ```
#[derive(Debug, Serialize, Deserialize, PartialEq, Validate)]
pub struct GetAccountInfoRequest {
    /// The account public key to query (base58-encoded)
    #[validate(length(min = 1, message = "Address cannot be empty"))]
    #[validate(custom(function = crate::validation::validate_pubkey))]
    pub address: String,
    /// Optional configuration for data slicing
    pub config: Option<GetAccountInfoConfig>,
}

/// Config parameters for the getAccountInfo request.
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GetAccountInfoConfig {
    #[serde(rename = "dataSlice")]
    pub data_slice: Option<DataSliceConfig>,
    #[serde(rename = "minContextSlot")]
    pub min_context_slot: Option<String>,
}

/// Config parameters for how much data should be returned.
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct DataSliceConfig {
    pub offset: u64,
    pub length: u64,
}

/// The response message for a getAccountInfo request.
/// Solana specification: <https://solana.com/docs/rpc/http/getaccountinfo>
#[derive(Serialize, Deserialize, Debug)]
pub struct AccountInfoResponse {
    pub context: RpcResponseContext,
    pub value: Option<AccountInfoResponseValue>,
}
