//! Privacy SDK types

use serde::{Deserialize, Serialize};

/// Default privacy endpoint
pub const DEFAULT_PRIVACY_ENDPOINT: &str = "https://privacy.synor.cc/api/v1";

/// Privacy client configuration
#[derive(Clone, Debug)]
pub struct PrivacyConfig {
    pub api_key: String,
    pub endpoint: String,
    pub timeout_secs: u64,
    pub retries: u32,
    pub debug: bool,
}

impl Default for PrivacyConfig {
    fn default() -> Self {
        Self {
            api_key: String::new(),
            endpoint: DEFAULT_PRIVACY_ENDPOINT.to_string(),
            timeout_secs: 30,
            retries: 3,
            debug: false,
        }
    }
}

/// Key type
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum KeyType {
    Ed25519,
    Secp256k1,
}

/// Generator type for commitments
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum GeneratorType {
    Default,
    Alternate,
}

impl Default for GeneratorType {
    fn default() -> Self {
        Self::Default
    }
}

/// Public key
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PublicKey {
    pub key: String,
    #[serde(rename = "type")]
    pub key_type: KeyType,
}

/// Private key
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct PrivateKey {
    pub key: String,
    #[serde(rename = "type")]
    pub key_type: KeyType,
}

/// UTXO for confidential transactions
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfidentialUtxo {
    pub txid: String,
    pub vout: u32,
    pub commitment: String,
    #[serde(rename = "rangeProof")]
    pub range_proof: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub blinding: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub amount: Option<String>,
}

/// Output for confidential transactions
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfidentialOutput {
    pub recipient: String,
    pub amount: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub blinding: Option<String>,
}

/// Output features
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OutputFeatures {
    pub flags: u32,
    #[serde(rename = "lockHeight", skip_serializing_if = "Option::is_none")]
    pub lock_height: Option<u64>,
}

/// Confidential transaction input
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfidentialTxInput {
    #[serde(rename = "outputRef")]
    pub output_ref: String,
    pub commitment: String,
}

/// Confidential transaction output
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfidentialTxOutput {
    pub commitment: String,
    #[serde(rename = "rangeProof")]
    pub range_proof: String,
    pub features: OutputFeatures,
}

/// Transaction kernel
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct TransactionKernel {
    pub features: u32,
    pub fee: String,
    #[serde(rename = "lockHeight")]
    pub lock_height: u64,
    pub excess: String,
    #[serde(rename = "excessSignature")]
    pub excess_signature: String,
}

/// Confidential transaction
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfidentialTransaction {
    pub txid: String,
    pub version: u32,
    pub inputs: Vec<ConfidentialTxInput>,
    pub outputs: Vec<ConfidentialTxOutput>,
    pub kernel: TransactionKernel,
    pub offset: String,
    pub raw: String,
}

/// Verification details for confidential transaction
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VerifyConfidentialTxDetails {
    #[serde(rename = "commitmentsBalance")]
    pub commitments_balance: bool,
    #[serde(rename = "rangeProofsValid")]
    pub range_proofs_valid: bool,
    #[serde(rename = "signatureValid")]
    pub signature_valid: bool,
    #[serde(rename = "noDuplicateInputs")]
    pub no_duplicate_inputs: bool,
}

/// Verification result for confidential transaction
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VerifyConfidentialTxResult {
    pub valid: bool,
    pub details: VerifyConfidentialTxDetails,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub error: Option<String>,
}

/// Ring signature components
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RingSignatureComponents {
    pub c: Vec<String>,
    pub r: Vec<String>,
}

/// Ring signature
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RingSignature {
    pub id: String,
    #[serde(rename = "messageHash")]
    pub message_hash: String,
    pub ring: Vec<String>,
    #[serde(rename = "keyImage")]
    pub key_image: String,
    pub signature: RingSignatureComponents,
    #[serde(rename = "ringSize")]
    pub ring_size: u32,
}

/// Ring signature verification result
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VerifyRingSignatureResult {
    pub valid: bool,
    #[serde(rename = "keyImage")]
    pub key_image: String,
}

/// Stealth address
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StealthAddress {
    pub address: String,
    #[serde(rename = "scanPublicKey")]
    pub scan_public_key: String,
    #[serde(rename = "spendPublicKey")]
    pub spend_public_key: String,
}

/// Stealth keypair
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct StealthKeypair {
    pub address: StealthAddress,
    #[serde(rename = "scanPrivateKey")]
    pub scan_private_key: String,
    #[serde(rename = "spendPrivateKey")]
    pub spend_private_key: String,
}

/// One-time address
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OneTimeAddress {
    pub address: String,
    #[serde(rename = "ephemeralPublicKey")]
    pub ephemeral_public_key: String,
    #[serde(rename = "sharedSecret", skip_serializing_if = "Option::is_none")]
    pub shared_secret: Option<String>,
}

/// Shared secret
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SharedSecret {
    pub secret: String,
    #[serde(rename = "oneTimePrivateKey")]
    pub one_time_private_key: String,
    #[serde(rename = "oneTimeAddress")]
    pub one_time_address: String,
}

/// Pedersen commitment
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Commitment {
    pub commitment: String,
    #[serde(default)]
    pub generator: GeneratorType,
}

/// Commitment with blinding factor
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct CommitmentWithBlinding {
    pub commitment: Commitment,
    pub blinding: String,
}

/// Range proof
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RangeProof {
    pub proof: String,
    pub commitment: String,
    #[serde(rename = "bitLength")]
    pub bit_length: u32,
}

/// Range proof verification result
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct VerifyRangeProofResult {
    pub valid: bool,
    #[serde(rename = "minValue")]
    pub min_value: String,
    #[serde(rename = "maxValue")]
    pub max_value: String,
}

/// Options for creating a confidential transaction
#[derive(Clone, Debug, Default)]
pub struct CreateConfidentialTxOptions {
    pub inputs: Vec<ConfidentialUtxo>,
    pub outputs: Vec<ConfidentialOutput>,
    pub fee: Option<String>,
    pub lock_height: Option<u64>,
}

/// Options for creating a ring signature
#[derive(Clone, Debug)]
pub struct CreateRingSignatureOptions {
    pub message: String,
    pub ring: Vec<String>,
    pub private_key: String,
    pub signer_index: Option<u32>,
}

/// Options for creating a range proof
#[derive(Clone, Debug)]
pub struct CreateRangeProofOptions {
    pub value: String,
    pub blinding: String,
    pub message: Option<String>,
    pub bit_length: Option<u32>,
}
