import os
import sys
import time
import subprocess
import webbrowser
from typing import Tuple, List

import qdarkstyle
from qtpy.QtCore import QPoint, QRectF
from qtpy.QtGui import QMouseEvent, QPainter, QLinearGradient
from qtpy.QtGui import QCloseEvent
from qtpy.QtCore import Signal, Qt, QUrl, QPropertyAnimation
from qtpy.QtWidgets import QApplication, QListWidgetItem, QWizard, QHeaderView, QMessageBox
from qtpy.QtWebEngineWidgets import *
from qtpy.QtWidgets import QWidget, QDesktopWidget, QFileDialog, QApplication, QDialog
from pmgwidgets import PMGPanel

from pyminer2.ui.base.option import Ui_Form as Option_Ui_Form
from pyminer2.ui.base.appStore import Ui_Form as appStore_Ui_Form
from pyminer2.ui.base.aboutMe import Ui_Form as About_Ui_Form
from pyminer2.ui.base.project_wizard import Ui_Wizard as Project_Ui_Form
from pyminer2.ui.base.first_form import Ui_Form as first_Ui_Form

from pyminer2.globals import openURL, get_main_window

from pyminer2.features.io.settings import Settings
from pyminer2.extensions.extensionlib.extension_lib import extension_lib


class OptionForm(QDialog, Option_Ui_Form):
    """
    打开"选项"窗口
    """
    signal_settings_changed = Signal()

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setupUi(self)
        self.center()
        self.page_format.setEnabled(False)
        self.page_appearance.setEnabled(False)

        self.setup_ui()

        # 通过combobox控件选择窗口风格
        self.comboBox_theme.activated[str].connect(self.slot_theme_changed)

        self.setting = dict()

        self.listWidget.currentRowChanged.connect(self.option_change)
        self.toolButton_workspace.clicked.connect(self.slot_change_workspace)
        self.toolButton_output.clicked.connect(self.slot_change_output)
        self.pushButton_cancel.clicked.connect(self.close)
        self.pushButton_ok.clicked.connect(self.close)
        self.pushButton_help.clicked.connect(self.get_help)

    def setup_ui(self):
        self.comboBox_9.setEnabled(False)
        self.comboBox_8.setEnabled(False)
        self.checkBox_2.setEnabled(False)
        self.checkBox_minitray.setEnabled(False)

    def add_settings_panel(self, text: str, settings_content: List):
        settings_widget = PMGPanel(views=settings_content)
        self.signal_settings_changed.connect(settings_widget.emit_settings_changed_signal)
        self.stackedWidget.addWidget(settings_widget)
        self.listWidget.addItem(QListWidgetItem(text))
        return settings_widget

    def add_page(self, text, page: QWidget):
        self.stackedWidget.addWidget(page)
        self.listWidget.addItem(QListWidgetItem(text))
        return page

    def closeEvent(self, a0: 'QCloseEvent') -> None:
        super(OptionForm, self).closeEvent(a0)
        self.refresh_settings()

    def keyPressEvent(self, e):
        """
        按键盘Escape退出当前窗口
        @param e:
        """
        if e.key() == Qt.Key_Escape:
            self.close()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def option_change(self, i):
        self.stackedWidget.setCurrentIndex(i)

    def slot_theme_changed(self, style):
        """
        在主题颜色改变时触发的回调
        :param style:
        :return:
        """
        from pyminer2.features.io.settings import load_theme
        load_theme(style)

        Settings.get_instance()['theme'] = self.comboBox_theme.currentText()
        # print(Settings.get_instance()['theme'])
        from pyminer2.globals import get_main_window
        get_main_window().settings_changed_signal.emit()
        # get_main_window().on_settings_changed()
        # self.signal_settings_changed.emit()

    def slot_change_workspace(self):
        directory = QFileDialog.getExistingDirectory(self, "选择工作路径位置", directory=Settings.get_instance()['work_dir'])
        if not directory == '':
            self.lineEdit_worksapce.setText(directory)

    def slot_change_output(self):
        directory = QFileDialog.getExistingDirectory(self, "选择输出文件夹位置", os.path.expanduser('~'))
        self.lineEdit_output.setText(directory)

    def load_settings(self):
        """
        在show()之前调用这个方法
        从而每次重新显示的时候都可以刷新数据。
        :return:
        """
        settings = Settings.get_instance()
        if settings.get('theme') is not None:
            for i in range(self.comboBox_theme.count()):
                if self.comboBox_theme.itemText(i) == settings['theme']:
                    self.comboBox_theme.setCurrentIndex(i)
        self.lineEdit_worksapce.setText(settings['work_dir'])

    def refresh_settings(self):
        """
        窗口关闭时，调用此方法，刷新主界面设置项。
        :return:
        """
        settings = Settings.get_instance()
        settings['work_dir'] = self.lineEdit_worksapce.text()
        settings['theme'] = self.comboBox_theme.currentText()
        from pyminer2.globals import get_main_window
        get_main_window().on_settings_changed()
        self.signal_settings_changed.emit()

    def show(self):
        """
        重写此方法，在显示之前重新加载一遍设置。
        :return:
        """
        self.load_settings()
        super(OptionForm, self).show()

    def exec_(self):
        """
        继承exec_方法。
        :return:
        """
        self.load_settings()
        super(OptionForm, self).exec_()

    def get_help(self):
        webbrowser.open('https://gitee.com/py2cn/pyminer/wikis/%E9%85%8D%E7%BD%AEPyMiner?sort_id=3263840')


