#  Copyright 2026 European Union
#  Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
#  SPDX-License-Identifier: EUPL-1.2
"""Unit tests for the GroupEditor widget.

:Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
:Description: Verify selection updates toolbox buttons and emits edit/remove signals.
"""

from __future__ import annotations

import pytest

# Skip this module if PySide6 is not available
pytest.importorskip('PySide6', reason='PySide6 is required for GUI tests')
from PySide6.QtCore import QItemSelectionModel
from PySide6.QtWidgets import QApplication

from mafw.steering.models import GroupConfig, ProcessorConfig
from mafw.steering_gui.controllers.steering_controller import SteeringController
from mafw.steering_gui.models.pipeline import PipelineItem, ProcessorPipeline
from mafw.steering_gui.models.steering_tree_model import SteeringTreeModel
from mafw.steering_gui.views.group_editor import GroupEditor

pytestmark = pytest.mark.gui


@pytest.fixture(scope='session')
def qapp() -> QApplication:
    """Ensure a single QApplication instance exists for all GUI tests."""

    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    return app


def _sample_model() -> tuple[SteeringTreeModel, PipelineItem]:
    controller = SteeringController()
    group_config = GroupConfig(name='GroupA', processors=['Proc1'], description='hello')
    group = PipelineItem(config=group_config)
    child = PipelineItem(config=ProcessorConfig(name='Proc1'), parent=group)
    group.children = [child]
    pipeline = ProcessorPipeline(items=[group])
    return SteeringTreeModel(controller, pipeline), group


def test_group_editor_sets_name_and_description(qapp: QApplication) -> None:
    """Setting a group item should populate the name and description fields."""

    editor = GroupEditor()
    model, group_item = _sample_model()
    editor.set_model(model)
    editor.set_group_item(group_item)

    assert editor._name_edit.text() == 'GroupA'
    assert editor._description_edit.text() == 'hello'


def test_group_editor_buttons_enable_with_selection(qapp: QApplication) -> None:
    """Selecting a row should enable the toolbox buttons."""

    editor = GroupEditor()
    model, group_item = _sample_model()
    editor.set_model(model)
    editor.set_group_item(group_item)

    assert editor._edit_button.isEnabled() is False
    root_index = editor._table.rootIndex()
    index = model.index(0, 0, root_index)
    editor._table.selectionModel().select(
        index,
        QItemSelectionModel.SelectionFlag.Select | QItemSelectionModel.SelectionFlag.Rows,
    )
    editor._update_action_state()

    assert editor._edit_button.isEnabled() is True
    assert editor._remove_button.isEnabled() is True


def test_group_editor_edit_and_remove_emit_signals(qapp: QApplication) -> None:
    """Edit and remove handlers should emit the related signals."""

    editor = GroupEditor()
    model, group_item = _sample_model()
    editor.set_model(model)
    editor.set_group_item(group_item)

    root_index = editor._table.rootIndex()
    index = model.index(0, 0, root_index)
    editor._table.selectionModel().select(
        index,
        QItemSelectionModel.SelectionFlag.Select | QItemSelectionModel.SelectionFlag.Rows,
    )
    editor._update_action_state()

    edits: list[str] = []
    removes: list[int] = []
    editor.edit_requested.connect(lambda item: edits.append(item.name()))
    editor.remove_requested.connect(lambda items: removes.append(len(items)))

    editor._on_edit_selected()
    editor._on_remove_selected()

    assert edits == ['Proc1']
    assert removes == [1]
