"""Widget for note display"""

# standard
from enum import Enum
from pathlib import Path

# PyQGIS
from qgis.core import QgsApplication
from qgis.PyQt import QtCore, uic
from qgis.PyQt.QtGui import QPalette
from qgis.PyQt.QtWidgets import QWidget

# project
from oslandia.gitlab_graphql.discussion import DiscussionGraphQLRequestManager, Note
from oslandia.toolbelt.qt_utils import localize_qdatetime, to_qdatetime


class NoteWidget(QWidget):
    """QWidget to display note

    :param parent: dialog parent, defaults to None
    :type parent: Optional[QWidget], optional
    """

    # Signal to indicate changes in note displayed
    noteChanged = QtCore.pyqtSignal()

    # Signal to indicate that the note was updated
    noteUpdated = QtCore.pyqtSignal()

    # Signal to ask for reply:
    replyAsked = QtCore.pyqtSignal()

    class DisplayMode(Enum):
        READ = 1
        UPDATE = 2

    def __init__(self, parent: QWidget | None = None):
        super().__init__(parent)
        ui_path = Path(__file__).resolve(True).parent / "wdg_note.ui"
        uic.loadUi(ui_path, self)

        self.note = None

        palette = self.txt_body.palette()
        normal = palette.color(QPalette.ColorRole.Base).name()

        self.txt_body.setStyleSheet(
            f"""
            QTextEdit {{
                border-radius: 15px;
                border: 2px solid lightblue;
                padding: 10px;
                background-color: {normal};
            }}
        """
        )

        self.txt_body.textChanged.connect(self.noteChanged.emit)
        self.set_display_mode(NoteWidget.DisplayMode.READ)

        self.btn_edit.clicked.connect(self._update_mode)
        self.btn_cancel.clicked.connect(self._cancel_update)
        self.btn_save.clicked.connect(self._update_note)
        self.btn_reply.clicked.connect(self.replyAsked.emit)

        self.btn_edit.setIcon(QgsApplication.getThemeIcon("mActionToggleEditing.svg"))
        self.btn_cancel.setIcon(
            QgsApplication.getThemeIcon("mActionCancelAllEdits.svg")
        )
        self.btn_save.setIcon(QgsApplication.getThemeIcon("mActionSaveAllEdits.svg"))

        self.btn_reply.setIcon(QgsApplication.getThemeIcon("mActionTiltUp.svg"))

    def _update_mode(self) -> None:
        """Switch to UPDATE mode"""
        self.set_display_mode(NoteWidget.DisplayMode.UPDATE)

    def _cancel_update(self) -> None:
        """Cancel UPDATE mode and restore displayed note"""
        if self.note:
            self.set_note(self.note)
        self.set_display_mode(NoteWidget.DisplayMode.READ)

    def _update_note(self) -> None:
        """Update note with current displayed values"""
        if self.note:
            body = self.txt_body.toPlainText()
            manager = DiscussionGraphQLRequestManager()
            note = manager.update_issue_note(note_id=self.note.graphql_id, body=body)
            if note is not None:
                self.set_note(note)
                self.set_display_mode(NoteWidget.DisplayMode.READ)
                self.noteUpdated.emit()

    def set_display_mode(self, mode: DisplayMode) -> None:
        """Set display mode:
            NoteWidget.DisplayMode.READ : all GUI are read only
            NoteWidget.DisplayMode.UPDATE : user can edit GUI

        :param mode: display mode
        :type mode: DisplayMode
        """
        self.display_mode = mode
        # Read only attribute
        read_only = mode == NoteWidget.DisplayMode.READ
        self.txt_body.setReadOnly(read_only)
        self.btn_edit.setVisible(mode == NoteWidget.DisplayMode.READ)
        self.btn_save.setVisible(mode == NoteWidget.DisplayMode.UPDATE)
        self.btn_cancel.setVisible(mode == NoteWidget.DisplayMode.UPDATE)

    def set_note(self, note: Note) -> None:
        """Set note displayed

        :param note: note
        :type note: Note
        """
        self.note = note
        self.txt_body.setText(note.body)
        self.txt_body.set_project_id(note.project_id)
        self.lbl_name.setText(note.author.name)
        self.lbl_user_name.setText(f"@{note.author.username}")
        self.lbl_date.setText(
            localize_qdatetime(
                to_qdatetime(note.created_at),
            )
        )
        self.lbl_date.setToolTip(
            localize_qdatetime(to_qdatetime(note.created_at), date_format="long")
        )

        self.btn_edit.setEnabled(False)
        self.btn_edit.setToolTip(self.tr("User permission undefined"))

        if note.user_permision is not None:
            self.btn_edit.setEnabled(note.user_permision.admin_note)
            self.btn_edit.setToolTip(
                ""
                if note.user_permision.admin_note
                else self.tr("You don't have the permission to edit this note")
            )