class AppstoreForm(QWidget, appStore_Ui_Form):
    def __init__(self):
        super(AppstoreForm, self).__init__()
        self.setupUi(self)
        self.center()

        self.browser = QWebEngineView()
        # 加载外部的web界面
        self.browser.load(QUrl('https://chrome.zzzmh.cn/index#ext'))
        self.horizontalLayout_2.addWidget(self.browser)

        self.toolButton_help.clicked.connect(self.main_help_display)

    def keyPressEvent(self, e):
        """
        按键盘Escape退出当前窗口
        @param e:
        """
        if e.key() == Qt.Key_Escape:
            self.close()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def main_help_display(self):
        """
        打开帮助页面
        """
        try:
            webbrowser.get('chrome').open_new_tab("http://www.pyminer.com")
        except Exception as e:
            webbrowser.open_new_tab("http://www.pyminer.com")


class AboutForm(QWidget, About_Ui_Form):
    def __init__(self):
        super(AboutForm, self).__init__()
        self.setupUi(self)
        self.center()

        self.main_about_display()

    def keyPressEvent(self, e):
        """
        按键盘Escape退出当前窗口
        @param e:
        """
        if e.key() == Qt.Key_Escape:
            self.close()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def main_about_display(self):
        """
        打开关于页面
        """
        import platform
        python_info = 'Python版本: ' + platform.python_version() + ' ' + platform.python_compiler()
        system_info = '系统信息: ' + platform.platform() + ' ' + platform.architecture()[0]
        cpu_info = 'CPU信息: ' + platform.processor()
        self.feedback.setPlainText(python_info + '\n' + system_info + '\n' + cpu_info)


