from PySide6.QtCore import Qt
from PySide6.QtGui import QAction, QIcon, QGuiApplication
from PySide6.QtWidgets import QMenu, QMessageBox, QProgressBar, QMdiArea
from PySide6.QtWidgets import QLabel, QMainWindow
from sqlalchemy import Engine
from kontor_schema import KontorDB

from .comic_window import ComicWindow
from .media_window import MediaWindow
from .meta_data_window import MetaDataWindow
from .progress import ProgressUpdate
from .dialogs import ExportKontorDialog, ImportKontorDialog
from .worker import VideoDownloader


class MainWindow(QMainWindow):

    def __init__(self, engine: Engine, log):
        super().__init__()

        self.downloader = None
        self.tick = QIcon('res/tick.png')
        self.cross = QIcon('res/cross.png')
        self.import_icon = QIcon("res/application-import.png")
        self.export_icon = QIcon("res/application-export.png")
        self.circle_icon = QIcon("res/arrow-circle-double.png")

        self.data = []
        self.filter = {}
        self.kontor_db = KontorDB(engine, log)
        self.log = log
        self._subwindows = {}
        self.media_dir = "/data/media"
        self.dl_tool = "yt-dlp"

        self._setup_ui()

    def _setup_ui(self):
        self.setWindowTitle("Kontor")
        self.setMinimumSize(1200, 800)
        self._create_actions()
        self.mdi_area = QMdiArea()
        self.setCentralWidget(self.mdi_area)
        self.mdi_area.setObjectName('mdi_area')
        self.mdi_area.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        self.mdi_area.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAsNeeded)
        self._create_menubar()
        self._create_toolbars()
        self.status_progress = QProgressBar()
        self.progress_update = ProgressUpdate(self.status_progress)
        self._create_statusbar()
        center_point = QGuiApplication.screens()[0].geometry().center()
        self.move(center_point - self.frameGeometry().center())

    def _create_actions(self):
        self.newAction = QAction("&New", self)
        self.aboutAction = QAction("&Über...", self)
        self.aboutAction.triggered.connect(self.about)
        self.showComicWindow = QAction("&Comic Window", self)
        self.showComicWindow.triggered.connect(self.show_comic_window)
        self.showTyscWindow = QAction("TYSC Window", self)
        self.showMediaWindow = QAction("&Media Window", self)
        self.showMediaWindow.triggered.connect(self.show_media_window)
        self.showMetaDataWindow = QAction("Meta Data Window", self)
        self.showMetaDataWindow.triggered.connect(self.show_meta_data_window)
        self.importAction = QAction(self.import_icon, "&Import", self)
        self.importAction.triggered.connect(self.import_from_file)
        self.exportAction = QAction(self.export_icon, "&Export", self)
        self.exportAction.triggered.connect(self.export_to_file)
        self.refreshAction = QAction(self.circle_icon, "&Refresh", self)
        self.refreshAction.triggered.connect(self.refresh)
        self.updateTitleAction = QAction("&Update Titles", self)
        self.updateTitleAction.triggered.connect(self.update_title)
        self.downloadAction = QAction("&Download Videos", self)
        self.downloadAction.triggered.connect(self.start_download)
        self.checkFileAction = QAction("&Check files", self)
        self.checkFileAction.triggered.connect(self.check_files)
        self.exitAction = QAction("&Beenden", self)
        self.exitAction.setShortcut("Alt+F4")
        self.exitAction.triggered.connect(self.close)

    def _create_menubar(self):
        menu_bar = self.menuBar()
        # File menu
        file_menu = QMenu("&Datei")
        menu_bar.addMenu(file_menu)
        file_menu.addAction(self.exitAction)
        # Kontor menu
        kontor_menu = QMenu("&Kontor")
        menu_bar.addMenu(kontor_menu)
        kontor_menu.addAction(self.importAction)
        kontor_menu.addAction(self.exportAction)
        comic_menu = QMenu("&Comic")
        comic_menu.addAction(self.showComicWindow)
        tysc_menu = QMenu("&TradeYourSportCards")
        media_file_menu = QMenu("&MediaFile")
        media_file_menu.addAction(self.updateTitleAction)
        media_file_menu.addAction(self.downloadAction)
        media_file_menu.addAction(self.checkFileAction)
        kontor_menu.addMenu(comic_menu)
        kontor_menu.addMenu(tysc_menu)
        kontor_menu.addMenu(media_file_menu)
        window_menu = QMenu("&Window")
        layouts_menu = QMenu("&Layouts")
        window_menu.addMenu(layouts_menu)
        window_menu.addAction(self.showComicWindow)
        window_menu.addAction(self.showMediaWindow)
        window_menu.addAction(self.showMetaDataWindow)
        menu_bar.addMenu(window_menu)
        # Help menu
        help_menu = QMenu("&Hilfe")
        menu_bar.addMenu(help_menu)
        help_menu.addAction(self.aboutAction)

    def _create_toolbars(self):
        # Kontor toolbar
        kontor_tool_bar = self.addToolBar("Kontor")
        kontor_tool_bar.addAction(self.importAction)
        kontor_tool_bar.addAction(self.exportAction)
        kontor_tool_bar.addAction(self.refreshAction)

    def _create_statusbar(self):
        self.statusBar = self.statusBar()
        self.statusBar.showMessage("Kontor ready", 6000)
        self.status_label = QLabel("")
        self.status_progress.setEnabled(False)
        self.statusBar.addPermanentWidget(self.status_progress)

    def about(self):
        QMessageBox.about(self, "Über Kontor", "Python: 3.11\nKontor: 0.1.0")

    def show_comic_window(self):
        if 'comic' not in self._subwindows:
            comic = ComicWindow(self)
            comic.closed.connect(self.sub_window_closed)
            self._subwindows['comic'] = comic
            self.mdi_area.addSubWindow(comic)
            comic.show()
        else:
            comic = self._subwindows.pop('comic')
            comic.close()
            self.mdi_area.removeSubWindow(comic)

    def show_media_window(self):
        if 'media' not in self._subwindows:
            media = MediaWindow(self)
            media.closed.connect(self.sub_window_closed)
            self._subwindows['media'] = media
            self.mdi_area.addSubWindow(media)
            media.show()
        else:
            media = self._subwindows.pop('media')
            media.close()
            self.mdi_area.removeSubWindow(media)

    def show_meta_data_window(self):
        if 'meta_data' not in self._subwindows:
            meta_data = MetaDataWindow(self)
            meta_data.closed.connect(self.sub_window_closed)
            self._subwindows['meta_data'] = meta_data
            self.mdi_area.addSubWindow(meta_data)
            meta_data.show()
        else:
            meta_data = self._subwindows.pop('meta_data')
            meta_data.close()
            self.mdi_area.removeSubWindow(meta_data)

    def remove_sub_window(self, name: str):
        self.log.info("remove subwindow %s", name)
        if name in self._subwindows:
            window = self._subwindows.pop(name)
            window.close()
            self.mdi_area.removeSubWindow(window)

    def sub_window_closed(self):
        self.log.info("close subwindow")

    def import_from_file(self):
        import_dlg = ImportKontorDialog(self)
        if import_dlg.exec():
            print(f"import DB from file {import_dlg.file_name}")
            self.kontor_db.import_db(import_dlg.file_name)
        else:
            print("do nothing for import")

    def export_to_file(self):
        export_dlg = ExportKontorDialog(self, self.kontor_db)
        if export_dlg.exec():
            self.log.info(export_dlg.get_tables_to_export())
            self.log.info(f"export DB to {export_dlg.file_name}")
            self.statusBar.showMessage(f"export DB to {export_dlg.file_name}", 3000)
            self.kontor_db.export_db(export_dlg.current_export_type, export_dlg.file_name)
        else:
            self.statusBar.showMessage("Export cancelled", 3000)

    def update_title(self):
        self.log.info("update title for table MediaFile")
        self.statusBar.showMessage("update title for table MediaFile", 3000)
        self.status_progress.setEnabled(True)
        self.kontor_db.update_titles()
        self.status_progress.setEnabled(False)
        self.refresh()

    def start_download(self):
        self.status_progress.setEnabled(True)
        self.statusBar.showMessage("download videos for table MediaFile", 3000)
        self.downloader = VideoDownloader(self.kontor_db, self.log)
        self.downloader.setTotalProgress.connect(self.status_progress.setMaximum)
        self.downloader.setCurrentProgress.connect(self.downloadProgress)
        self.downloader.succeeded.connect(self.downloadSucceeded)
        self.downloader.finished.connect(self.downloadFinished)
        self.downloader.start()

    def downloadProgress(self, value: int):
        self.status_progress.setValue(value)
        self.refresh()

    def downloadSucceeded(self):
        self.status_progress.setValue(self.status_progress.maximum())
        self.statusBar.showMessage("Download succeeded", 3000)

    def downloadFinished(self):
        self.status_progress.setEnabled(False)
        del self.downloader

    def check_files(self):
        self.log.info("check files")
        self.statusBar.showMessage("check files for table MediaFile", 3000)
        self.kontor_db.check_files()

    def refresh(self):
        self.log.info("refresh")
        for (_, window) in self._subwindows.items():
            window.refresh()

    def update_status(self, message, timeout=3000):
        self.statusBar.showMessage(message, timeout=timeout)
