// client/tests/form_request_tests.rs
pub use rstest::{fixture, rstest};
pub use client::services::grpc_client::GrpcClient;
pub use client::state::pages::form::FormState;
pub use client::state::pages::canvas_state::CanvasState;
pub use prost_types::Value;
pub use prost_types::value::Kind;
pub use std::collections::HashMap;
pub use tonic::Status;
pub use tokio::time::{timeout, Duration};
pub use std::time::{SystemTime, UNIX_EPOCH};

// ========================================================================
// HELPER FUNCTIONS AND UTILITIES
// ========================================================================

/// Generate unique identifiers for test isolation using timestamp
fn generate_unique_id() -> String {
    let timestamp = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .as_nanos();
    // Ensure we always get a 12-character hex string by padding with zeros
    format!("{:012x}", timestamp % 1_000_000_000_000u128)
}

/// Helper function to create string value
fn create_string_value(s: &str) -> Value {
    Value { 
        kind: Some(Kind::StringValue(s.to_string())) 
    }
}

/// Helper function to create number value
fn create_number_value(n: f64) -> Value {
    Value { 
        kind: Some(Kind::NumberValue(n)) 
    }
}

/// Helper function to create boolean value
fn create_bool_value(b: bool) -> Value {
    Value { 
        kind: Some(Kind::BoolValue(b)) 
    }
}

/// Helper function to create null value
fn create_null_value() -> Value {
    Value { 
        kind: Some(Kind::NullValue(0)) 
    }
}

/// Check if backend is available
async fn is_backend_available() -> bool {
    if std::env::var("SKIP_BACKEND_TESTS").is_ok() {
        return false;
    }
    
    match GrpcClient::new().await {
        Ok(_) => true,
        Err(_) => false,
    }
}

/// Skip test if backend is not available
macro_rules! skip_if_backend_unavailable {
    () => {
        if !is_backend_available().await {
            println!("Backend unavailable - skipping test");
            return;
        }
    };
}

// ========================================================================
// TEST CONTEXT AND FIXTURES
// ========================================================================

#[derive(Clone)]
struct FormTestContext {
    client: GrpcClient,
    profile_name: String,
    table_name: String,
}

impl FormTestContext {
    /// Create test form data for insertion
    fn create_test_form_data(&self) -> HashMap<String, Value> {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value("Test Company Ltd"));
        data.insert("telefon".to_string(), create_string_value("+421123456789"));
        data.insert("email".to_string(), create_string_value("test@company.com"));
        data.insert("kz".to_string(), create_string_value("KZ123"));
        data.insert("ulica".to_string(), create_string_value("Test Street 123"));
        data.insert("mesto".to_string(), create_string_value("Test City"));
        data
    }

    /// Create minimal valid form data
    fn create_minimal_form_data(&self) -> HashMap<String, Value> {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value("Minimal Company"));
        data
    }

    /// Create form data with invalid fields
    fn create_invalid_form_data(&self) -> HashMap<String, Value> {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value("Test Company"));
        data.insert("nonexistent_field".to_string(), create_string_value("Invalid"));
        data
    }

    /// Create form data with type mismatches
    fn create_type_mismatch_data(&self) -> HashMap<String, Value> {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value("Test Company"));
        data.insert("age".to_string(), create_string_value("thirty")); // String for number field
        data
    }
}

#[fixture]
async fn form_test_context() -> FormTestContext {
    let client = GrpcClient::new()
        .await
        .expect("Failed to create gRPC client for test");
    
    let unique_id = generate_unique_id();
    let profile_name = format!("test_profile_{}", unique_id);
    let table_name = format!("test_table_{}", unique_id);

    FormTestContext {
        client,
        profile_name,
        table_name,
    }
}

#[fixture]
async fn populated_test_context() -> FormTestContext {
    let mut context = form_test_context().await;
    
    // Pre-populate with test data if backend is available
    if is_backend_available().await {
        let test_data = context.create_test_form_data();
        let _ = context.client.post_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            test_data,
        ).await;
    }
    
    context
}

