# coding:utf-8
from typing import List
from PySide6.QtCore import Qt, QRect, QRectF, QSize
from PySide6.QtGui import QPainter, QColor, QPainterPath, QAction
from PySide6.QtWidgets import QLineEdit, QListWidgetItem, QListWidget

from ..widgets.menu  import (RoundMenu, MenuAnimationType, MenuAnimationManager, MenuActionListWidget,
                             IndicatorMenuItemDelegate, LineEditMenu, MenuIndicatorType, CheckableMenu)
from ..widgets.line_edit import CompleterMenu, LineEdit
from ..widgets.acrylic_label import AcrylicBrush
from ...common.style_sheet import isDarkTheme


class AcrylicMenuActionListWidget(MenuActionListWidget):

    def __init__(self, parent=None):
        super().__init__(parent)
        self.acrylicBrush = AcrylicBrush(self.viewport(), 35)
        self.setViewportMargins(0, 0, 0, 0)
        self.setProperty("transparent", True)

        super().addItem(self.createPlaceholderItem(self._topMargin()))
        super().addItem(self.createPlaceholderItem(self._bottomMargin()))

    def _updateAcrylicColor(self):
        if isDarkTheme():
            tintColor = QColor(32, 32, 32, 200)
            luminosityColor = QColor(0, 0, 0, 0)
        else:
            tintColor = QColor(255, 255, 255, 160)
            luminosityColor = QColor(255, 255, 255, 50)

        self.acrylicBrush.tintColor = tintColor
        self.acrylicBrush.luminosityColor = luminosityColor

    def _topMargin(self):
        return 6

    def _bottomMargin(self):
        return 6

    def setItemHeight(self, height: int):
        """ set the height of item """
        if height == self._itemHeight:
            return

        for i in range(1, self.count() - 1):
            item = self.item(i)
            if not self.itemWidget(item):
                item.setSizeHint(QSize(item.sizeHint().width(), height))

        self._itemHeight = height
        self.adjustSize()

    def addItem(self, item):
        return super().insertItem(self.count() - 1, item)

    def createPlaceholderItem(self, height=2):
        item = QListWidgetItem()
        item.setSizeHint(QSize(1, height))
        item.setFlags(Qt.ItemFlag.NoItemFlags)
        return item

    def clipPath(self):
        path = QPainterPath()
        path.addRoundedRect(QRectF(self.rect()).adjusted(0, 0, -2.5, -2.5), 8, 8)
        return path

    def paintEvent(self, e) -> None:
        painter = QPainter(self.viewport())
        painter.setRenderHints(QPainter.Antialiasing |
                               QPainter.SmoothPixmapTransform)

        self.acrylicBrush.clipPath = self.clipPath()
        self._updateAcrylicColor()
        self.acrylicBrush.paint()

        super().paintEvent(e)


class AcrylicMenuBase:

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def setUpMenu(self, view):
        self.hBoxLayout.removeWidget(self.view)
        self.view.deleteLater()

        self.view = view
        self.hBoxLayout.addWidget(self.view)

        self.setShadowEffect()

        self.view.itemClicked.connect(self._onItemClicked)
        self.view.itemEntered.connect(self._onItemEntered)

    def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
        p = MenuAnimationManager.make(self, aniType)._endPosition(pos)
        self.view.acrylicBrush.grabImage(QRect(p, self.layout().sizeHint()))
        super().exec(pos, ani, aniType)


class AcrylicMenu(AcrylicMenuBase, RoundMenu):
    """ Acrylic menu """

    def __init__(self, title="", parent=None):
        super().__init__(title, parent)
        self.setUpMenu(AcrylicMenuActionListWidget(self))

    def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
        return super().exec(pos, ani, aniType)


class AcrylicCompleterMenuActionListWidget(AcrylicMenuActionListWidget):

    def clipPath(self):
        path = QPainterPath()
        path.setFillRule(Qt.FillRule.WindingFill)
        path.addRoundedRect(QRectF(self.rect()).adjusted(1, 1, -2.5, -2.5), 8, 8)

        if self.property("dropDown"):
            path.addRect(1, 1, 11, 11)
            path.addRect(self.width() - 12, 1, 11, 11)
        else:
            path.addRect(1, self.height() - 11, 11, 11)
            path.addRect(self.width() - 12, self.height() - 11, 11, 11)

        return path


class AcrylicCompleterMenu(AcrylicMenuBase, CompleterMenu):
    """ Acrylic completer menu """

    def __init__(self, lineEdit: LineEdit):
        super().__init__(lineEdit)
        self.setUpMenu(AcrylicCompleterMenuActionListWidget(self))

        self.view.setObjectName('completerListWidget')
        self.view.setItemDelegate(IndicatorMenuItemDelegate())
        self.view.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        self.setItemHeight(33)

    def _onItemClicked(self, item):
        self._hideMenu(False)
        self._onCompletionItemSelected(item.text(), self.view.row(item)-1)

    def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
        return super().exec(pos, ani, aniType)

    def setItems(self, items):
        """ set completion items """
        self.view.clear()

        self.items = items

        QListWidget.addItem(self.view, self.view.createPlaceholderItem(self.view._topMargin()))
        self.view.addItems(items)

        for i in range(1, self.view.count()):
            item = self.view.item(i)
            item.setSizeHint(QSize(1, self.itemHeight))

        QListWidget.addItem(self.view, self.view.createPlaceholderItem(self.view._bottomMargin()))


class AcrylicLineEditMenu(AcrylicMenuBase, LineEditMenu):
    """ Acrylic line edit menu """

    def __init__(self, parent: QLineEdit):
        super().__init__(parent)
        self.setUpMenu(AcrylicMenuActionListWidget(self))

    def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
        return super().exec(pos, ani, aniType)


class AcrylicCheckableMenu(AcrylicMenuBase, CheckableMenu):
    """ Checkable menu """

    def __init__(self, title="", parent=None, indicatorType=MenuIndicatorType.CHECK):
        super().__init__(title, parent, indicatorType)
        self.setUpMenu(AcrylicMenuActionListWidget(self))
        self.view.setObjectName('checkableListWidget')

    def exec(self, pos, ani=True, aniType=MenuAnimationType.DROP_DOWN):
        return super().exec(pos, ani, aniType)


class AcrylicSystemTrayMenu(AcrylicMenu):
    """ System tray menu """

    def showEvent(self, e):
        super().showEvent(e)
        self.adjustPosition()
        self.view.acrylicBrush.grabImage(QRect(self.pos(), self.layout().sizeHint()))


class AcrylicCheckableSystemTrayMenu(AcrylicCheckableMenu):
    """ Checkable system tray menu """

    def showEvent(self, e):
        super().showEvent(e)
        self.adjustPosition()