use serde_json::json;
use uforia_execution_core::{
    dry_run_payload, ExecutionError, ExecutionVenue, InstrumentType, OrderIntent, OrderType,
    VenueCapabilities,
};

pub fn capabilities() -> VenueCapabilities {
    VenueCapabilities {
        venue: ExecutionVenue::Lighter,
        instrument_types: vec![InstrumentType::Perp],
        order_types: vec![
            OrderType::Market,
            OrderType::Limit,
            OrderType::Ioc,
            OrderType::ReduceOnlyLimit,
        ],
        supports_post_only: false,
        supports_reduce_only: true,
        supports_amend: true,
        supports_mass_cancel: true,
        supports_private_ws: true,
        supports_quote_routing: false,
    }
}

pub fn build_order_payload(
    intent: &OrderIntent,
    account_index: u64,
    nonce: u64,
) -> Result<serde_json::Value, ExecutionError> {
    let caps = capabilities();
    if !caps.instrument_types.contains(&intent.instrument_type) {
        return Err(ExecutionError::UnsupportedInstrumentType);
    }
    if !caps.order_types.contains(&intent.order_type) {
        return Err(ExecutionError::UnsupportedOrderType);
    }
    Ok(dry_run_payload(
        "lighter_order",
        &[
            ("account_index", json!(account_index)),
            ("nonce", json!(nonce)),
            ("symbol", json!(intent.symbol)),
            ("side", json!(intent.side)),
            ("price", json!(intent.price)),
            ("size", json!(intent.size)),
            ("reduce_only", json!(intent.reduce_only)),
        ],
    ))
}

#[cfg(test)]
mod tests {
    use super::*;
    use uforia_execution_core::{ExecutionVenue, InstrumentType, OrderIntent, OrderSide};

    #[test]
    fn builds_lighter_payload() {
        let mut intent = OrderIntent::new(
            "acct",
            ExecutionVenue::Lighter,
            InstrumentType::Perp,
            "ETH",
            "ETH-PERP",
            OrderSide::Sell,
            OrderType::Limit,
            3.0,
        );
        intent.price = Some(4_000.0);
        let payload = build_order_payload(&intent, 1, 99).expect("payload");
        assert_eq!(payload["account_index"], 1);
        assert_eq!(payload["nonce"], 99);
    }
}