#[rstest]
#[tokio::test]
async fn test_post_table_data_success(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let test_data = context.create_test_form_data();

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data.clone(),
    ).await;

    match result {
        Ok(response) => {
            assert!(response.success, "POST operation should succeed");
            assert!(response.inserted_id > 0, "Should return valid inserted ID");
            assert!(!response.message.is_empty(), "Should return non-empty message");
            println!("POST successful: ID {}, Message: {}", response.inserted_id, response.message);
        }
        Err(e) => {
            if let Some(status) = e.downcast_ref::<Status>() {
                if status.code() == tonic::Code::Unavailable {
                    println!("Backend unavailable - test cannot run");
                    return;
                }
            }
            panic!("POST request failed unexpectedly: {}", e);
        }
    }
}

#[rstest]
#[tokio::test]
async fn test_post_table_data_minimal_data(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let minimal_data = context.create_minimal_form_data();

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        minimal_data,
    ).await;

    assert!(result.is_ok(), "POST with minimal data should succeed");
    let response = result.unwrap();
    assert!(response.success);
    assert!(response.inserted_id > 0);
}

#[rstest]
#[tokio::test]
async fn test_get_table_data_count_success(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let result = context.client.get_table_data_count(
        context.profile_name.clone(),
        context.table_name.clone(),
    ).await;

    match result {
        Ok(count) => {
            assert!(count >= 0, "Count should be non-negative");
            println!("GET count successful: {}", count);
        }
        Err(e) => {
            if let Some(status) = e.downcast_ref::<Status>() {
                if status.code() == tonic::Code::Unavailable {
                    println!("Backend unavailable - test cannot run");
                    return;
                }
            }
            panic!("GET count request failed unexpectedly: {}", e);
        }
    }
}

#[rstest]
#[tokio::test]
async fn test_get_table_data_by_id_with_existing_record(#[future] populated_test_context: FormTestContext) {
    let mut context = populated_test_context.await;
    skip_if_backend_unavailable!();

    // First create a record
    let test_data = context.create_test_form_data();
    let post_result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data.clone(),
    ).await;

    if let Ok(post_response) = post_result {
        let created_id = post_response.inserted_id;

        // Now try to get it
        let get_result = context.client.get_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            created_id,
        ).await;

        match get_result {
            Ok(response) => {
                assert!(!response.data.is_empty(), "Should return data fields");
                println!("GET by ID successful: {} fields", response.data.len());

                // Verify some data matches
                if let Some(firma_value) = response.data.get("firma") {
                    assert_eq!(firma_value, "Test Company Ltd");
                }
            }
            Err(e) => panic!("GET by ID failed unexpectedly: {}", e),
        }
    } else {
        println!("Could not create test record, skipping GET test");
    }
}

#[rstest]
#[tokio::test]
async fn test_get_table_data_by_nonexistent_id(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let nonexistent_id = 99999;
    let result = context.client.get_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        nonexistent_id,
    ).await;

    assert!(result.is_err(), "GET should fail for nonexistent ID");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::NotFound);
    }
}

#[rstest]
#[tokio::test]
async fn test_put_table_data_success(#[future] populated_test_context: FormTestContext) {
    let mut context = populated_test_context.await;
    skip_if_backend_unavailable!();

    // First create a record
    let test_data = context.create_test_form_data();
    let post_result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data,
    ).await;

    if let Ok(post_response) = post_result {
        let created_id = post_response.inserted_id;

        // Update the record
        let mut update_data = HashMap::new();
        update_data.insert("firma".to_string(), create_string_value("Updated Company Name"));
        update_data.insert("telefon".to_string(), create_string_value("+421987654321"));

        let put_result = context.client.put_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            created_id,
            update_data,
        ).await;

        match put_result {
            Ok(response) => {
                assert!(response.success, "PUT operation should succeed");
                assert_eq!(response.updated_id, created_id, "Should return correct updated ID");
                println!("PUT successful: ID {}, Message: {}", response.updated_id, response.message);
            }
            Err(e) => panic!("PUT request failed unexpectedly: {}", e),
        }
    } else {
        println!("Could not create test record, skipping PUT test");
    }
}

