//! Verifica que un párrafo largo, dentro de un bloque angosto, reserva el
//! alto de **varias líneas** (no se aplasta en una). Es el regresor del bug
//! "textos aplastados" de puriy: sin medición con parley, taffy le daba a la
//! hoja de texto una sola línea de alto y las líneas envueltas se solapaban.

use llimphi_compositor::{measure_text_node, mount, View};
use llimphi_layout::taffy::prelude::*;
use llimphi_layout::taffy::Size as TSize;
use llimphi_layout::LayoutTree;

#[derive(Clone)]
enum Msg {}

#[test]
fn parrafo_largo_reserva_varias_lineas() {
    // Bloque de 200px de ancho con un párrafo que claramente excede una línea.
    let texto = "Lorem ipsum dolor sit amet consectetur adipiscing elit sed do \
                 eiusmod tempor incididunt ut labore et dolore magna aliqua ut \
                 enim ad minim veniam quis nostrud exercitation ullamco laboris.";
    let block: View<Msg> = View::new(Style {
        size: TSize { width: length(200.0_f32), height: auto() },
        flex_direction: FlexDirection::Row,
        flex_wrap: FlexWrap::Wrap,
        ..Default::default()
    })
    .children(vec![View::new(Style {
        size: TSize { width: auto(), height: auto() },
        flex_shrink: 1.0,
        ..Default::default()
    })
    .text_aligned(texto, 16.0_f32, vello::peniko::Color::BLACK, llimphi_text::Alignment::Start)]);

    let mut layout = LayoutTree::new();
    let mounted = mount(&mut layout, block);
    let mut ts = llimphi_text::Typesetter::new();
    let tmap = &mounted.text_measures;
    assert_eq!(tmap.len(), 1, "debería haber exactamente una hoja de texto");

    let computed = layout
        .compute_with_measure(mounted.root, (800.0, 600.0), |nid, known, avail| match tmap.get(&nid)
        {
            Some(tm) => measure_text_node(&mut ts, tm, known, avail),
            None => TSize::ZERO,
        })
        .expect("layout");

    // El nodo de texto es el segundo en orden DFS (root, luego la hoja).
    let leaf_id = mounted.nodes[1].id;
    let rect = computed.get(leaf_id).expect("rect de la hoja");
    // A 16px y ~1.2 de interlínea, una línea ≈ 19px. Con ~150px de texto en
    // 200px de ancho deberían ser >= 4 líneas → bastante más de una.
    assert!(
        rect.h > 40.0,
        "el párrafo se aplastó: alto={} (esperaba varias líneas)",
        rect.h
    );
    assert!(rect.w <= 200.0 + 1.0, "no debería exceder el ancho del bloque");
}

#[test]
fn line_height_mayor_reserva_mas_alto() {
    let texto = "una línea de texto que envuelve en dos o tres renglones según \
                 el ancho disponible para el bloque contenedor angosto";
    let medir = |lh: f32| -> f32 {
        let mut ts = llimphi_text::Typesetter::new();
        let tm = llimphi_compositor::TextMeasure {
            content: texto.to_string(),
            size_px: 16.0,
            alignment: llimphi_text::Alignment::Start,
            italic: false,
            font_family: None,
            line_height: lh,
        };
        let known = TSize { width: Some(180.0_f32), height: None };
        let avail = TSize {
            width: AvailableSpace::Definite(180.0),
            height: AvailableSpace::MaxContent,
        };
        measure_text_node(&mut ts, &tm, known, avail).height
    };
    let compacto = medir(1.0);
    let comodo = medir(2.0);
    assert!(
        comodo > compacto * 1.5,
        "line-height: 2 debería reservar bastante más alto que 1.0 (got {compacto} vs {comodo})"
    );
}
