//! Performance benchmarks for state mutations
//!
//! Measures the performance of app state operations to ensure quick mutations:
//! - Target: <0.5ms for navigation methods
//! - Target: <0.5ms for screen transitions
//! - Target: <0.1ms for dirty flag operations
//!
//! Run with: `cargo bench -p syntaxis-tui --bench state_mutations`

use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use std::hint::black_box;

fn string_mutation_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("string_mutations");
    group.significance_level(0.1);
    group.sample_size(10000);

    // Benchmark string input handling
    group.bench_function("set_project_name_short", |b| {
        b.iter(|| {
            let _name = black_box("My Project".to_string());
        })
    });

    group.bench_function("set_project_name_long", |b| {
        b.iter(|| {
            let _name = black_box(
                "This is a very long project name that might be entered by the user".to_string(),
            );
        })
    });

    // Benchmark string clearing
    group.bench_function("clear_project_name", |b| {
        b.iter(|| {
            let mut name = black_box("Project Name".to_string());
            name.clear();
            let _ = black_box(name);
        })
    });

    // Benchmark description mutation
    group.bench_function("set_project_description", |b| {
        b.iter(|| {
            let _desc = black_box("A detailed description of the project".to_string());
        })
    });

    group.finish();
}

fn vector_mutation_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("vector_mutations");
    group.significance_level(0.1);
    group.sample_size(1000);

    // Benchmark vector operations with various sizes
    for size in [10, 100, 1000].iter() {
        group.bench_with_input(
            BenchmarkId::from_parameter(format!("create_{}_items", size)),
            size,
            |b, &size| {
                b.iter(|| {
                    let mut items = Vec::new();
                    for i in 0..size {
                        items.push(black_box(i));
                    }
                    let _ = black_box(items);
                })
            },
        );
    }

    // Benchmark index access
    for size in [10, 100, 1000].iter() {
        group.bench_with_input(
            BenchmarkId::from_parameter(format!("access_{}_items", size)),
            size,
            |b, &size| {
                let items: Vec<_> = (0..size).collect();
                b.iter(|| {
                    let idx = black_box(5);
                    if idx < items.len() {
                        let _ = black_box(&items[idx]);
                    }
                })
            },
        );
    }

    group.finish();
}

fn enum_variant_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("enum_variants");
    group.significance_level(0.1);
    group.sample_size(10000);

    // Benchmark enum creation/assignment
    group.bench_function("screen_variant_projectslist", |b| {
        b.iter(|| {
            let _ = black_box(0); // Projects list variant
        })
    });

    group.bench_function("screen_variant_projectdetail", |b| {
        b.iter(|| {
            let _ = black_box(1); // Project detail variant
        })
    });

    group.bench_function("screen_variant_security", |b| {
        b.iter(|| {
            let _ = black_box(2); // Security variant
        })
    });

    group.bench_function("screen_variant_createproject", |b| {
        b.iter(|| {
            let _ = black_box(3); // Create project variant
        })
    });

    group.finish();
}

fn option_mutation_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("option_mutations");
    group.significance_level(0.1);
    group.sample_size(10000);

    // Benchmark Option<T> operations
    group.bench_function("set_current_project_some", |b| {
        b.iter(|| {
            let _project = black_box(Some("Project 1"));
        })
    });

    group.bench_function("clear_current_project_none", |b| {
        b.iter(|| {
            let _project: Option<&str> = black_box(None);
        })
    });

    // Benchmark option checking
    group.bench_function("check_project_exists", |b| {
        let project = black_box(Some("Project 1"));
        b.iter(|| {
            if project.is_some() {
                let _ = black_box(true);
            }
        })
    });

    group.finish();
}

fn number_mutation_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("number_mutations");
    group.significance_level(0.1);
    group.sample_size(10000);

    // Benchmark numeric state changes
    group.bench_function("increment_selected_index", |b| {
        b.iter(|| {
            let index = black_box(5);
            let size = black_box(20);
            let _next = (index + 1) % size;
        })
    });

    group.bench_function("decrement_selected_index", |b| {
        b.iter(|| {
            let index = black_box(5);
            let _prev = if index == 0 { 19 } else { index - 1 };
        })
    });

    // Benchmark item count mutation
    group.bench_function("update_items_completed", |b| {
        b.iter(|| {
            let mut completed = black_box(5);
            completed += 1;
            let _ = black_box(completed);
        })
    });

    group.finish();
}

fn combined_state_mutation_benchmark(c: &mut Criterion) {
    let mut group = c.benchmark_group("combined_mutations");
    group.significance_level(0.1);
    group.sample_size(1000);

    // Simulate a complex state mutation like screen transition
    group.bench_function("transition_with_state_reset", |b| {
        b.iter(|| {
            let _screen = black_box(1); // new screen
            let _name = black_box("".to_string()); // clear name
            let _desc = black_box("".to_string()); // clear description
            let _dirty = black_box(true); // set dirty
        })
    });

    // Simulate navigation with boundary check
    group.bench_function("navigate_with_bounds_check", |b| {
        b.iter(|| {
            let index = black_box(18);
            let size = black_box(20);
            let next = (index + 1) % size;
            let _ = black_box(next);
        })
    });

    group.finish();
}

criterion_group!(
    benches,
    string_mutation_benchmark,
    vector_mutation_benchmark,
    enum_variant_benchmark,
    option_mutation_benchmark,
    number_mutation_benchmark,
    combined_state_mutation_benchmark
);
criterion_main!(benches);