#[rstest]
#[tokio::test]
async fn test_put_table_data_nonexistent_id(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let nonexistent_id = 99999;
    let mut update_data = HashMap::new();
    update_data.insert("firma".to_string(), create_string_value("Updated Company"));

    let result = context.client.put_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        nonexistent_id,
        update_data,
    ).await;

    assert!(result.is_err(), "PUT should fail for nonexistent ID");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::NotFound);
    }
}

#[rstest]
#[tokio::test]
async fn test_delete_table_data_success(#[future] populated_test_context: FormTestContext) {
    let mut context = populated_test_context.await;
    skip_if_backend_unavailable!();

    // First create a record
    let test_data = context.create_test_form_data();
    let post_result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data,
    ).await;

    if let Ok(post_response) = post_result {
        let created_id = post_response.inserted_id;

        let delete_result = context.client.delete_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            created_id,
        ).await;

        match delete_result {
            Ok(response) => {
                assert!(response.success, "DELETE operation should succeed");
                println!("DELETE successful for ID {}", created_id);
            }
            Err(e) => panic!("DELETE request failed unexpectedly: {}", e),
        }
    } else {
        println!("Could not create test record, skipping DELETE test");
    }
}

#[rstest]
#[tokio::test]
async fn test_delete_table_data_nonexistent_id(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let nonexistent_id = 99999;
    let result = context.client.delete_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        nonexistent_id,
    ).await;

    // DELETE should succeed even for nonexistent IDs (idempotent operation)
    assert!(result.is_ok(), "DELETE should not fail for nonexistent ID");
    let response = result.unwrap();
    assert!(response.success, "DELETE should report success even for nonexistent ID");
}

// ========================================================================
// ERROR HANDLING AND VALIDATION TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_invalid_profile_and_table_errors(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let bogus_profile = "profile_does_not_exist".to_string();
    let bogus_table = "table_does_not_exist".to_string();

    let result = context.client.get_table_data_count(bogus_profile, bogus_table).await;

    assert!(result.is_err(), "Expected error for non-existent profile/table");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::NotFound, "Expected NotFound for non-existent profile");
    }
}

#[rstest]
#[tokio::test]
async fn test_invalid_column_validation(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let invalid_data = context.create_invalid_form_data();

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        invalid_data,
    ).await;

    assert!(result.is_err(), "Expected error for undefined column");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::InvalidArgument);
        assert!(status.message().contains("Invalid column") ||
                status.message().contains("nonexistent"));
    }
}

#[rstest]
#[tokio::test]
async fn test_data_type_validation(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let type_mismatch_data = context.create_type_mismatch_data();

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        type_mismatch_data,
    ).await;

    assert!(result.is_err(), "Expected error for wrong data type");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::InvalidArgument);
    }
}

#[rstest]
#[tokio::test]
async fn test_empty_data_validation(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let empty_data = HashMap::new();

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        empty_data,
    ).await;

    assert!(result.is_err(), "Expected error for empty data");
    if let Some(status) = result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::InvalidArgument);
    }
}

// ========================================================================
// SOFT DELETE BEHAVIOR TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_soft_delete_behavior_comprehensive(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    // 1. Create a record
    let test_data = context.create_test_form_data();
    let post_result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data,
    ).await;

    if let Ok(post_response) = post_result {
        let record_id = post_response.inserted_id;
        println!("Created record with ID {}", record_id);

        // 2. Verify count before deletion
        let count_before = context.client.get_table_data_count(
            context.profile_name.clone(),
            context.table_name.clone()
        ).await.unwrap_or(0);
        assert!(count_before >= 1, "Count should be at least 1 after creation");

        // 3. Soft-delete the record
        let delete_result = context.client.delete_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            record_id,
        ).await;

        assert!(delete_result.is_ok(), "Delete operation should succeed");
        println!("Soft-deleted record {}", record_id);

        // 4. Verify count decreased after deletion
        let count_after = context.client.get_table_data_count(
            context.profile_name.clone(),
            context.table_name.clone()
        ).await.unwrap_or(0);
        assert_eq!(count_after, count_before - 1, "Count should decrease by 1 after soft delete");

        // 5. Try to GET the soft-deleted record
        let get_result = context.client.get_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            record_id,
        ).await;

        assert!(get_result.is_err(), "Should not be able to GET a soft-deleted record");
        if let Some(status) = get_result.unwrap_err().downcast_ref::<Status>() {
            assert_eq!(status.code(), tonic::Code::NotFound);
        }
        println!("Correctly failed to GET soft-deleted record");
    } else {
        println!("Could not create test record for soft delete test");
    }
}

