from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import QSize, QPropertyAnimation, QEasingCurve, QParallelAnimationGroup
from PyQt5.QtGui import QFont
from PyQt5.QtWidgets import QPushButton, QSizePolicy
from qgis.core import QgsMessageLog, Qgis
import logging
from weissflaechenkartierung.res import styles
from weissflaechenkartierung.src.tools import get_module_name

# logger = logging.getLogger(get_module_name())
logger = logging.getLogger("base_logger")


class WindowFunctions:
    menu_pages = {
        "btn_menu_wfk": {
            "index": 0,
            "txt": "Kartierung",
            "icon": "url(:/16x16/map.png)"
        },
        "btn_menu_analyze": {
            "index": 1,
            "txt": "Analyse",
            "icon": "url(:/16x16/magnifying-glass.png)"
        },
        "btn_menu_settings": {
            "index": 2,
            "txt": "Einstellungen",
            "icon": "url(:/16x16/settings.png)"
        },
        "btn_menu_ciss": {
            "index": 3
        }
    }

    def __init__(self, window):
        self.wnd = window
        self.menu_count = 0
        self.last_menus: list = []
        self.cur_menu: str = ""

    @staticmethod
    def deselect_menu(get_style, object_id: str):
        """
        deselect the right frame of the button
        """
        deselect = get_style.replace(
            styles.WIDGET.FRAME_MENU_SELECTION.replace("OBJECTID", object_id),
            ""
        )
        return deselect

    @staticmethod
    def select_menu(get_style, object_id: str):
        """
        select the right frame of the button
        """
        select = get_style + styles.WIDGET.FRAME_MENU_SELECTION.replace("OBJECTID", object_id)
        return select

    def go_to_last_menu_point(self):
        """
        goes to the last known menu point
        """
        if len(self.last_menus) > 0:
            last_menu = self.last_menus.pop()
            self.change_menu(last_menu)

    def change_menu(self, obj_name: str):
        """
        changes the current selected menu
        """
        try:
            # reset all selections
            for w in self.wnd.ui.frame_left_menu.findChildren(QtWidgets.QFrame):
                w.setStyleSheet(self.deselect_menu(w.styleSheet(), w.objectName()))

            # select the right one
            for w in self.wnd.ui.frame_left_menu.findChildren(QtWidgets.QFrame):
                if w.objectName() == "frame_" + obj_name:
                    w.setStyleSheet(self.select_menu(w.styleSheet(), w.objectName()))
            # select the right index
            self.wnd.ui.pages_widget.setCurrentIndex(self.menu_pages[obj_name]["index"])
            # set the right orientation
        except KeyError:
            logger.error("can not change the menu, the menu key does not exist")
            QgsMessageLog.logMessage(message="WfkDialog:change_menu: can not change the menu, the menu key does not "
                                             "exist",
                                     level=Qgis.Critical)

    def menu_button_clicked(self):
        """
        called when the user serves trough the menu
        """
        btn_obj_name: str = self.wnd.sender().objectName()  # get the current sender object (in this case the btn)
        if self.cur_menu != "" and self.cur_menu != btn_obj_name:  # change only if the cur one is not empty
            if len(self.last_menus) > 10:
                self.last_menus.pop(0)
            self.last_menus.append(self.cur_menu)
        self.cur_menu = btn_obj_name
        if btn_obj_name in self.menu_pages:
            self.change_menu(obj_name=btn_obj_name)  # changes the current menu to the new

    def toggle_menu(self, max_width, enable):
        """
        called when the users toggles the menu button
        """
        if enable:
            # GET WIDTH
            width = self.wnd.ui.frame_left_menu_container.width()
            max_extend = max_width
            standard = 60

            # SET MAX WIDTH
            if width == 60:
                width_extended = max_extend
                self.wnd.ui.btn_toggle.setToolTip("Zuklappen")
            else:
                width_extended = standard
                self.wnd.ui.btn_toggle.setToolTip("Aufklappen")

            # ANIMATION
            self.anim1 = QPropertyAnimation(self.wnd.ui.frame_left_menu_container, b"minimumWidth")
            self.anim1.setDuration(100)
            self.anim1.setStartValue(width)
            self.anim1.setEndValue(width_extended)
            self.anim1.setEasingCurve(QEasingCurve.InOutQuart)

            self.anim2 = QPropertyAnimation(self.wnd.ui.frame_left_menu, b"minimumWidth")
            self.anim2.setDuration(100)
            self.anim2.setStartValue(width)
            self.anim2.setEndValue(width_extended)
            self.anim2.setEasingCurve(QEasingCurve.InOutQuart)

            self.anim_group = QParallelAnimationGroup()
            self.anim_group.addAnimation(self.anim1)
            self.anim_group.addAnimation(self.anim2)
            self.anim_group.start()

    def add_new_btn_to_menu(self, obj_name):
        """
        adds a dynamic button to the menu bar
        """
        logger.info("added new menu button: " + obj_name)
        new_btn_font = QFont()
        new_btn_font.setFamily(u"Segoe UI")
        new_button = QPushButton(str(self.menu_count), self.wnd)
        new_button.setObjectName(obj_name)

        new_button_sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        new_button_sizePolicy.setHorizontalStretch(0)
        new_button_sizePolicy.setVerticalStretch(0)
        new_button_sizePolicy.setHeightForWidth(new_button.sizePolicy().hasHeightForWidth())

        new_button.setSizePolicy(new_button_sizePolicy)
        new_button.setMinimumSize(QSize(0, 70))
        new_button.setLayoutDirection(QtCore.Qt.LeftToRight)
        new_button.setFont(new_btn_font)

        if "icon" in self.menu_pages[obj_name]:
            new_button.setStyleSheet(
                styles.WIDGET.BUTTON_MENU.replace('ICON_REPLACE', self.menu_pages[obj_name]["icon"]))

        if "txt" in self.menu_pages[obj_name]:
            new_button.setText(self.menu_pages[obj_name]["txt"])
            new_button.setToolTip(self.menu_pages[obj_name]["txt"])
        new_button.clicked.connect(self.menu_button_clicked)

        f = QtWidgets.QFrame()
        f.setFrameShape(QtWidgets.QFrame.NoFrame)
        f.setFrameShadow(QtWidgets.QFrame.Raised)
        f.setObjectName("frame_" + obj_name)
        l = QtWidgets.QVBoxLayout(f)
        l.setObjectName("l")
        l.setSpacing(0)
        l.setContentsMargins(0, 0, 0, 0)

        f_size_policy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
        f_size_policy.setHorizontalStretch(0)
        f_size_policy.setVerticalStretch(0)
        f_size_policy.setHeightForWidth(new_button.sizePolicy().hasHeightForWidth())

        f.setMinimumSize(QSize(0, 70))
        f.setLayoutDirection(QtCore.Qt.LeftToRight)
        f.setSizePolicy(f_size_policy)

        f.layout().addWidget(new_button)

        self.wnd.ui.layout_menus.addWidget(f)

    @staticmethod
    def enable_widget(enable: bool, widget: QtWidgets.QWidget) -> bool:
        """
        disables or enables any widget and colorize it
        """
        if widget:
            widget.setEnabled(enable)
            style_sheet_lighter = "QPushButton { background-color: rgba(52, 59, 72, 100);}"

            if not enable:
                widget.setStyleSheet(widget.styleSheet() + style_sheet_lighter)
            else:
                widget.setStyleSheet(widget.styleSheet().replace(style_sheet_lighter, ""))
            return True
        return False
