/*
 * Ethereal Exchange API
 *
 * Ethereal HTTP API for real-time trading, order management, and market data access.
 *
 * The version of the OpenAPI document: 0.1.0
 *
 * Generated by: https://openapi-generator.tech
 */

use crate::models;
use serde::{Deserialize, Serialize};

#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct SubmitOrderMarketDtoData {
    /// Bytes32 encoded subaccount name (0x prefix, zero padded)
    #[serde(rename = "subaccount")]
    pub subaccount: String,
    /// Address of account
    #[serde(rename = "sender")]
    pub sender: String,
    /// Message nonce timestamp (nanoseconds since Unix Epoch)
    #[serde(rename = "nonce")]
    pub nonce: String,
    /// Market order type
    #[serde(rename = "type")]
    pub r#type: Type,
    /// Non-directional quantity of product in native units expressed as a decimal (precision: 9)
    #[serde(rename = "quantity")]
    pub quantity: rust_decimal::Decimal,
    #[serde(rename = "side")]
    pub side: models::OrderSide,
    /// Onchain generated productId from prior product registration
    #[serde(rename = "onchainId")]
    pub onchain_id: i32,
    #[serde(rename = "engineType")]
    pub engine_type: models::EngineType,
    /// A subaccount scoped unique client-generated order id (either a UUID or alphanumeric string up to 32 characters)
    #[serde(rename = "clientOrderId", skip_serializing_if = "Option::is_none")]
    pub client_order_id: Option<String>,
    /// Whether this should be a reduce-only order, required for close
    #[serde(rename = "reduceOnly", skip_serializing_if = "Option::is_none")]
    pub reduce_only: Option<bool>,
    /// Order closes the entire current position, requires zero quantity and reduceOnly
    #[serde(rename = "close", skip_serializing_if = "Option::is_none")]
    pub close: Option<bool>,
    /// Stop price expressed as a decimal (precision: 9), requires stopType
    #[serde(rename = "stopPrice", skip_serializing_if = "Option::is_none")]
    pub stop_price: Option<rust_decimal::Decimal>,
    /// Stop type, either 0 (take-profit) or 1 (stop-loss), requires non-zero stopPrice
    #[serde(rename = "stopType", skip_serializing_if = "Option::is_none")]
    pub stop_type: Option<StopType>,
    /// Message signedAt current timestamp (seconds since Unix Epoch)
    #[serde(rename = "signedAt")]
    pub signed_at: i64,
    /// Order expiry timestamp (seconds since Unix Epoch), defaults to the maximum allowed value: signedAt + 6652800
    #[serde(rename = "expiresAt", skip_serializing_if = "Option::is_none")]
    pub expires_at: Option<i64>,
    /// Group Id (UUID) for linking orders together in OCO/OTO relationships
    #[serde(rename = "groupId", skip_serializing_if = "Option::is_none")]
    pub group_id: Option<uuid::Uuid>,
    /// Contingency type for order groups: OTO (Order-Triggers-Order) or OCO (One-Cancels-Other)
    #[serde(
        rename = "groupContingencyType",
        skip_serializing_if = "Option::is_none"
    )]
    pub group_contingency_type: Option<GroupContingencyType>,
}

impl SubmitOrderMarketDtoData {
    pub fn new(
        subaccount: String,
        sender: String,
        nonce: String,
        r#type: Type,
        quantity: rust_decimal::Decimal,
        side: models::OrderSide,
        onchain_id: i32,
        engine_type: models::EngineType,
        signed_at: i64,
    ) -> SubmitOrderMarketDtoData {
        SubmitOrderMarketDtoData {
            subaccount,
            sender,
            nonce,
            r#type,
            quantity,
            side,
            onchain_id,
            engine_type,
            client_order_id: None,
            reduce_only: None,
            close: None,
            stop_price: None,
            stop_type: None,
            signed_at,
            expires_at: None,
            group_id: None,
            group_contingency_type: None,
        }
    }
}
/// Market order type
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum Type {
    #[serde(rename = "MARKET")]
    Market,
}

impl Default for Type {
    fn default() -> Type {
        Self::Market
    }
}
/// Stop type, either 0 (take-profit) or 1 (stop-loss), requires non-zero stopPrice
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum StopType {
    #[serde(rename = "0")]
    GAIN,
    #[serde(rename = "1")]
    LOSS,
}

impl Default for StopType {
    fn default() -> StopType {
        Self::GAIN
    }
}
/// Contingency type for order groups: OTO (Order-Triggers-Order) or OCO (One-Cancels-Other)
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize)]
pub enum GroupContingencyType {
    #[serde(rename = "0")]
    OTO,
    #[serde(rename = "1")]
    OCO,
}

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