#![cfg(feature = "qr")]

use pdfmake_rust::{Document, DocumentNode, FontRegistry, QrNode};

#[test]
fn document_accepts_qr_node_with_fit_size() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("hello").fit(96.0)))
        .build();

    match &document.content[0] {
        DocumentNode::Qr(qr) => {
            assert_eq!(qr.text, "hello");
            assert_eq!(qr.fit, Some(96.0));
        }
        other => panic!("expected qr node, got {other:?}"),
    }
}

use pdfmake_rust::{normalize_document, Alignment};

#[test]
fn normalize_preserves_qr_block_fields() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("hello").fit(72.0).alignment(Alignment::Right)))
        .build();

    let normalized = normalize_document(&document).unwrap();
    match &normalized.blocks[0] {
        pdfmake_rust::NormalizedBlock::Qr(qr) => {
            assert_eq!(qr.text, "hello");
            assert_eq!(qr.fit, Some(72.0));
            assert_eq!(qr.alignment, Alignment::Right);
        }
        other => panic!("expected normalized qr, got {other:?}"),
    }
}

use pdfmake_rust::{measure_document, PdfMakeError};

#[test]
fn measure_qr_generates_square_vector_size() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("hello").fit(84.0)))
        .build();

    let normalized = normalize_document(&document).unwrap();
    let measured = measure_document(&normalized, &FontRegistry::empty()).unwrap();

    match &measured.blocks[0] {
        pdfmake_rust::MeasuredBlock::Qr(qr) => {
            assert_eq!(qr.width, 84.0);
            assert_eq!(qr.height, 84.0);
            assert!(qr.modules > 0);
            assert!(!qr.dark_modules.is_empty());
        }
        other => panic!("expected measured qr, got {other:?}"),
    }
}

#[test]
fn measure_qr_rejects_empty_text() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("")))
        .build();

    let normalized = normalize_document(&document).unwrap();
    let error = measure_document(&normalized, &FontRegistry::empty()).unwrap_err();
    match error {
        PdfMakeError::InvalidQrContent => {}
        other => panic!("expected invalid qr content, got {other:?}"),
    }
}

use pdfmake_rust::{layout_document, PdfMake};

#[test]
fn layout_qr_creates_qr_item() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("hello").fit(84.0)))
        .build();
    let normalized = normalize_document(&document).unwrap();
    let measured = measure_document(&normalized, &FontRegistry::empty()).unwrap();
    let layout = layout_document(&measured).unwrap();

    match &layout.pages[0].items[0] {
        pdfmake_rust::LayoutItem::Qr(qr) => {
            assert_eq!(qr.width, 84.0);
            assert_eq!(qr.height, 84.0);
            assert!(!qr.dark_modules.is_empty());
        }
        other => panic!("expected layout qr, got {other:?}"),
    }
}

#[test]
fn render_qr_document_outputs_vector_rectangles() {
    let document = Document::builder()
        .content(DocumentNode::qr(QrNode::new("hello").fit(72.0)))
        .build();

    let pdf = PdfMake::new().render(&document).unwrap();
    let text = String::from_utf8_lossy(&pdf);

    assert!(text.contains("/Filter /FlateDecode"));
    assert!(text.contains("stream\n"));
    assert!(text.contains("endstream"));
    assert!(!text.contains("/Subtype /Image"));
}

#[test]
fn qr_node_accepts_colors_and_ecc() {
    let qr = QrNode::new("test")
        .foreground("#333333")
        .background("#FFFFFF")
        .ecc_level("H");
    assert_eq!(qr.foreground, Some("#333333".into()));
    assert_eq!(qr.background, Some("#FFFFFF".into()));
    assert_eq!(qr.ecc_level, Some("H".into()));
}

#[test]
fn qr_with_colors_renders() {
    let doc = Document::builder()
        .content(DocumentNode::qr(
            QrNode::new("https://example.com")
                .fit(80.0)
                .foreground("#2C3E50")
                .background("#ECF0F1")
        ))
        .build();
    let pdf = PdfMake::new().render(&doc).unwrap();
    assert!(pdf.len() > 100);
}