class ProjectWizardForm(QWizard, Project_Ui_Form):
    """
    新建项目引导窗口
    """

    def __init__(self,parent=None):
        super(ProjectWizardForm, self).__init__(parent=None)
        self.setupUi(self)
        self.center()
        self.default_setting()
        self.init()

    def init(self):
        # 初始化项目路径
        project_name = self.projectNameLineEdit.text()
        workspace_dir = os.path.join(os.path.expanduser('~'), 'PyMiner_workspace', project_name)
        file_dir = os.path.join(os.path.expanduser('~'), 'PyMiner_workspace', project_name, 'main.py')
        self.projectDirectoryEditLine.setText(workspace_dir)
        self.absoluteDirectoryEditLine.setText(file_dir)

        # 浏览按钮触发事件
        self.toolButton.clicked.connect(self.getProjectDirectory)
        # 向导界面finish按钮按下后触发的事件
        self.button(QWizard.FinishButton).clicked.connect(self.finishWizard)
        # 项目名称框text发生改变时触发的事件
        self.projectNameLineEdit.textChanged.connect(self.projectNameLineEditTextChange)
        # 选择不同项目类型时下方展示不同的类型描述
        self.file_list.itemClicked.connect(self.fileListItemClicked)

    def getProjectDirectory(self):
        """
        浏览按钮触发的事件，选择文件夹
        :return:
        """
        directory_name = QFileDialog.getExistingDirectory(None, "请选择文件夹路径", "./")
        self.projectDirectoryEditLine.setText(directory_name)
        project_name = self.projectNameLineEdit.text()
        if project_name != "":
            self.absoluteDirectoryEditLine.setText(directory_name + "/" + project_name)
        else:
            self.absoluteDirectoryEditLine.setText(directory_name)

    def finishWizard(self):
        """
        完成项目创建向导后做的动作，文件夹不存在时创建路径并创建空的main.py文件，文件存在时只创建main.py，然后在主窗口中打开
        :return:
        """
        import os
        file_path = self.absoluteDirectoryEditLine.text()
        if os.path.exists(file_path):
            print('文件已存在')  # 创建空文件
        else:
            current_project_type = self.file_list.item(self.file_list.currentRow()).text()
            if current_project_type == "Python-Empty":  # 创建空项目
                with open(file_path, "w") as f:
                    f.write('')
            elif current_project_type == "Python-Template-Basic":  # 创建base template项目
                with open(file_path, "w") as f:
                    f.write("""#--coding:utf-8--

            if __name__ == '__main__':
            #  Create your codes here
            """)
            elif current_project_type == "Python-Template-Plot":  # 创建plot template项目
                with open(file_path, "w") as f:
                    f.write("""#--coding:utf-8--
            import matplotlib.pyplot as plt
            import numpy as np

            def demoTemplate():
                x = np.linspace(0,5,200)
                y1 = x + 1
                y2 = x -1
                plt.figure()
                #### 去边框
                ax = plt.axes()
                ax.spines['top'].set_visible(False)
                ax.spines['right'].set_visible(False)
                #### 关闭坐标轴//就剩下中间的绘图区，坐标轴连带标签都去掉了
                #### 网格设置
                plt.grid(axis="both",linestyle='-.',c='b')
                #### 绘图
                plt.plot(x,y1,'c--')
                plt.plot(x,y2,'r-.')
                plt.text(1,0.5,"text")
                #### legend
                plt.legend(["y1","y2"])
                #### 标签
                plt.xlabel("xlabel")
                plt.ylabel("ylabel")
                plt.title("title")
                plt.show()

            if __name__ == '__main__':
                demoTemplate()
            """)
            elif current_project_type == "Python-Template-PyQt":  # 创建pyqt template项目
                with open(file_path, "w") as f:
                    f.write("""#--coding:utf-8--
            import sys
            from PyQt5.QtWidgets import QApplication, QDialog

            from pyqt_template import Ui_PyQtTemplate


            class CallPyQtTemplate(QDialog, Ui_PyQtTemplate):
                def __init__(self):
                    super(CallPyQtTemplate, self).__init__()
                    self.setupUi(self)


            if __name__ == '__main__':
                app = QApplication(sys.argv)
                form = CallPyQtTemplate()
                form.show()
                sys.exit(app.exec())
            """)
            project_path=self.projectDirectoryEditLine.text()
            extension_lib.Program.set_work_dir(project_path)  # 在文件树区域打开新建项目


    def projectNameLineEditTextChange(self):
        """
        项目名称发生改变时同步改变绝对路径
        Returns
        -------

        """
        project_name = self.projectNameLineEdit.text()
        absolute_directory = self.absoluteDirectoryEditLine.text()
        # 将文件路径按照/分割成列表，然后把最后一个元素也就是项目名称pop()移出列表，最后再拼接成完整的路径
        absolute_directory_list = absolute_directory.split("/")
        absolute_directory_list.pop()
        if absolute_directory != "":
            self.absoluteDirectoryEditLine.setText("/".join(absolute_directory_list) + "/" + project_name)

    def fileListItemClicked(self):
        current_project_type = self.file_list.item(self.file_list.currentRow()).text()
        if current_project_type == "Python-Empty":
            self.plainTextEdit.setPlainText("Create a Python Project containing an Empty main.py.")
        elif current_project_type == "Python-Template-Basic":
            self.plainTextEdit.setPlainText("Create a Python Project containing a Base Template main.py.")
        elif current_project_type == "Python-Template-Plot":
            self.plainTextEdit.setPlainText("Create a Python Project containing a Plot Template main.py.")
        elif current_project_type == "Python-Template-PyQt":
            self.plainTextEdit.setPlainText("Create a Python Project containing a PyQt Template main.py.")

    def keyPressEvent(self, e):
        """
        按键盘Escape退出当前窗口
        @param e:
        """
        if e.key() == Qt.Key_Escape:
            self.close()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def default_setting(self):
        item = self.file_list.item(1)
        item.setSelected(True)


