// client/tests/form_tests.rs
use rstest::{fixture, rstest};
use std::collections::HashMap;
use client::state::pages::form::{FormState, FieldDefinition};
use canvas::state::CanvasState
use client::state::pages::canvas_state::CanvasState;

#[fixture]
fn test_form_state() -> FormState {
    let fields = vec![
        FieldDefinition {
            display_name: "Company".to_string(),
            data_key: "firma".to_string(),
            is_link: false,
            link_target_table: None,
        },
        FieldDefinition {
            display_name: "Phone".to_string(),
            data_key: "telefon".to_string(),
            is_link: false,
            link_target_table: None,
        },
        FieldDefinition {
            display_name: "Email".to_string(),
            data_key: "email".to_string(),
            is_link: false,
            link_target_table: None,
        },
    ];
    
    FormState::new("test_profile".to_string(), "test_table".to_string(), fields)
}

#[fixture]
fn test_form_data() -> HashMap<String, String> {
    let mut data = HashMap::new();
    data.insert("firma".to_string(), "Test Company".to_string());
    data.insert("telefon".to_string(), "+421123456789".to_string());
    data.insert("email".to_string(), "test@example.com".to_string());
    data
}

#[rstest]
fn test_form_state_creation(test_form_state: FormState) {
    assert_eq!(test_form_state.profile_name, "test_profile");
    assert_eq!(test_form_state.table_name, "test_table");
    assert_eq!(test_form_state.fields.len(), 3);
    assert_eq!(test_form_state.current_field(), 0);
    assert!(!test_form_state.has_unsaved_changes());
}

#[rstest]
fn test_form_field_navigation(mut test_form_state: FormState) {
    // Test initial field
    assert_eq!(test_form_state.current_field(), 0);
    
    // Test navigation to next field
    test_form_state.set_current_field(1);
    assert_eq!(test_form_state.current_field(), 1);
    
    // Test navigation to last field
    test_form_state.set_current_field(2);
    assert_eq!(test_form_state.current_field(), 2);
    
    // Test invalid field (should not crash)
    test_form_state.set_current_field(999);
    assert_eq!(test_form_state.current_field(), 2); // Should stay at valid field
}

#[rstest]
fn test_form_data_entry(mut test_form_state: FormState) {
    // Test entering data in first field
    *test_form_state.get_current_input_mut() = "Test Company".to_string();
    test_form_state.set_has_unsaved_changes(true);
    
    assert_eq!(test_form_state.get_current_input(), "Test Company");
    assert!(test_form_state.has_unsaved_changes());
}

#[rstest]
fn test_form_field_switching_with_data(mut test_form_state: FormState) {
    // Enter data in first field
    *test_form_state.get_current_input_mut() = "Company Name".to_string();
    
    // Switch to second field
    test_form_state.set_current_field(1);
    *test_form_state.get_current_input_mut() = "+421123456789".to_string();
    
    // Switch back to first field
    test_form_state.set_current_field(0);
    assert_eq!(test_form_state.get_current_input(), "Company Name");
    
    // Switch to second field again
    test_form_state.set_current_field(1);
    assert_eq!(test_form_state.get_current_input(), "+421123456789");
}

#[rstest]
fn test_form_reset_functionality(mut test_form_state: FormState) {
    // Add some data
    test_form_state.set_current_field(0);
    *test_form_state.get_current_input_mut() = "Test Company".to_string();
    test_form_state.set_current_field(1);
    *test_form_state.get_current_input_mut() = "+421123456789".to_string();
    test_form_state.set_has_unsaved_changes(true);
    test_form_state.id = 123;
    test_form_state.current_position = 5;
    
    // Reset the form
    test_form_state.reset_to_empty();
    
    // Verify reset
    assert_eq!(test_form_state.id, 0);
    assert!(!test_form_state.has_unsaved_changes());
    assert_eq!(test_form_state.current_field(), 0);
    
    // Check all fields are empty
    for i in 0..test_form_state.fields.len() {
        test_form_state.set_current_field(i);
        assert!(test_form_state.get_current_input().is_empty());
    }
}