// ========================================================================
// POSITIONAL RETRIEVAL TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_positional_retrieval_comprehensive(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    // 1. Create multiple records
    let test_names = ["Alice Corp", "Bob Industries", "Charlie Ltd"];
    let mut created_ids = Vec::new();

    for (i, name) in test_names.iter().enumerate() {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value(name));
        data.insert("kz".to_string(), create_string_value(&format!("KZ{}", i + 1)));

        if let Ok(response) = context.client.post_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            data,
        ).await {
            created_ids.push(response.inserted_id);
        }
    }

    if created_ids.len() < 3 {
        println!("Could not create enough test records for positional test");
        return;
    }

    println!("Created {} records with IDs: {:?}", created_ids.len(), created_ids);

    // 2. Test valid positional retrieval
    for i in 0..3 {
        let position = (i + 1) as i32;
        let result = context.client.get_table_data_by_position(
            context.profile_name.clone(),
            context.table_name.clone(),
            position,
        ).await;

        match result {
            Ok(response) => {
                assert!(!response.data.is_empty(), "Position {} should return data", position);
                if let Some(firma_value) = response.data.get("firma") {
                    assert!(test_names.contains(&firma_value.as_str()),
                           "Returned firma '{}' should be one of our test names", firma_value);
                }
                println!("Successfully retrieved record at position {}", position);
            }
            Err(e) => {
                println!("Failed to get record at position {}: {}", position, e);
            }
        }
    }

    // 3. Test out-of-bounds position
    let oob_position = 100;
    let result_oob = context.client.get_table_data_by_position(
        context.profile_name.clone(),
        context.table_name.clone(),
        oob_position,
    ).await;

    assert!(result_oob.is_err(), "Should fail for out-of-bounds position");
    if let Some(status) = result_oob.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::NotFound);
    }

    // 4. Test invalid position (≤ 0)
    let invalid_positions = [0, -1, -5];
    for invalid_pos in invalid_positions {
        let result_invalid = context.client.get_table_data_by_position(
            context.profile_name.clone(),
            context.table_name.clone(),
            invalid_pos,
        ).await;

        assert!(result_invalid.is_err(), "Should fail for invalid position {}", invalid_pos);
        if let Some(status) = result_invalid.unwrap_err().downcast_ref::<Status>() {
            assert_eq!(status.code(), tonic::Code::InvalidArgument);
        }
    }
}