class FirstForm(QDialog, first_Ui_Form):
    """
    快速操作窗口
    """

    def __init__(self, parent=None):
        super(FirstForm, self).__init__(parent)
        self.setupUi(self)
        self.center()
        self.setWindowOpacity(0.95)
        self.setWindowTitle(self.tr('Quick Start'))
        # self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Popup)  # 无边框、弹出式
        self.animation = None
        # self.setStyleSheet("border-radius:10px;border:none;")
        # self.setAttribute(Qt.WA_TranslucentBackground)

        # 绑定事件
        self.btn_open_python.clicked.connect(self.open_script)
        self.btn_manual.clicked.connect(self.open_manual)
        self.btn_website.clicked.connect(self.open_website)
        self.btn_source.clicked.connect(self.open_source)
        self.btn_member.clicked.connect(self.open_member)
        self.btn_donate.clicked.connect(self.open_donate)

        self.btn_open_csv.clicked.connect(self.open_csv)
        self.btn_open_excel.clicked.connect(self.open_excel)
        self.btn_open_matlab.clicked.connect(self.open_matlab)
        self.btn_open_folder.clicked.connect(self.open_folder)

    def closeEvent(self, event):
        if self.animation is None:
            self.animation = QPropertyAnimation(self, b'windowOpacity', self.parent())
            # self.animation.setPropertyName(b'windowOpacity')
            self.animation.setDuration(200)
            self.animation.setStartValue(self.windowOpacity())
            self.animation.setEndValue(0)
            self.animation.finished.connect(self.close)
            self.animation.start()
            event.ignore()

    def mouseMoveEvent(self, e: QMouseEvent):  # 重写移动事件
        self._endPos = e.pos() - self._startPos
        self.move(self.pos() + self._endPos)
        super(FirstForm, self).mouseMoveEvent(e)

    def mousePressEvent(self, e: QMouseEvent):
        if e.button() == Qt.LeftButton:
            self._isTracking = True
            self._startPos = QPoint(e.x(), e.y())
        super(FirstForm, self).mousePressEvent(e)

    def mouseReleaseEvent(self, e: QMouseEvent):
        super(FirstForm, self).mouseReleaseEvent(e)
        if e.button() == Qt.LeftButton:
            self._isTracking = False
            self._startPos = None
            self._endPos = None

    def keyPressEvent(self, e):
        """
        按键盘Escape退出当前窗口
        @param e:
        """
        super(FirstForm, self).keyPressEvent(e)
        if e.key() == Qt.Key_Escape:
            self.close()

    def center(self):
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def open_script(self):
        user_home = os.path.expanduser('~')
        file_name, filetype = QFileDialog.getOpenFileName(self, "选取文件", user_home, "Python Files (*.py);;All Files (*)")
        self.hide()
        extension_lib.get_interface('code_editor').open_script(file_name)
        self.close()

    def open_manual(self):
        """
        打开快速入门
        :return:
        """
        openURL("https://gitee.com/py2cn/pyminer/wikis/%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B?sort_id=3137860")

    def open_website(self):
        """
        打开快速入门
        :return:
        """
        openURL("http://www.pyminer.com")

    def open_source(self):
        """
        打开快速入门
        :return:
        """
        openURL("https://gitee.com/py2cn/pyminer")

    def open_member(self):
        """
        打开 ‘加入我们’ 页面
        :return:
        """
        openURL("https://gitee.com/py2cn/pyminer/wikis/%E8%81%94%E7%B3%BB%E6%88%91%E4%BB%AC?sort_id=2761039")

    def open_donate(self):
        """
        打开 ‘捐赠’ 页面
        :return:
        """
        openURL("https://gitee.com/py2cn/pyminer/wikis/%E6%8D%90%E8%B5%A0?sort_id=2925146")

    def open_csv(self):
        """
        调用主程序打开csv到工作区间
        :return:
        """
        self.hide()
        extension_lib.get_interface('dataio').show_import_file_dialog('csv', '')
        self.close()

    def open_excel(self):
        """
        调用主程序打开excel到工作区间
        :return:
        """
        self.hide()
        extension_lib.get_interface('dataio').show_import_file_dialog('excel', '')
        self.close()

    def open_matlab(self):
        """
        调用主程序打开matlab到工作区间
        :return:
        """
        self.hide()
        extension_lib.get_interface('dataio').show_import_file_dialog('matlab', '')
        # get_main_window().process_file('matlab')
        self.close()

    def open_folder(self):
        user_home = os.path.expanduser('~')
        project_path = QFileDialog.getExistingDirectory(self, "选取文件夹", user_home)
        self.hide()
        extension_lib.Program.set_work_dir(project_path)
        self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    # form = FirstForm()
    form = ProjectWizardForm()
    form.show()
    sys.exit(app.exec_())
