#  Copyright 2026 European Union
#  Author: Bulgheroni Antonio (antonio.bulgheroni@ec.europa.eu)
#  SPDX-License-Identifier: EUPL-1.2
"""Dialog for selecting fields for field filters."""

from __future__ import annotations

from typing import TYPE_CHECKING

from PySide6.QtCore import QSortFilterProxyModel, Qt
from PySide6.QtGui import QStandardItem, QStandardItemModel
from PySide6.QtWidgets import (
    QDialog,
    QHBoxLayout,
    QLabel,
    QLineEdit,
    QListView,
    QPushButton,
    QVBoxLayout,
    QWidget,
)

if TYPE_CHECKING:
    from mafw.steering.models import ModelFilterConfig, ProcessorConfig


class AddFieldFilterDialog(QDialog):
    """Dialog presenting a selectable list of fields for a model."""

    def __init__(
        self,
        model_config: ModelFilterConfig,
        processor_config: ProcessorConfig,
        parent: QWidget | None = None,
    ) -> None:
        super().__init__(parent)
        self.setWindowTitle(f'Add Field Filter for {model_config.model}')

        self._model_config = model_config
        self._processor_config = processor_config

        # Create model items
        self._model = QStandardItemModel()
        self._populate_model()

        self._proxy_model = QSortFilterProxyModel(self)
        self._proxy_model.setSourceModel(self._model)
        self._proxy_model.setFilterCaseSensitivity(Qt.CaseSensitivity.CaseInsensitive)

        self.list_view = QListView()
        self.list_view.setModel(self._proxy_model)
        self.list_view.setSelectionMode(QListView.SelectionMode.SingleSelection)
        self.list_view.setEditTriggers(QListView.EditTrigger.NoEditTriggers)

        self.filter_edit = QLineEdit()
        self.filter_edit.setClearButtonEnabled(True)
        self.filter_edit.setPlaceholderText('Filter fields...')

        self._prompt = QLabel(f'Select a field from {model_config.model} to add as a field filter.')
        self._prompt.setWordWrap(True)

        self.add_button = QPushButton('Add')
        self.add_button.setEnabled(False)
        self.cancel_button = QPushButton('Cancel')

        self._setup_layout()
        self._wire_signals()
        self.resize(300, 400)

    def _populate_model(self) -> None:
        if not self._model_config.model_info:
            return

        # Fields already in ModelFilterConfig
        existing_conditions = set(self._model_config.conditions.keys())

        # Fields already in FieldFilterConfigs
        existing_field_filters = set()
        filters = self._processor_config.filters.get(self._model_config.model, [])
        from mafw.steering.models import FieldFilterConfig

        for f in filters:
            if isinstance(f, FieldFilterConfig):
                existing_field_filters.add(f.field_name)

        excluded = existing_conditions | existing_field_filters

        for field_name, info in self._model_config.model_info.field_info.items():
            if field_name in excluded:
                continue

            item = QStandardItem(field_name)
            if info.help_text:
                item.setToolTip(info.help_text)
            self._model.appendRow(item)

    def selected_field(self) -> str | None:
        """Return the currently selected field name."""
        indexes = self.list_view.selectionModel().selectedIndexes()
        if not indexes:
            return None
        proxy_index = indexes[0]
        source_index = self._proxy_model.mapToSource(proxy_index)
        return self._model.itemFromIndex(source_index).text()

    def _setup_layout(self) -> None:
        buttons = QHBoxLayout()
        buttons.addStretch(1)
        buttons.addWidget(self.cancel_button)
        buttons.addWidget(self.add_button)

        layout = QVBoxLayout()
        layout.addWidget(self._prompt)
        layout.addWidget(self.filter_edit)
        layout.addWidget(self.list_view)
        layout.addLayout(buttons)
        self.setLayout(layout)

    def _wire_signals(self) -> None:
        self.list_view.selectionModel().selectionChanged.connect(self._update_add_enabled)
        self.list_view.doubleClicked.connect(lambda *_: self.accept())
        self.add_button.clicked.connect(self.accept)
        self.cancel_button.clicked.connect(self.reject)
        self.filter_edit.textChanged.connect(self._proxy_model.setFilterFixedString)

    def _update_add_enabled(self, *_: object) -> None:
        has_selection = bool(self.list_view.selectionModel().selectedIndexes())
        self.add_button.setEnabled(has_selection)
