from dataclasses import dataclass

from aitop.ui.layout import LayoutCalculator, LayoutRect


@dataclass
class _FakeDisplay:
    height: int
    width: int


def test_layout_narrow_terminal_disables_overview_split() -> None:
    display = _FakeDisplay(height=40, width=100)
    calculator = LayoutCalculator(display)

    layout = calculator.calculate()

    assert layout["overview_separator_x"] == -1
    assert layout["overview_left"] == layout["content"]
    assert layout["overview_right"] == LayoutRect(0, 0, 0, 0)


def test_layout_wide_terminal_enables_overview_split() -> None:
    display = _FakeDisplay(height=40, width=160)
    calculator = LayoutCalculator(display)

    layout = calculator.calculate()
    left = layout["overview_left"]
    right = layout["overview_right"]
    separator_x = layout["overview_separator_x"]

    assert separator_x >= 0
    assert left.right == separator_x
    assert right.x == separator_x + calculator.OVERVIEW_SEPARATOR_WIDTH
    assert right.width >= 0


def test_layout_cache_reused_until_dimensions_change() -> None:
    display = _FakeDisplay(height=40, width=160)
    calculator = LayoutCalculator(display)

    first = calculator.calculate()
    second = calculator.calculate()
    assert first is second

    display.width = 161
    third = calculator.calculate()
    assert third is not second


def test_get_content_area_applies_margins() -> None:
    display = _FakeDisplay(height=30, width=120)
    calculator = LayoutCalculator(display)

    layout = calculator.calculate()
    content = layout["content"]
    inner = calculator.get_content_area()

    assert inner.x == content.x + calculator.CONTENT_MARGIN_LEFT
    expected_inner_width = (
        content.width - calculator.CONTENT_MARGIN_LEFT - calculator.CONTENT_MARGIN_RIGHT
    )
    assert inner.width == max(
        0,
        expected_inner_width,
    )


def test_get_bar_width_respects_floor_and_cap() -> None:
    display = _FakeDisplay(height=30, width=40)
    calculator = LayoutCalculator(display)

    assert calculator.get_bar_width(max_width=50, label_width=100) == 10

    display.width = 300
    calculator.invalidate_cache()
    assert calculator.get_bar_width(max_width=50, label_width=10) == 50
