from qgis.PyQt.QtCore import QModelIndex, QObject, QSortFilterProxyModel, Qt

from oslandia.gui.mdl_issue import IssuesListModel


class IssueProxyModel(QSortFilterProxyModel):
    def __init__(self, parent: QObject = None):
        """Proxy model for issue

        :param parent: object parent, defaults to None
        :type parent: QObject, optional
        """
        super().__init__(parent)
        self.userid_list = []
        self._show_closed = True
        self._search_txt = None

    def show_closed(self, show: bool = True) -> None:
        """Define if closed issue should be displayed

        :param show: visibility value, defaults to True
        :type show: bool, optional
        """
        if self._show_closed != show:
            self._show_closed = show
            self.invalidateFilter()

    def set_visible_user(self, userid_list: list) -> None:
        """If a user is defined, only issues assigned to this userid will be displayed.

        :param userid: User ID
        :type userid: list
        """
        if self.userid_list != userid_list:
            self.userid_list = userid_list
            self.invalidateFilter()

    def set_search_txt(self, search_txt: str | None) -> None:
        """If a search text is defined, only issue with name or description containing search text will be displayed

        :param search_txt: _description_
        :type search_txt: Optional[str]
        """
        if self._search_txt != search_txt:
            self._search_txt = search_txt
            self.invalidateFilter()

    def filterAcceptsRow(self, source_row: int, source_parent: QModelIndex) -> bool:
        """
        Filter visible rows for issue

        Args:
            source_row: (int) source row
            source_parent: (QModelIndex) source parent

        Returns: True if row is visible, False otherwise

        """
        result = True
        name_index = self.sourceModel().index(
            source_row, IssuesListModel.NAME_COL, source_parent
        )
        issue = self.sourceModel().data(name_index, Qt.ItemDataRole.UserRole)
        if not self._show_closed and issue:
            result &= issue.state != "closed"

        if self._search_txt and issue:
            result &= (
                self._search_txt in issue.description or self._search_txt in issue.name
            )

        if self.userid_list and issue:
            result &= issue.assignee_id in self.userid_list

        return result
