from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, pyqtSignal

from base.base import BaseMainWindow, Settings
from gui.start_widget import (CustomMenuBar, CustomStatusBar,
                               StartWidget, CustomTabWidget,
                                 RaportWidget, SeekingWidget,
                                 ClientAnalyzerWidget)
from gui.settings_window import SystemSettings, OperatorSettings, FilterSettings
from gui.report_gui import ReportSettings


# FIXME: При отркытии RaportMode все прочитанные трейсы должны удаляться, но они открываются...
class MainWindow(BaseMainWindow):

    signal_mode = pyqtSignal(int)
    signal_settings = pyqtSignal(Settings)
    signal_replot_all = pyqtSignal()
    signal_open_file = pyqtSignal(str)
    signal_save_file = pyqtSignal(list)
    signal_open_dir = pyqtSignal(str)
    signal_TCW_for_client = pyqtSignal()

    def __init__(self) -> None:
        super().__init__()
        self._init_startUI()

    def show_plot_tabs(self, plot_widgets: list[QtWidgets.QWidget]) -> None:
        for plot_widget in plot_widgets:
            self._tab_widget.create_tab(plot_widget)

        tab_count = self._tab_widget.count()
        if tab_count > 10:
            for i in range(0, tab_count-10):
                self._tab_widget.close_tab(i)

        self.status_widget.set_note("Done!")
        self.status_widget.set_progress(100)

    def keyPressEvent(self, a0) -> None:
        if a0.key() == Qt.Key_F5:
            tab_count = self._tab_widget.count()
            for i in range(0, tab_count):
                self._tab_widget.close_tab(i)
    
    def closeEvent(self, a0):
        self.operSettings.close()
        self.sysSettings.close()
        self.repSettings.close()
        super().closeEvent(a0)

    def _init_startUI(self) -> None:
        self._init_settings()
        self._init_menu()
        self._init_status_bar()
        start_widget = StartWidget()
        start_widget.seeking_mode_btn.clicked.connect(self._init_seekingUI)
        start_widget.raport_mode_btn.clicked.connect(self._init_raportUI)
        start_widget.client_mode_btn.clicked.connect(self._init_client_UI)
        self.setCentralWidget(start_widget.get_widget())
        
    def _init_settings(self) -> None:
        self.sysSettings = SystemSettings("params/system_params.json", 'System', self._upd_settings)
        self.repSettings = ReportSettings()
        self.operSettings = OperatorSettings("params/operator_params.json", 'Operator', self._upd_settings)
        self.filterSettings = FilterSettings("params/filter_params.json", "Client filter", self._upd_settings)

    def _init_menu(self) -> None:
        self.menu = CustomMenuBar(self.sysSettings, self.repSettings, self.operSettings, self.filterSettings)
        self.menu.seeking_action.triggered.connect(self._init_seekingUI)
        self.menu.raport_action.triggered.connect(self._init_raportUI)
        self.menu.client_action.triggered.connect(self._init_client_UI)
        self.menu.view_settings.triggered.connect(lambda: self._on_tab_changed(0))
        self.menu.setup(self)

    def _init_status_bar(self) -> None:
        self.status_widget = CustomStatusBar()
        self.statusBar().addPermanentWidget(self.status_widget.get_widget(), 1)

    def _init_tab_widget(self) -> None:
        self._tab_widget = CustomTabWidget()
        self._tab_widget.currentChanged.connect(self._on_tab_changed)

    def _on_tab_changed(self, index):
        tab = self._tab_widget.currentWidget() 
        if tab:
            reg_items = tab.property("reg_items")
            curve_items = tab.property("curve_items")
            qt_items = tab.property("qt_items")
            self.repSettings.build(index, reg_items, curve_items, qt_items)

    def _clear(self) -> None:
        if self.layout() is not None:
            while self.layout().count():
                child = self.layout().takeAt(0)
                if child.widget() is not None:
                    child.widget().deleteLater()
        self._init_tab_widget()
        self._transfer_settings()

    def _init_raportUI(self) -> None:
        self._clear()
        self._set_mode(1)
        raport_widget = RaportWidget(self._tab_widget)
        raport_widget.open_file_btn.clicked.connect(self._open_file)
        raport_widget.save_screen_btn.clicked.connect(self._save_plots)
        self.setCentralWidget(raport_widget.get_widget())
        
    def _init_seekingUI(self) -> None:
        self._clear()
        self._set_mode(2)
        seeking_widget = SeekingWidget(self._tab_widget)
        self.setCentralWidget(seeking_widget.get_widget())

    def _init_client_UI(self) -> None:
        self._clear()
        self._set_mode(3)
        client_widget = ClientAnalyzerWidget(self._tab_widget)
        #TODO: привязать действия к кнопкам
        client_widget.open_folder_btn.clicked.connect(self._open_folder)
        client_widget.save_screen_btn.clicked.connect(self._save_plots)
        client_widget.build_TCW_btn.clicked.connect(self._build_TCW_for_client)
        self.setCentralWidget(client_widget.get_widget())
        
    def _build_TCW_for_client(self):
        self.signal_TCW_for_client.emit()
        
    def _set_mode(self, num:int) -> None:
        match num:
            case 1:
                self.status_widget.set_mode("raport mode")
                self.signal_mode.emit(1)
            case 2:
                self.status_widget.set_mode("online mode")
                self.signal_mode.emit(2)
            case 3:
                self.status_widget.set_mode("client processor mode")
                self.signal_mode.emit(3)

    def _transfer_settings(self) -> None:
        settings = Settings()
        settings.system = self.sysSettings.getParams()
        settings.operator = self.operSettings.getParams()
        settings.filter = self.filterSettings.getParams()
        self.signal_settings.emit(settings)
        
    def _upd_settings(self) -> None:
        self._transfer_settings()
        if self.status_widget._mode_label.text():
            self._tab_widget.clear()
            self.signal_replot_all.emit()
    
    def _open_file(self) -> None:
        CSV_path, _ = QtWidgets.QFileDialog.getOpenFileName(self,"Select csv file", "", "CSV Files (*.csv)")
        if CSV_path:
            self.signal_open_file.emit(CSV_path)
    
    def _open_folder(self) -> None:
        dir_path = QtWidgets.QFileDialog.getExistingDirectory(self,"Select folder with traces","",
                                                              QtWidgets.QFileDialog.ShowDirsOnly | QtWidgets.QFileDialog.DontResolveSymlinks)
        if dir_path:
            self.signal_open_dir.emit(dir_path)

    def _save_plots(self) -> None:
        filepath, _ = QtWidgets.QFileDialog.getSaveFileName(self, "Save file", "", "Image Files (*.png *.jpeg)")
        tab = self._tab_widget.currentWidget()
        if tab: self.signal_save_file.emit([filepath, tab])

        # TODO: эта реализация работает, но для пользователя будет больно каждый раз писать имена и расширения
        #  сохраняемых файлов, не кажется? Можно сделать, как показано ниже, тогда файлам будет назначаться имя
        #  по умолчанию и с расширением. ХЗ правда, как эта форма на винде будет выглядеть - надо проверить.
        #  ========================================================
        #  dialog = QFileDialog()
        #  dialog.setOptions(QFileDialog.DontUseNativeDialog)
        #  dialog.setFileMode(QFileDialog.AnyFile)
        #  dialog.setAcceptMode(QFileDialog.AcceptSave)
        #  dialog.setDirectory(os.getcwd())
        #  dialog.selectFile("untitled.txt")
        #  dialog.exec_()
        #  if dialog.accepted:
        #      # emit signal to save file
        #      ...
        #  ========================================================
        
           
