#[cfg(test)]
mod tests {
    use crate::layout::{border_side, cell_borders, filter_borders, filter_cell_borders, LayoutLine};
    use crate::model::TableStyle;

    #[test]
    fn cell_borders_generates_4_lines() {
        let borders = cell_borders(10.0, 20.0, 100.0, 50.0);
        assert_eq!(borders.len(), 4);

        assert_eq!(borders[0], LayoutLine { x1: 10.0, y1: 20.0, x2: 110.0, y2: 20.0 });
        assert_eq!(borders[1], LayoutLine { x1: 110.0, y1: 20.0, x2: 110.0, y2: 70.0 });
        assert_eq!(borders[2], LayoutLine { x1: 110.0, y1: 70.0, x2: 10.0, y2: 70.0 });
        assert_eq!(borders[3], LayoutLine { x1: 10.0, y1: 70.0, x2: 10.0, y2: 20.0 });
    }

    #[test]
    fn border_side_identifies_all_sides() {
        let (x, y, w, h) = (10.0, 20.0, 100.0, 50.0);
        let borders = cell_borders(x, y, w, h);

        assert_eq!(border_side(&borders[0], x, y, w, h), Some(0), "top");
        assert_eq!(border_side(&borders[1], x, y, w, h), Some(1), "right");
        assert_eq!(border_side(&borders[2], x, y, w, h), Some(2), "bottom");
        assert_eq!(border_side(&borders[3], x, y, w, h), Some(3), "left");
    }

    #[test]
    fn filter_cell_borders_with_table_style_light_horizontal_keeps_correct_sides() {
        let (x, y, w, h) = (0.0, 0.0, 200.0, 100.0);
        let raw = cell_borders(x, y, w, h);
        // LightHorizontalLines keeps only horizontal borders (top, bottom)
        let filtered = filter_borders(&raw, Some(TableStyle::LightHorizontalLines), None);
        assert_eq!(filtered.len(), 2, "should have top and bottom");

        // Now apply per-cell border: disable top (border[1]), keep bottom (border[3])
        let border = Some(vec![false, false, false, true]); // [left, top, right, bottom]
        let result = filter_cell_borders(&filtered, &border, x, y, w, h);
        assert_eq!(result.len(), 1, "should have only bottom");
        // Bottom border is at y + h
        assert!((result[0].y1 - (y + h)).abs() < 0.5, "remaining border should be bottom");
    }

    #[test]
    fn filter_cell_borders_with_table_style_light_vertical_keeps_correct_sides() {
        let (x, y, w, h) = (0.0, 0.0, 200.0, 100.0);
        let raw = cell_borders(x, y, w, h);
        // LightVerticalLines keeps only vertical borders (right, left)
        let filtered = filter_borders(&raw, Some(TableStyle::LightVerticalLines), None);
        assert_eq!(filtered.len(), 2, "should have right and left");

        // Disable right (border[2]), keep left (border[0])
        let border = Some(vec![true, false, false, false]); // [left, top, right, bottom]
        let result = filter_cell_borders(&filtered, &border, x, y, w, h);
        assert_eq!(result.len(), 1, "should have only left");
        // Left border is at x
        assert!((result[0].x1 - x).abs() < 0.5, "remaining border should be left");
    }

    #[test]
    fn filter_cell_borders_without_table_style_uses_correct_indices() {
        let (x, y, w, h) = (0.0, 0.0, 200.0, 100.0);
        let raw = cell_borders(x, y, w, h);
        // No table style filtering
        let filtered = filter_borders(&raw, None, None);
        assert_eq!(filtered.len(), 4);

        // Disable top and bottom, keep left and right
        let border = Some(vec![true, false, true, false]); // [left, top, right, bottom]
        let result = filter_cell_borders(&filtered, &border, x, y, w, h);
        assert_eq!(result.len(), 2, "should have left and right");
        // Verify correct sides
        for line in &result {
            let side = border_side(line, x, y, w, h);
            assert!(side == Some(1) || side == Some(3), "should be right or left, got {:?}", side);
        }
    }

    #[test]
    fn filter_cell_borders_none_border_keeps_all() {
        let (x, y, w, h) = (0.0, 0.0, 200.0, 100.0);
        let raw = cell_borders(x, y, w, h);
        let filtered = filter_borders(&raw, Some(TableStyle::CrossLines), None);
        let result = filter_cell_borders(&filtered, &None, x, y, w, h);
        assert_eq!(result.len(), 4, "None border should keep all");
    }
}