// ========================================================================
// WORKFLOW AND INTEGRATION TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_complete_crud_workflow(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let test_data = context.create_test_form_data();

    // 1. CREATE - Post data
    let post_result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data.clone(),
    ).await;

    let created_id = match post_result {
        Ok(response) => {
            assert!(response.success, "POST should succeed");
            println!("Workflow: Created record with ID {}", response.inserted_id);
            response.inserted_id
        }
        Err(e) => {
            if let Some(status) = e.downcast_ref::<Status>() {
                if status.code() == tonic::Code::Unavailable {
                    println!("Workflow test skipped - backend not available");
                    return;
                }
            }
            panic!("Workflow POST failed unexpectedly: {}", e);
        }
    };

    // 2. READ - Get the created data
    let get_result = context.client.get_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        created_id,
    ).await;

    let get_response = get_result.expect("Workflow GET should succeed");
    if let Some(firma_value) = get_response.data.get("firma") {
        assert_eq!(firma_value, "Test Company Ltd", "Retrieved data should match created data");
    }
    println!("Workflow: Verified created data");

    // 3. UPDATE - Modify the data
    let mut update_data = HashMap::new();
    update_data.insert("firma".to_string(), create_string_value("Updated in Workflow"));
    update_data.insert("telefon".to_string(), create_string_value("+421999888777"));

    let put_result = context.client.put_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        created_id,
        update_data,
    ).await;

    let put_response = put_result.expect("Workflow PUT should succeed");
    assert!(put_response.success, "PUT should succeed");
    assert_eq!(put_response.updated_id, created_id, "PUT should return correct ID");
    println!("Workflow: Updated record");

    // 4. VERIFY UPDATE - Get updated data
    let get_updated_result = context.client.get_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        created_id,
    ).await;

    let get_updated_response = get_updated_result.expect("Workflow GET after update should succeed");
    if let Some(firma_value) = get_updated_response.data.get("firma") {
        assert_eq!(firma_value, "Updated in Workflow", "Data should be updated");
    }
    println!("Workflow: Verified updated data");

    // 5. DELETE - Remove the data
    let delete_result = context.client.delete_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        created_id,
    ).await;

    let delete_response = delete_result.expect("Workflow DELETE should succeed");
    assert!(delete_response.success, "DELETE should succeed");
    println!("Workflow: Deleted record");

    // 6. VERIFY DELETE - Ensure data is gone
    let get_deleted_result = context.client.get_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        created_id,
    ).await;

    assert!(get_deleted_result.is_err(), "Should not be able to GET deleted record");
    if let Some(status) = get_deleted_result.unwrap_err().downcast_ref::<Status>() {
        assert_eq!(status.code(), tonic::Code::NotFound);
    }
    println!("Workflow: Verified record deletion");

    println!("Complete CRUD workflow test successful for ID {}", created_id);
}

// ========================================================================
// FORM STATE INTEGRATION TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_form_state_integration(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    // Create a form state
    let mut form_state = FormState::new(
        context.profile_name.clone(),
        context.table_name.clone(),
        vec![], // columns would be populated in real use
    );

    // Test count update
    let count_result = context.client.get_table_data_count(
        context.profile_name.clone(),
        context.table_name.clone(),
    ).await;

    if let Ok(count) = count_result {
        form_state.total_count = count;
        assert_eq!(form_state.total_count, count, "Form state count should match backend");
        println!("Form state updated with count: {}", form_state.total_count);
    }

    // Create a test record for form state testing
    let test_data = context.create_test_form_data();
    if let Ok(post_response) = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        test_data,
    ).await {
        let created_id = post_response.inserted_id;

        // Test form state update from backend response
        if let Ok(get_response) = context.client.get_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            created_id,
        ).await {
            form_state.update_from_response(&get_response.data, created_id as u64);
            assert_eq!(form_state.current_position, created_id as u64, "Form state position should match");
            assert!(!form_state.has_unsaved_changes(), "Form state should not have unsaved changes after update");
            println!("Form state successfully updated from backend data");
        }
    } else {
        println!("Could not create test record for form state test");
    }
}

// ========================================================================
// CONCURRENT OPERATIONS TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_concurrent_post_operations(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    // Create multiple concurrent POST operations using tokio::spawn
    let mut handles = Vec::new();

    for i in 0..5 {
        let context_clone = context.clone();
        let handle = tokio::spawn(async move {
            let mut data = context_clone.create_test_form_data();
            data.insert("firma".to_string(), create_string_value(&format!("Concurrent Company {}", i)));
            data.insert("kz".to_string(), create_string_value(&format!("CONC{}", i)));

            let mut client = context_clone.client;
            client.post_table_data(
                context_clone.profile_name.clone(),
                context_clone.table_name.clone(),
                data,
            ).await
        });
        handles.push(handle);
    }

    // Wait for all tasks to complete
    let mut success_count = 0;
    for (i, handle) in handles.into_iter().enumerate() {
        match handle.await {
            Ok(Ok(response)) => {
                assert!(response.success, "Concurrent POST {} should succeed", i);
                success_count += 1;
            }
            Ok(Err(_)) => {
                println!("Concurrent POST {} failed (may be expected if backend issues)", i);
            }
            Err(e) => {
                println!("Concurrent task {} panicked: {}", i, e);
            }
        }
    }

    println!("Concurrent operations: {}/{} succeeded", success_count, 5);
    assert!(success_count > 0, "At least some concurrent operations should succeed");
}

