from typing import Any, List
from PySide6 import QtCore, QtGui


class QLogModel(QtCore.QAbstractTableModel):
    def __init__(self, *args: Any):
        QtCore.QAbstractTableModel.__init__(self, *args)
        self._entries: List[Any] = []

    def rowCount(self, parent: Any = None, *args: Any, **kwargs: Any) -> int:
        return len(self._entries)

    def columnCount(self, parent: Any = None, *args: Any, **kwargs: Any) -> int:
        return 3

    def data(self, index: QtCore.QModelIndex, role: Any = None) -> Any:
        if role == QtCore.Qt.DisplayRole:
            # data to display
            d = self._entries[index.row()][index.column()]
            return d

        elif role == QtCore.Qt.ForegroundRole and index.column() == 1:
            # text colors for log level
            return {
                "INFO": QtGui.QColor("lime"),
                "WARNING": QtGui.QColor("orange"),
                "ERROR": QtGui.QColor("red"),
                "SEND": QtGui.QColor("blue"),
                "DEBUG": QtGui.QColor("blue"),
                "CRITICAL": QtGui.QColor("violet"),
            }[self._entries[index.row()][index.column()]]

        return None

    def headerData(self, section: int, orientation: Any, role: Any = None) -> Any:
        if role == QtCore.Qt.DisplayRole and orientation == QtCore.Qt.Horizontal:
            return ["Time", "Level", "Message"][section]
        return QtCore.QAbstractTableModel.headerData(self, section, orientation, role)

    def add_entry(self, entry: Any) -> None:
        self.beginInsertRows(QtCore.QModelIndex(), len(self._entries), len(self._entries))
        self._entries.append(entry)
        self.endInsertRows()

class LogModelProxy(QtCore.QSortFilterProxyModel):
    def __init__(self, *args: Any):
        QtCore.QSortFilterProxyModel.__init__(self, *args)
        self.setDynamicSortFilter(True)
        self.sort(0)
        self._filter_source: List[str] = []

    def filterAcceptsRow(self, row: int, parent: QtCore.QModelIndex) -> bool:
        # show it
        return True

    def filter_source(self, source: str, show: bool) -> None:
        if show and source in self._filter_source:
            self._filter_source.remove(source)
            self.invalidateFilter()
        elif not show and source not in self._filter_source:
            self._filter_source.append(source)
            self.invalidateFilter()


__all__ = ["QLogModel", "LogModelProxy"]
