from PyQt5.QtCore import pyqtSignal, Qt, QSize
from PyQt5.QtGui import QFontDatabase
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QLabel, QHBoxLayout, QLayout, QGraphicsDropShadowEffect, QApplication

from config import config
from kit.component.kit_button import KitIconButton, KitButton
from kit.component.kit_overlay import KitOverlay


class KitPopupBase(QWidget):
    """
    弹窗要使用show打开
    """

    def __init__(self):
        super(KitPopupBase, self).__init__()
        self._parent = None

        self.__init_widget()
        self.__init_slot()
        self.__init_qss()

    def __init_widget(self):
        shadow = QGraphicsDropShadowEffect()
        shadow.setXOffset(0)
        shadow.setYOffset(0)
        shadow.setBlurRadius(4)
        shadow.setColor(Qt.black)
        self.setGraphicsEffect(shadow)
        self.hide()

    def __init_slot(self):
        pass

    def __init_qss(self):
        self.setAttribute(Qt.WA_StyledBackground, True)

    def init_parent(self):
        self.focusWidget()
        window = QApplication.activeWindow()
        if window is not None:
            self._parent = window
            self.setParent(window)

    def show(self):
        self.init_parent()
        super(KitPopupBase, self).show()


class KitPopup(KitPopupBase):

    CloseOnClicked = 0
    CloseOnEscape = 1

    def __init__(self):
        super(KitPopup, self).__init__()

        self.close_policy = KitPopup.CloseOnClicked
        self.overlay = KitOverlay()

        self.__init_widget()
        self.__init_slot()
        self.__init_qss()

    def __init_widget(self):
        pass

    def __init_slot(self):
        self.overlay.clicked.connect(lambda: self.close() if self.close_policy == KitPopup.CloseOnClicked else None)
        self.overlay.resized.connect(self.__fresh_position)

    def __init_qss(self):
        self.setAttribute(Qt.WA_StyledBackground, True)

    def __fresh_position(self):
        self.move((self.overlay.width() - self.width()) // 2, (self.overlay.height() - self.height()) // 2)
        self.update()

    def setClosePolicy(self, policy: int):
        self.close_policy = policy
        self.overlay.setClosePolicy(policy)

    def show(self):
        self.overlay.show()
        self.raise_()
        super().show()

    def close(self):
        super().close()
        self.overlay.close()


class KitModal(KitPopup):
    """
    可以用来做一个单例。
    """

    confirm = pyqtSignal()
    cancel = pyqtSignal()

    def __init__(self, title: str = None, content_layout: QLayout = None, bottom_buttons_layout: QLayout = None):
        super(KitModal, self).__init__()

        self.title = title
        self.header_layout = QHBoxLayout()
        self.content_layout = QVBoxLayout()
        self.bottom_buttons_layout = QHBoxLayout()

        self.__init_widget()
        self.__init_slot()
        self.__init_qss()

        self.setTitle(self.title)
        self.setContentLayout(content_layout)
        self.setBottomButtonLayout(bottom_buttons_layout)

    def __init_widget(self):
        self.setClosePolicy(KitPopup.CloseOnEscape)

        self.title_label = QLabel()
        self.title_label.setObjectName('modal_title')
        self.header_widget = QWidget()
        self.header_widget.setObjectName('modal_header')
        self.header_widget.setFixedHeight(40)
        self.header_widget.setLayout(self.header_layout)
        self.header_layout.addWidget(self.title_label, alignment=Qt.AlignHCenter)

        self.content_widget = QWidget()
        self.content_widget.setObjectName('modal_content')
        self.content_widget.setLayout(self.content_layout)
        self.bottom_button_widget = QWidget()
        self.bottom_button_widget.setObjectName('modal_bottom')
        self.bottom_button_widget.setLayout(self.bottom_buttons_layout)

        self.v_layout = QVBoxLayout()
        self.v_layout.addWidget(self.header_widget)
        self.v_layout.addWidget(self.content_widget, 1)
        self.v_layout.addWidget(self.bottom_button_widget)

        self.close_button = KitIconButton('\ue634')
        self.close_button.setObjectName('modal_close_btn')
        self.close_button.setShape(KitButton.Round)
        self.close_button.setType(KitButton.Text)
        self.close_button.setShadow(False)
        self.close_button.setParent(self.header_widget)

        self.default_button_layout = QHBoxLayout()
        self.confirm_btn = KitButton("确定")
        self.cancel_btn = KitButton("取消")
        self.cancel_btn.setType(KitButton.Text)
        self.default_button_layout.addStretch(1)
        self.default_button_layout.addWidget(self.cancel_btn)
        self.default_button_layout.addWidget(self.confirm_btn)

        self.setLayout(self.v_layout)

    def __init_slot(self):
        self.close_button.clicked.connect(self.close)
        self.confirm_btn.clicked.connect(self.confirm.emit)
        self.cancel_btn.clicked.connect(self.cancel.emit)

    def __init_qss(self):
        self.setAttribute(Qt.WA_StyledBackground, True)

    def __fresh_close_btn_position(self):
        self.close_button.move(self.header_widget.rect().right() - self.close_button.width(), 0)

    def setTitle(self, title: str):
        self.title = title
        self.title_label.setText(title)

    def setContent(self, content: str):
        layout = QVBoxLayout()
        label = QLabel(content)
        label.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
        layout.addWidget(label)
        self.setContentLayout(layout)

    def setHeaderLayout(self, layout):
        while self.header_layout.count() > 0:
            self.header_layout.removeItem(self.header_layout.takeAt(0))
        if layout is None:
            layout = QHBoxLayout()
        self.header_layout.addLayout(layout)

    def setContentLayout(self, layout):
        while self.content_layout.count() > 0:
            self.content_layout.removeItem(self.content_layout.takeAt(0))
        if layout is None:
            layout = QVBoxLayout()
        self.content_layout.addLayout(layout)

    def setDefaultBottomButton(self):
        self.setNoBottomButton()
        if not self.cancel_btn.isVisible():
            self.cancel_btn.setParent(self.bottom_button_widget)
            self.cancel_btn.setVisible(True)
        self.bottom_buttons_layout.addLayout(self.default_button_layout)

    def setBottomButtonLayout(self, layout):
        self.setNoBottomButton()
        self.bottom_buttons_layout.addLayout(layout)

    def setNoCloseButton(self):
        self.close_button.hide()

    def setNoBottomButton(self):
        while self.bottom_buttons_layout.count() > 0:
            self.bottom_buttons_layout.removeItem(self.bottom_buttons_layout.takeAt(0))

    def setOneBottomButton(self):
        self.cancel_btn.setVisible(False)

    def resizeEvent(self, a0):
        super().resizeEvent(a0)
        self.__fresh_close_btn_position()

    @classmethod
    def setModalNotice(cls, title: str = None, content: str = None):
        modal_notice = cls(title)
        modal_notice.setContent(content)
        modal_notice.setNoBottomButton()
        modal_notice.adjustSize()
        modal_notice.show()
        return modal_notice

    @classmethod
    def setModalDialog(cls, title: str = None, content: str = None, confirm=None, cancel=None):
        modal_dialog = cls(title)
        modal_dialog.setContent(content)
        modal_dialog.confirm.connect(confirm)
        modal_dialog.cancel.connect(cancel)
        modal_dialog.setDefaultBottomButton()
        modal_dialog.adjustSize()
        modal_dialog.show()
        return modal_dialog


if __name__ == "__main__":
    import sys
    QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps)

    app = QApplication(sys.argv)

    fontId = QFontDatabase.addApplicationFont("assets/font/iconfont.ttf")
    fontName = QFontDatabase.applicationFontFamilies(fontId)[0]
    qss = config.init_qss()
    app.setStyleSheet(qss)

    main = QWidget()
    main_layout = QVBoxLayout()
    main.resize(600, 800)
    main.setLayout(main_layout)

    modal = KitModal("123")
    modal.confirm.connect(lambda: print("confirm"))
    modal.cancel.connect(lambda: modal.close())
    modal.setOneBottomButton()
    modal.setNoBottomButton()
    modal.setDefaultBottomButton()

    btn = KitButton('show modal', parent=main)
    btn.clicked.connect(lambda: modal.show())
    main_layout.addWidget(btn)

    content_layout = QVBoxLayout()
    content_label = QLabel("这是弹窗内容")
    content_layout.addWidget(content_label)

    btn2 = KitButton('change modal content')
    btn2.clicked.connect(lambda: modal.setContentLayout(content_layout))
    main_layout.addWidget(btn2)

    btn3 = KitButton('show modal notice')
    btn3.clicked.connect(lambda: KitModal.setModalNotice("提示", "这是一个提示"))
    main_layout.addWidget(btn3)

    btn4 = KitButton('show modal dialog')
    btn4.clicked.connect(lambda: KitModal.setModalDialog("提示", "这是一个提示", lambda: print("confirm"), lambda: print("cancel")))
    main_layout.addWidget(btn4)

    main.show()

    sys.exit(app.exec_())
