mod common;

use common::{authed_client, authenticate, authenticate_funded, first_pair_id};
use uuid::Uuid;

#[tokio::test]
#[ignore = "requires running API server"]
async fn order_lifecycle() {
    let (token, _address, _signer) = authenticate_funded().await;
    let authed = authed_client(&token);
    let pair_id = first_pair_id().await;
    let pair_uuid: Uuid = pair_id.parse().unwrap();

    // Create
    let created = authed
        .create_order(&monaco_sdk::types::CreateOrderRequest {
            trading_pair_id: pair_uuid,
            order_type: "LIMIT".into(),
            side: "BUY".into(),
            price: Some("0.01".into()),
            quantity: "1".into(),
            leverage: None,
            margin_account_id: None,
            risk_bucket_collateral: None,
            risk_bucket_id: None,
            position_side: None,
            reduce_only: None,
            trading_mode: Some("SPOT".into()),
            time_in_force: Some("GTC".into()),
            expiration_date: None,
            slippage_tolerance_bps: None,
            use_master_balance: None,
            stop_loss: None,
            take_profit: None,
            strategy_key: None,
        })
        .await
        .unwrap()
        .into_inner();

    let order_id = created.order_id.unwrap().to_string();

    // Get by ID
    let fetched = authed
        .get_order_by_id(&order_id)
        .await
        .unwrap()
        .into_inner();

    assert_eq!(fetched.id.unwrap().to_string(), order_id);

    // Replace (update price)
    let replaced = authed
        .replace_order(
            &order_id,
            &monaco_sdk::types::ReplaceOrderRequest {
                price: Some("0.02".into()),
                quantity: None,
                use_master_balance: None,
            },
        )
        .await
        .unwrap()
        .into_inner();

    let new_order_id = replaced.order_id.unwrap().to_string();
    assert_ne!(new_order_id, order_id);

    // Cancel the replaced order
    let cancelled = authed
        .cancel_order(&monaco_sdk::types::CancelOrderRequest {
            order_id: new_order_id.parse().unwrap(),
        })
        .await
        .unwrap()
        .into_inner();

    assert_eq!(cancelled.status.as_deref(), Some("SUCCESS"));
}

#[tokio::test]
#[ignore = "requires running API server"]
async fn list_orders() {
    let (token, _address, _signer) = authenticate().await;
    let authed = authed_client(&token);

    let resp = authed
        .get_orders(None, None, None, None, None, None, None)
        .await
        .unwrap()
        .into_inner();

    // New wallet may have no orders — just confirm the call works
    let _ = resp.orders;
}

#[tokio::test]
#[ignore = "requires running API server"]
async fn batch_create_and_cancel() {
    let (token, _address, _signer) = authenticate_funded().await;
    let authed = authed_client(&token);
    let pair_id = first_pair_id().await;
    let pair_uuid: Uuid = pair_id.parse().unwrap();

    // Batch create two orders
    let batch = authed
        .batch_create_orders(&monaco_sdk::types::BatchCreateOrdersRequest {
            orders: vec![
                monaco_sdk::types::BatchCreateOrderItem {
                    trading_pair_id: pair_uuid,
                    order_type: "LIMIT".into(),
                    side: "BUY".into(),
                    price: Some("0.01".into()),
                    quantity: "1".into(),
                    leverage: None,
                    margin_account_id: None,
                    risk_bucket_collateral: None,
                    risk_bucket_id: None,
                    position_side: None,
                    reduce_only: None,
                    trading_mode: Some("SPOT".into()),
                    time_in_force: Some("GTC".into()),
                    expiration_date: None,
                    slippage_tolerance_bps: None,
                    use_master_balance: None,
                    strategy_key: None,
                },
                monaco_sdk::types::BatchCreateOrderItem {
                    trading_pair_id: pair_uuid,
                    order_type: "LIMIT".into(),
                    side: "BUY".into(),
                    price: Some("0.02".into()),
                    quantity: "2".into(),
                    leverage: None,
                    margin_account_id: None,
                    risk_bucket_collateral: None,
                    risk_bucket_id: None,
                    position_side: None,
                    reduce_only: None,
                    trading_mode: Some("SPOT".into()),
                    time_in_force: Some("GTC".into()),
                    expiration_date: None,
                    slippage_tolerance_bps: None,
                    use_master_balance: None,
                    strategy_key: None,
                },
            ],
        })
        .await
        .unwrap()
        .into_inner();

    assert_eq!(batch.total_succeeded, Some(2));

    // Collect created order IDs and batch cancel them
    let order_ids: Vec<Uuid> = batch
        .results
        .unwrap()
        .iter()
        .filter_map(|r| r.order_id)
        .collect();

    assert_eq!(order_ids.len(), 2);

    let cancel_resp = authed
        .batch_cancel_orders(&monaco_sdk::types::BatchCancelOrdersRequest { order_ids })
        .await
        .unwrap()
        .into_inner();

    assert_eq!(cancel_resp.total_cancelled, Some(2));
}
