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

:Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
:Description: Verify editor population and parameter model 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 Qt
from PySide6.QtWidgets import QApplication

from mafw.steering.models import ParameterConfig, ParameterSchemaStatus, ParameterSource, ProcessorConfig
from mafw.steering_gui.views.processor_parameter_editor import ParameterTableModel, ProcessorParameterEditor

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 test_editor_populates_processor_fields(qapp: QApplication) -> None:
    """Editor should display processor name, replica, and flags."""

    editor = ProcessorParameterEditor()
    config = ProcessorConfig(
        name='Proc#R1',
        new_only=True,
        inheritance=False,
        parameters={
            'alpha': ParameterConfig(
                name='alpha',
                value=1,
                default=1,
                source=ParameterSource.CONFIG,
                status=ParameterSchemaStatus.OK,
            )
        },
    )
    editor.set_processor_data(config)

    assert editor.current_name() == 'Proc#R1'
    assert editor._processor_label.text() == 'Processor: Proc'
    assert editor._replica_edit.text() == 'R1'
    assert editor._new_only_checkbox.isChecked() is True
    assert editor._inherit_checkbox.isChecked() is False


def test_parameter_model_emits_changes(qapp: QApplication) -> None:
    """Parameter model should emit signals for value and active changes."""

    model = ParameterTableModel()
    model.set_parameters(
        [
            ParameterConfig(
                name='alpha',
                value=1,
                default=1,
                source=ParameterSource.DEFAULT,
                status=ParameterSchemaStatus.OK,
            )
        ]
    )

    value_changes: list[tuple[str, object]] = []
    active_changes: list[tuple[str, bool]] = []
    model.parameter_value_changed.connect(lambda name, value: value_changes.append((name, value)))
    model.parameter_active_changed.connect(lambda name, active, value: active_changes.append((name, active)))

    value_index = model.index(0, 2)
    assert model.setData(value_index, 5, Qt.ItemDataRole.EditRole) is True
    assert value_changes == [('alpha', 5)]
    assert model._rows[0].config.active_override is True

    active_index = model.index(0, 0)
    assert model.setData(active_index, Qt.CheckState.Checked, Qt.ItemDataRole.CheckStateRole) is True
    assert active_changes == [('alpha', True)]


def test_parameter_model_boolean_value_uses_checkbox(qapp: QApplication) -> None:
    """Boolean parameters should render and update via a check state."""

    model = ParameterTableModel()
    model.set_parameters(
        [
            ParameterConfig(
                name='flag',
                value=False,
                default=False,
                source=ParameterSource.DEFAULT,
                status=ParameterSchemaStatus.OK,
                type=bool,
            )
        ]
    )

    index = model.index(0, 2)
    assert model.data(index, Qt.ItemDataRole.DisplayRole) == ''
    assert model.data(index, Qt.ItemDataRole.CheckStateRole) == Qt.CheckState.Unchecked

    assert model.setData(index, Qt.CheckState.Checked, Qt.ItemDataRole.CheckStateRole) is True
    assert model._rows[0].config.value is True
    assert model._rows[0].config.active_override is True
