use pdfmake_rust::*;

#[test]
fn test_toc_node_creation() {
    let toc = TocNode::new()
        .id("main-toc")
        .title(DocumentNode::text("Table of Contents"));

    assert_eq!(toc.id, Some("main-toc".to_string()));
    assert!(toc.title.is_some());
}

#[test]
fn test_text_node_with_toc_item() {
    let text_node = TextNode::new("Chapter 1").toc_item("main-toc");
    assert_eq!(text_node.toc_item, Some("main-toc".to_string()));
}

#[test]
fn test_toc_normalization() {
    let doc = Document::builder()
        .content(DocumentNode::stack(vec![
            DocumentNode::toc(
                TocNode::new()
                    .id("main-toc")
                    .title(DocumentNode::text("Table of Contents"))
            ),
            DocumentNode::Text(TextNode::new("Chapter 1").toc_item("main-toc")),
            DocumentNode::Text(TextNode::new("Chapter 2").toc_item("main-toc")),
        ]))
        .build();

    let normalized = normalize_document(&doc).unwrap();

    // Check that toc_items registry is populated
    assert!(normalized.toc_items.contains_key("main-toc"));
    let entries = normalized.toc_items.get("main-toc").unwrap();
    assert_eq!(entries.len(), 2);
    assert_eq!(entries[0].text, "Chapter 1");
    assert_eq!(entries[1].text, "Chapter 2");
}

#[test]
fn test_toc_measurement() {
    let doc = Document::builder()
        .content(DocumentNode::stack(vec![
            DocumentNode::toc(
                TocNode::new()
                    .id("main-toc")
                    .title(DocumentNode::text("Table of Contents"))
            ),
            DocumentNode::Text(TextNode::new("Chapter 1").toc_item("main-toc")),
        ]))
        .build();

    let fonts = FontRegistry::load(&doc.fonts).unwrap();
    let normalized = normalize_document(&doc).unwrap();
    let measured = measure_document(&normalized, &fonts).unwrap();

    // Find the Toc block
    let toc_block = measured.blocks.iter().find(|b| matches!(b, MeasuredBlock::Toc(_)));
    assert!(toc_block.is_some(), "Should have a MeasuredBlock::Toc");
}

#[test]
fn test_toc_render_produces_pdf() {
    let doc = Document::builder()
        .content(DocumentNode::stack(vec![
            DocumentNode::toc(
                TocNode::new()
                    .id("main-toc")
                    .title(DocumentNode::text("Table of Contents"))
            ),
            DocumentNode::Text(TextNode::new("Chapter 1").toc_item("main-toc")),
            DocumentNode::Text(TextNode::new("Chapter 2").toc_item("main-toc")),
        ]))
        .build();

    let result = PdfMake::new().render(&doc);
    assert!(result.is_ok(), "PDF rendering should succeed");

    let pdf_bytes = result.unwrap();
    assert!(!pdf_bytes.is_empty(), "PDF should not be empty");
    assert!(pdf_bytes.starts_with(b"%PDF"), "Should be valid PDF");
}

#[test]
fn test_toc_in_table_cells() {
    let doc = Document::builder()
        .content(DocumentNode::stack(vec![
            DocumentNode::toc(
                TocNode::new()
                    .id("main-toc")
                    .title(DocumentNode::text("Table of Contents"))
            ),
            DocumentNode::table(
                TableNode::new(vec![
                    vec![TableCell::node(
                        DocumentNode::Text(TextNode::new("Table Chapter").toc_item("main-toc"))
                    )]
                ])
            ),
        ]))
        .build();

    let normalized = normalize_document(&doc).unwrap();

    // Check that toc_item inside table cell is collected
    assert!(normalized.toc_items.contains_key("main-toc"));
    let entries = normalized.toc_items.get("main-toc").unwrap();
    assert_eq!(entries.len(), 1);
    assert_eq!(entries[0].text, "Table Chapter");
}

#[test]
fn test_toc_in_list_items() {
    let doc = Document::builder()
        .content(DocumentNode::stack(vec![
            DocumentNode::toc(
                TocNode::new()
                    .id("main-toc")
                    .title(DocumentNode::text("Table of Contents"))
            ),
            DocumentNode::list(ListNode::unordered(vec![
                DocumentNode::Text(TextNode::new("List Item 1").toc_item("main-toc")),
                DocumentNode::text("List Item 2"),
            ])),
        ]))
        .build();

    let normalized = normalize_document(&doc).unwrap();

    // Check that toc_item inside list is collected
    assert!(normalized.toc_items.contains_key("main-toc"));
    let entries = normalized.toc_items.get("main-toc").unwrap();
    assert_eq!(entries.len(), 1);
    assert_eq!(entries[0].text, "List Item 1");
}
