"""Tests for the overhauled Positioning & Layout UI."""

from types import SimpleNamespace
import importlib

import pytest


panels = importlib.import_module("src.ui.panels")


class FakeLayout:
    """Minimal substitute for Blender layout that records UI calls."""

    def __init__(self, kind="layout"):
        self.kind = kind
        self.calls = []
        self.children = []
        self.enabled = True
        self.alignment = None
        self.scale_x = 1.0
        self.scale_y = 1.0
        self.use_property_split = False
        self.use_property_decorate = True

    def _child(self, kind, kwargs):
        child = FakeLayout(kind)
        self.calls.append((kind, kwargs, child))
        self.children.append(child)
        return child

    def label(self, text="", **kwargs):
        self.calls.append(("label", {"text": text, **kwargs}))
        return None

    def prop(self, props, prop_name, **kwargs):
        # Access attribute to mirror Blender's behaviour of raising AttributeError
        getattr(props, prop_name)
        data = {"name": prop_name}
        data.update(kwargs)
        self.calls.append(("prop", data))
        return None

    def separator(self, **kwargs):
        self.calls.append(("separator", kwargs))
        return None

    def row(self, **kwargs):
        return self._child("row", kwargs)

    def column(self, **kwargs):
        return self._child("column", kwargs)

    def box(self):
        return self._child("box", {})

    def operator(self, operator_id, **kwargs):
        self.calls.append(("operator", {"id": operator_id, **kwargs}))
        return SimpleNamespace()


def collect_calls(layout):
    """Flatten recorded calls from layout tree."""
    flattened = []
    for entry in layout.calls:
        if len(entry) == 3:
            kind, kwargs, child = entry
            flattened.append((kind, kwargs))
            flattened.extend(collect_calls(child))
        else:
            flattened.append(entry)
    return flattened


def make_default_props(**overrides):
    """Helper to build a props namespace with defaults for positioning tests."""
    defaults = dict(
        text="Main",
        texture_width=1024,
        texture_height=1024,
        prepend_text="",
        append_text="",
        prepend_margin=10.0,
        append_margin=10.0,
        prepend_append_layout="HORIZONTAL",
        position_mode="PRESET",
        anchor_point="MIDDLE_CENTER",
        margins_linked=False,
        margin_x=0.0,
        margin_y=0.0,
        offset_x=0,
        offset_y=0,
        manual_position_unit="PERCENTAGE",
        manual_position_x=50.0,
        manual_position_y=50.0,
        constrain_to_canvas=True,
        image_overlays=[],
        active_overlay_index=0,
    )
    defaults.update(overrides)
    return SimpleNamespace(**defaults)


def test_text_input_section_exposes_dimensions():
    """Dimensions should appear alongside the main text control."""
    layout = FakeLayout()
    props = make_default_props()

    panels.draw_text_input_section(layout, props)

    calls = collect_calls(layout)
    prop_names = [data["name"] for kind, data in calls if kind == "prop"]
    assert "texture_width" in prop_names
    assert "texture_height" in prop_names


def test_positioning_section_drops_additional_text(monkeypatch):
    """Positioning panel should no longer render prepend/append controls."""
    layout = FakeLayout()
    props = make_default_props()

    monkeypatch.setattr("src.utils.system.get_anchor_point_matrix", lambda: [["CENTER"]])
    monkeypatch.setattr(panels, "safe_operator_call", lambda *args, **kwargs: SimpleNamespace())

    panels.draw_positioning_section(layout, props)

    calls = collect_calls(layout)
    labels = [data["text"] for kind, data in calls if kind == "label"]
    prop_names = [data["name"] for kind, data in calls if kind == "prop"]

    assert "Additional Text:" not in labels
    assert "prepend_text" not in prop_names
    assert "append_text" not in prop_names


def test_composition_section_renders_text_component(monkeypatch):
    """Composition panel should show text component controls within the proper section."""
    layout = FakeLayout()
    text_component = SimpleNamespace(
        enabled=True,
        name="Intro Text",
        component_type="TEXT",
        placement_mode="PREPEND",
        text_content="Intro",
        text_spacing=10.0,
        image_spacing=5.0,
        x_position=0.5,
        y_position=0.5,
        scale=1.0,
        rotation=0.0,
        z_index=0,
    )
    props = make_default_props(image_overlays=[text_component])

    monkeypatch.setattr(panels, "safe_operator_call", lambda *args, **kwargs: SimpleNamespace())
    monkeypatch.setattr(panels, "has_image_overlays", lambda: True)

    panels.draw_composition_section(layout, props)

    calls = collect_calls(layout)
    prop_names = [data["name"] for kind, data in calls if kind == "prop"]
    labels = [data["text"] for kind, data in calls if kind == "label"]
    sections = [text for text in labels if "Components" in text]

    assert "component_type" in prop_names
    assert "text_content" in prop_names
    assert "placement_mode" in prop_names
    assert "text_spacing" in prop_names
    assert "Prepended Components" in sections


def test_composition_section_renders_image_component(monkeypatch):
    """Composition panel should show image component controls within the proper section."""
    layout = FakeLayout()
    image_component = SimpleNamespace(
        enabled=True,
        name="Logo",
        component_type="IMAGE",
        placement_mode="ABSOLUTE",
        image_path="/tmp/logo.png",
        x_position=0.5,
        y_position=0.5,
        text_spacing=10.0,
        image_spacing=5.0,
        scale=1.0,
        rotation=0.0,
        z_index=1,
    )
    props = make_default_props(image_overlays=[image_component])

    monkeypatch.setattr(panels, "safe_operator_call", lambda *args, **kwargs: SimpleNamespace())
    monkeypatch.setattr(panels, "has_image_overlays", lambda: True)

    panels.draw_composition_section(layout, props)

    calls = collect_calls(layout)
    prop_names = [data["name"] for kind, data in calls if kind == "prop"]
    labels = [data["text"] for kind, data in calls if kind == "label"]
    sections = [text for text in labels if "Components" in text]

    assert "component_type" in prop_names
    assert "image_path" in prop_names
    assert "placement_mode" in prop_names
    assert "x_position" in prop_names
    assert "Absolute Components" in sections