#[rstest]
fn test_form_update_from_response(mut test_form_state: FormState, test_form_data: HashMap<String, String>) {
    let position = 3;
    
    // Update form with response data
    test_form_state.update_from_response(&test_form_data, position);
    
    // Verify data was loaded
    assert_eq!(test_form_state.current_position, position);
    assert!(!test_form_state.has_unsaved_changes());
    assert_eq!(test_form_state.current_field(), 0);
    
    // Check field values
    test_form_state.set_current_field(0);
    assert_eq!(test_form_state.get_current_input(), "Test Company");
    
    test_form_state.set_current_field(1);
    assert_eq!(test_form_state.get_current_input(), "+421123456789");
    
    test_form_state.set_current_field(2);
    assert_eq!(test_form_state.get_current_input(), "test@example.com");
}

#[rstest]
fn test_form_cursor_position(mut test_form_state: FormState) {
    // Test initial cursor position
    assert_eq!(test_form_state.current_cursor_pos(), 0);
    
    // Add some text
    *test_form_state.get_current_input_mut() = "Test Company".to_string();
    
    // Test cursor positioning
    test_form_state.set_current_cursor_pos(5);
    assert_eq!(test_form_state.current_cursor_pos(), 5);
    
    // Test cursor bounds
    test_form_state.set_current_cursor_pos(999);
    // Should be clamped to text length
    assert!(test_form_state.current_cursor_pos() <= "Test Company".len());
}

#[rstest]
fn test_form_field_display_names(test_form_state: FormState) {
    let field_names = test_form_state.fields();
    
    assert_eq!(field_names.len(), 3);
    assert_eq!(field_names[0], "Company");
    assert_eq!(field_names[1], "Phone");
    assert_eq!(field_names[2], "Email");
}

#[rstest]
fn test_form_inputs_vector(mut test_form_state: FormState) {
    // Add data to fields
    test_form_state.set_current_field(0);
    *test_form_state.get_current_input_mut() = "Company A".to_string();
    
    test_form_state.set_current_field(1);
    *test_form_state.get_current_input_mut() = "123456789".to_string();
    
    test_form_state.set_current_field(2);
    *test_form_state.get_current_input_mut() = "test@test.com".to_string();
    
    // Get inputs vector
    let inputs = test_form_state.inputs();
    
    assert_eq!(inputs.len(), 3);
    assert_eq!(inputs[0], "Company A");
    assert_eq!(inputs[1], "123456789");
    assert_eq!(inputs[2], "test@test.com");
}

#[rstest]
fn test_form_position_management(mut test_form_state: FormState) {
    // Test initial position
    assert_eq!(test_form_state.current_position, 1);
    assert_eq!(test_form_state.total_count, 0);
    
    // Set some values
    test_form_state.total_count = 10;
    test_form_state.current_position = 5;
    
    assert_eq!(test_form_state.current_position, 5);
    assert_eq!(test_form_state.total_count, 10);
    
    // Test reset affects position
    test_form_state.reset_to_empty();
    assert_eq!(test_form_state.current_position, 11); // total_count + 1
}

#[rstest]
fn test_form_autocomplete_state(mut test_form_state: FormState) {
    // Test initial autocomplete state
    assert!(!test_form_state.autocomplete_active);
    assert!(test_form_state.autocomplete_suggestions.is_empty());
    assert!(test_form_state.selected_suggestion_index.is_none());
    
    // Test deactivating autocomplete
    test_form_state.autocomplete_active = true;
    test_form_state.deactivate_autocomplete();
    
    assert!(!test_form_state.autocomplete_active);
    assert!(test_form_state.autocomplete_suggestions.is_empty());
    assert!(test_form_state.selected_suggestion_index.is_none());
    assert!(!test_form_state.autocomplete_loading);
}

#[rstest]
fn test_form_empty_data_handling(mut test_form_state: FormState) {
    let empty_data = HashMap::new();
    
    // Update with empty data
    test_form_state.update_from_response(&empty_data, 1);
    
    // All fields should be empty
    for i in 0..test_form_state.fields.len() {
        test_form_state.set_current_field(i);
        assert!(test_form_state.get_current_input().is_empty());
    }
}

#[rstest]
fn test_form_partial_data_handling(mut test_form_state: FormState) {
    let mut partial_data = HashMap::new();
    partial_data.insert("firma".to_string(), "Partial Company".to_string());
    // Intentionally missing telefon and email
    
    test_form_state.update_from_response(&partial_data, 1);
    
    // First field should have data
    test_form_state.set_current_field(0);
    assert_eq!(test_form_state.get_current_input(), "Partial Company");
    
    // Other fields should be empty
    test_form_state.set_current_field(1);
    assert!(test_form_state.get_current_input().is_empty());
    
    test_form_state.set_current_field(2);
    assert!(test_form_state.get_current_input().is_empty());
}
