use std::sync::{Arc, Mutex};
use pdfmake_rust::{Document, DocumentNode, PdfMake, RenderOptions};

#[test]
fn callback_invoked_with_zero_and_one() {
    let doc = Document::builder()
        .content(DocumentNode::text("Hello"))
        .build();

    let values: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));
    let values_clone = Arc::clone(&values);

    let options = RenderOptions::default()
        .progress_callback(Arc::new(move |v| {
            values_clone.lock().unwrap().push(v);
        }));

    PdfMake::new().render_with_options(&doc, &options).unwrap();

    let vals = values.lock().unwrap();
    assert!(!vals.is_empty(), "callback should have been invoked");
    assert_eq!(vals[0], 0.0, "first callback should be 0.0");
    assert_eq!(*vals.last().unwrap(), 1.0, "last callback should be 1.0");
}

#[test]
fn callback_invoked_per_page() {
    let doc = Document::builder()
        .content(DocumentNode::text("Page content"))
        .build();

    let values: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));
    let values_clone = Arc::clone(&values);

    let options = RenderOptions::default()
        .progress_callback(Arc::new(move |v| {
            values_clone.lock().unwrap().push(v);
        }));

    PdfMake::new().render_with_options(&doc, &options).unwrap();

    let vals = values.lock().unwrap();
    // For a single-page document: [0.0, 1.0, 1.0]
    // 0.0 at start, 1.0 after page 1/1, 1.0 at end
    assert!(vals.len() >= 3, "expected at least 3 callbacks, got {}", vals.len());
    // The per-page callback for page 1 of 1 should be 1.0
    assert_eq!(vals[1], 1.0, "page callback should be 1.0 for single page");
}

#[test]
fn no_callback_when_none() {
    let doc = Document::builder()
        .content(DocumentNode::text("Hello"))
        .build();

    let options = RenderOptions::default();
    let result = PdfMake::new().render_with_options(&doc, &options);
    assert!(result.is_ok(), "render should succeed without callback");
}

#[test]
fn callback_values_are_monotonically_non_decreasing() {
    let doc = Document::builder()
        .content(DocumentNode::text("Hello"))
        .build();

    let values: Arc<Mutex<Vec<f32>>> = Arc::new(Mutex::new(Vec::new()));
    let values_clone = Arc::clone(&values);

    let options = RenderOptions::default()
        .progress_callback(Arc::new(move |v| {
            values_clone.lock().unwrap().push(v);
        }));

    PdfMake::new().render_with_options(&doc, &options).unwrap();

    let vals = values.lock().unwrap();
    for window in vals.windows(2) {
        assert!(window[1] >= window[0], "progress should not decrease: {} -> {}", window[0], window[1]);
    }
}
