"""Tests for the layout composition engine."""

from __future__ import annotations

import pytest

from pptx_mcp.engine.composition import Cell, LayoutGrid, Margin
from pptx_mcp.models.slides import Position


class TestCell:
    def test_to_position(self) -> None:
        cell = Cell(left=1.0, top=2.0, width=3.0, height=4.0)
        pos = cell.to_position()
        assert isinstance(pos, Position)
        assert pos.left == 1.0
        assert pos.top == 2.0
        assert pos.width == 3.0
        assert pos.height == 4.0

    def test_inset(self) -> None:
        cell = Cell(left=1.0, top=1.0, width=4.0, height=3.0)
        inset = cell.inset(0.5)
        assert inset.left == 1.5
        assert inset.top == 1.5
        assert inset.width == 3.0
        assert inset.height == 2.0

    def test_inset_clamps_to_minimum(self) -> None:
        cell = Cell(left=1.0, top=1.0, width=0.5, height=0.5)
        inset = cell.inset(0.5)
        assert inset.width == 0.1
        assert inset.height == 0.1

    def test_split_vertical(self) -> None:
        cell = Cell(left=1.0, top=1.0, width=4.0, height=4.0)
        top, bottom = cell.split_vertical(0.25)
        assert top.height == 1.0
        assert bottom.height == 3.0
        assert bottom.top == 2.0

    def test_split_horizontal(self) -> None:
        cell = Cell(left=1.0, top=1.0, width=6.0, height=4.0)
        left, right = cell.split_horizontal(0.5)
        assert left.width == 3.0
        assert right.width == 3.0
        assert right.left == 4.0


class TestLayoutGrid:
    def test_content_area(self) -> None:
        grid = LayoutGrid(
            slide_width=13.333, slide_height=7.5,
            margin=Margin(left=0.75, right=0.75, top=1.6, bottom=0.5),
        )
        assert grid.content_width == pytest.approx(11.833)
        assert grid.content_height == pytest.approx(5.4)

    def test_columns_count(self) -> None:
        grid = LayoutGrid()
        cells = grid.columns(3, gap=0.4)
        assert len(cells) == 3

    def test_columns_fill_width(self) -> None:
        grid = LayoutGrid(slide_width=10.0, margin=Margin(left=1.0, right=1.0, top=1.0, bottom=1.0))
        cells = grid.columns(2, gap=0.5)
        total = sum(c.width for c in cells) + 0.5  # 2 cols + 1 gap
        assert total == pytest.approx(8.0)

    def test_columns_no_overlap(self) -> None:
        grid = LayoutGrid()
        cells = grid.columns(4, gap=0.3)
        for i in range(len(cells) - 1):
            assert cells[i].left + cells[i].width <= cells[i + 1].left + 0.01

    def test_rows_count(self) -> None:
        grid = LayoutGrid()
        cells = grid.rows(3, gap=0.3)
        assert len(cells) == 3

    def test_grid_dimensions(self) -> None:
        grid = LayoutGrid()
        result = grid.grid(3, 2)
        assert len(result) == 2
        assert len(result[0]) == 3

    def test_auto_layout_single_row(self) -> None:
        grid = LayoutGrid()
        cells = grid.auto_layout(3, max_cols=4)
        assert len(cells) == 3
        # Should be a single row since 3 <= max_cols
        assert all(c.top == cells[0].top for c in cells)

    def test_auto_layout_wraps(self) -> None:
        grid = LayoutGrid()
        cells = grid.auto_layout(6, max_cols=3)
        assert len(cells) == 6
        # First 3 in one row, next 3 in another
        assert cells[0].top == cells[1].top == cells[2].top
        assert cells[3].top == cells[4].top == cells[5].top
        assert cells[0].top < cells[3].top

    def test_auto_layout_empty(self) -> None:
        grid = LayoutGrid()
        assert grid.auto_layout(0) == []

    def test_centered_cell(self) -> None:
        grid = LayoutGrid(slide_width=10.0, margin=Margin(left=1.0, right=1.0, top=1.0, bottom=1.0))
        cell = grid.centered_cell(4.0, 2.0)
        # Content area is 8.0 wide, cell is 4.0 → centered at left=3.0
        assert cell.left == pytest.approx(3.0)
        assert cell.width == 4.0

    def test_full_width_row(self) -> None:
        grid = LayoutGrid()
        cell = grid.full_width_row(top=2.0, height=1.0)
        assert cell.width == grid.content_width
        assert cell.top == 2.0
        assert cell.height == 1.0

    def test_side_by_side_equal(self) -> None:
        grid = LayoutGrid(slide_width=10.0, margin=Margin(left=1.0, right=1.0, top=1.0, bottom=1.0))
        left, right = grid.side_by_side(left_ratio=0.5, gap=0.4)
        assert left.width == pytest.approx(right.width)
        assert left.left + left.width + 0.4 == pytest.approx(right.left)

    def test_side_by_side_asymmetric(self) -> None:
        grid = LayoutGrid(slide_width=10.0, margin=Margin(left=1.0, right=1.0, top=1.0, bottom=1.0))
        left, right = grid.side_by_side(left_ratio=0.6, gap=0.4)
        assert left.width > right.width