// ========================================================================
// PERFORMANCE AND STRESS TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_rapid_sequential_operations(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let start_time = std::time::Instant::now();
    let operation_count = 10;
    let mut successful_operations = 0;

    for i in 0..operation_count {
        let mut data = context.create_test_form_data();
        data.insert("firma".to_string(), create_string_value(&format!("Rapid Company {}", i)));
        data.insert("kz".to_string(), create_string_value(&format!("RAP{}", i)));

        if let Ok(response) = context.client.post_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            data,
        ).await {
            assert!(response.success, "Rapid operation {} should succeed", i);
            successful_operations += 1;
        }
    }

    let duration = start_time.elapsed();
    println!("{} rapid operations took: {:?}", operation_count, duration);
    println!("Success rate: {}/{}", successful_operations, operation_count);

    assert!(successful_operations > 0, "At least some rapid operations should succeed");
    assert!(duration.as_secs() < 30, "Rapid operations should complete in reasonable time");
}

// ========================================================================
// CONNECTION AND CLIENT TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_grpc_client_connection() {
    if std::env::var("SKIP_BACKEND_TESTS").is_ok() {
        println!("Connection test skipped due to SKIP_BACKEND_TESTS");
        return;
    }

    let client_result = GrpcClient::new().await;
    match client_result {
        Ok(_) => println!("gRPC client connection test passed"),
        Err(e) => {
            println!("gRPC client connection failed (expected if backend not running): {}", e);
            // Don't panic - this is expected when backend is not available
        }
    }
}

#[rstest]
#[tokio::test]
async fn test_client_timeout_handling(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    // Test that operations complete within reasonable timeouts
    let timeout_duration = Duration::from_secs(10);

    let count_result = timeout(
        timeout_duration,
        context.client.get_table_data_count(
            context.profile_name.clone(),
            context.table_name.clone(),
        )
    ).await;

    match count_result {
        Ok(Ok(count)) => {
            println!("Count operation completed within timeout: {}", count);
        }
        Ok(Err(e)) => {
            println!("Count operation failed: {}", e);
        }
        Err(_) => {
            panic!("Count operation timed out after {:?}", timeout_duration);
        }
    }
}

// ========================================================================
// DATA EDGE CASES TESTS
// ========================================================================

#[rstest]
#[tokio::test]
async fn test_special_characters_and_unicode(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let special_strings = vec![
        "José María González",
        "Москва",
        "北京市",
        "🚀 Tech Company 🌟",
        "Quote\"Test'Apostrophe",
        "Price: $1,000.50 (50% off!)",
    ];

    for (i, test_string) in special_strings.iter().enumerate() {
        let mut data = HashMap::new();
        data.insert("firma".to_string(), create_string_value(test_string));
        data.insert("kz".to_string(), create_string_value(&format!("UNI{}", i)));

        let result = context.client.post_table_data(
            context.profile_name.clone(),
            context.table_name.clone(),
            data,
        ).await;

        if let Ok(response) = result {
            assert!(response.success, "Should handle special characters: '{}'", test_string);
            println!("Successfully handled special string: '{}'", test_string);
        } else {
            println!("Failed to handle special string: '{}' (may be expected)", test_string);
        }
    }
}

#[rstest]
#[tokio::test]
async fn test_null_and_empty_values(#[future] form_test_context: FormTestContext) {
    let mut context = form_test_context.await;
    skip_if_backend_unavailable!();

    let mut data = HashMap::new();
    data.insert("firma".to_string(), create_string_value("Null Test Company"));
    data.insert("telefon".to_string(), create_null_value());
    data.insert("email".to_string(), create_string_value(""));
    data.insert("ulica".to_string(), create_string_value("   ")); // Whitespace only

    let result = context.client.post_table_data(
        context.profile_name.clone(),
        context.table_name.clone(),
        data,
    ).await;

    if let Ok(response) = result {
        assert!(response.success, "Should handle null and empty values");
        println!("Successfully handled null and empty values");
    } else {
        println!("Failed to handle null and empty values (may be expected based on validation)");
    }
}

include!("form_request_tests2.rs");
include!("form_request_tests3.rs");
