from Qt import QtWidgets, QtCore

import sync_job
import login_dialog
import subprocess
import utils
import os
import logging
log = logging.getLogger("wizart_desktop")


INTERVAL_IN_MIN = 30
INTERVAL_IN_MS = INTERVAL_IN_MIN * 60 * 1000
SUCCESSFUL = 0


class ActionsTab(QtWidgets.QWidget):

    FTP_BTN_CAPTION = "Data Sync"
    FTP_BTN_CAPTION_DOWNLOAD = "Data Sync Download"
    FTP_BTN_CAPTION_UPLOAD = "Data Sync Upload"
    FTP_BTN_CAPTION_DOWNLOAD_CONFIG = "Data Sync Download Config"
    FTP_BTN_CAPTION_CANCEL = "Cancel"

    def __init__(self, app, parent=None):
        super(ActionsTab, self).__init__(parent)
        self.app = app
        self.setObjectName("actions")
        self.setLayout(QtWidgets.QVBoxLayout())
        self.sync_job_thread = sync_job.SyncJobThread()

        self.ftp_sync_btn = QtWidgets.QPushButton(self.FTP_BTN_CAPTION)

        self.ftp_sync_menu = QtWidgets.QMenu()
        #self.ftp_sync_menu.addAction(self.FTP_BTN_CAPTION_DOWNLOAD_CONFIG, self.ftp_update_config)
        self.ftp_sync_menu.addAction(
            self.FTP_BTN_CAPTION_DOWNLOAD,
            lambda: self.launch_sync(utils.SYNC_MODE_DOWNLOAD),
        )
        self.ftp_sync_menu.addAction(
            self.FTP_BTN_CAPTION_UPLOAD,
            lambda: self.launch_sync(utils.SYNC_MODE_UPLOAD),
        )
        self.ftp_sync_btn.setMenu(self.ftp_sync_menu)

        self.sync_job_thread.finished.connect(self.ftp_sync_finish)

        self.ftp_sync_btn.released.connect(self.ftp_sync_cancel)
        QtWidgets.QApplication.instance().aboutToQuit.connect(lambda: self.sync_job_thread.kill_job())

        self.set_sync_folder_btn = QtWidgets.QPushButton("Set Studio Root Folder")
        self.ftp_login_btn = QtWidgets.QPushButton("Set Data Sync Login/Password")
        self.ftp_login_btn.released.connect(self.set_ftp_credentials)
        self.set_sync_folder_btn.released.connect(self.set_sync_folder)
        self.layout().addWidget(self.set_sync_folder_btn)

        self.layout().addWidget(self.set_sync_folder_btn)
        self.layout().addWidget(self.ftp_login_btn)
        self.layout().addWidget(self.ftp_sync_btn)

        group_box = QtWidgets.QGroupBox("Work Area")
        group_box.setAlignment(QtCore.Qt.AlignHCenter)
        self.open_folder_btn = QtWidgets.QPushButton("Open Folder in Explorer")
        self.open_folder_btn.released.connect(self.open_work_folder_explorer)
        group_box_hlt = QtWidgets.QHBoxLayout()
        group_box_hlt.addStretch()
        group_box_hlt.addWidget(self.open_folder_btn)
        group_box.setLayout(QtWidgets.QVBoxLayout())

        group_box.layout().addLayout(group_box_hlt)
        #group_box.layout().addWidget(self.open_folder_btn)
        self.work_folder_label = QtWidgets.QLabel()
        #self.work_folder_label.setSizePolicy(QtWidgets.QSizePolicy.Ignored, QtWidgets.QSizePolicy.MinimumExpanding )
        self.work_folder_label.setWordWrap(True)
        self.work_folder_view = QtWidgets.QTreeView(self)
        self.work_folder_view.dropEvent = self._tree_view_drop_event
        self.work_folder_view.setAcceptDrops(True)
        self.work_folder_view.setDropIndicatorShown(True)
        self.work_folder_view.setSelectionMode( QtWidgets.QAbstractItemView.ExtendedSelection )
        self.work_folder_view.contextMenuEvent = self._tree_view_context_menu_event
        group_box.layout().addWidget(self.work_folder_label)
        group_box.layout().addWidget(self.work_folder_view)
        self.fs_model = QtWidgets.QFileSystemModel()
        self.fs_model.setReadOnly(False)
        self.layout().addWidget(group_box)

        self.fs_watcher = QtCore.QFileSystemWatcher()
        self.fs_watcher.directoryChanged.connect(self.work_area_update_changed)
        self.update_work_folder_view()

        # first update config and start update with time interval
        self.ftp_update_config()
        self.check_updates_timer = QtCore.QTimer()
        self.check_updates_timer.timeout.connect(self.ftp_update_config)
        self.check_updates_timer.setInterval(INTERVAL_IN_MS)
        self.check_updates_timer.start()

    def ftp_update_config(self):
        if self.sync_job_thread.isRunning():
            return
        if self.check_sync_credentials():
            self.ftp_sync_start(utils.SYNC_MODE_DOWNLOAD_CONFIG)

    def open_work_folder_explorer(self):
        index = self.work_folder_view.rootIndex()
        if index.isValid():
            path = index.data(QtWidgets.QFileSystemModel.FilePathRole)
            path = os.path.normpath(path)
            subprocess.call('explorer "%s"' % path, shell=True)

    def _tree_view_context_menu_event(self, event):
        menu = QtWidgets.QMenu(self.work_folder_view)

        def _delete_selected():
            sel = self.work_folder_view.selectedIndexes()
            file_list = set([])
            for index in sel:
                filename = "<b>%s</b>" % os.path.basename( index.data(QtWidgets.QFileSystemModel.FilePathRole) )
                file_list.add(filename)
            result = QtWidgets.QMessageBox.question(self, "Delete Files", "Are you sure want to delete files: %s ?" % ",".join(file_list), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if result == QtWidgets.QMessageBox.Yes:
                for index in sel:
                    self.fs_model.remove(index)
        menu.addAction("Delete Selected Files", _delete_selected)
        menu.exec_(event.globalPos())

    def _tree_view_drop_event(self, event):
        mimeData = event.mimeData()
        if mimeData.hasUrls():
            urls = event.mimeData().urls()
            file_list = []
            for url in urls:
                filename = "<b>%s</b>" % os.path.basename(url.path())
                file_list.append(filename)
            result = QtWidgets.QMessageBox.question(self, "FTP Upload", "Are you sure want to upload files: %s ?" % ",".join(file_list), QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
            if result == QtWidgets.QMessageBox.Yes:
                return QtWidgets.QTreeView.dropEvent(self.work_folder_view, event)

    def update_work_folder_view(self):
        sync_path = utils.get_sync_path()
        if sync_path:
            work_path = os.path.join(sync_path, "work")
            if os.path.exists(work_path):
                self.work_folder_view.show()
                self.work_folder_view.setModel(self.fs_model)
                self.work_folder_view.setRootIndex(self.fs_model.index(work_path))
                self.fs_model.setRootPath(work_path)
                doc = """This is your work folder. It is a synced folder of your <b>'/work'</b> folder on ftp. Any files you drop here will <b>trigger FULL folder sync</b> with our server. Use it exchange playblasts with us, and deliver final maya files."""
                self.work_folder_label.setText(doc)
                if self.fs_watcher.directories():
                    self.fs_watcher.removePaths(self.fs_watcher.directories())
                self.fs_watcher.addPath(work_path)
                return

        self.work_folder_view.setModel(None)
        self.work_folder_view.hide()
        self.work_folder_label.setText("Not Found Work Folder")
        if self.fs_watcher.directories():
            self.fs_watcher.removePaths(self.fs_watcher.directories())

    def work_area_update_changed(self, path):
        if not self.sync_job_thread.isRunning():
            self.ftp_sync_start(utils.SYNC_MODE_UPLOAD)

    def ftp_sync_finish(self):
        self.ftp_sync_btn.setText(self.FTP_BTN_CAPTION)
        self.ftp_sync_btn.setMenu(self.ftp_sync_menu)

        self.work_folder_view.setDisabled(False)
        self.ftp_login_btn.setDisabled(False)
        self.set_sync_folder_btn.setDisabled(False)
        self.update_work_folder_view()
        self.app.rescan_projects_config()
        is_returned_success = self.sync_job_thread.returncode == SUCCESSFUL
        is_latest_mode_sync_config = self.sync_job_thread.mode == utils.SYNC_MODE_DOWNLOAD_CONFIG
        if is_returned_success and is_latest_mode_sync_config:
            self.ftp_sync_start(utils.SYNC_MODE_PUBLIC_S3_SYNC)

    def ftp_sync_start(self, mode):
        if self.sync_job_thread.isRunning() and mode != self.sync_job_thread.mode:
            self.sync_job_thread.proc.terminate()
            self.sync_job_thread.wait()
        if self.check_sync_credentials():
            if utils.get_sync_path():
                self.sync_job_thread.mode = mode
                self.sync_job_thread.output_widget = self.app.log_view
                self.sync_job_thread.start()
                self.ftp_sync_btn.setText(self.FTP_BTN_CAPTION_CANCEL)
                self.ftp_sync_btn.setMenu(None)

                self.ftp_login_btn.setDisabled(True)
                self.set_sync_folder_btn.setDisabled(True)
                self.work_folder_view.setDisabled(True)
            else:
                log.info('Wizart Root Folder is not set. Data cann\'t be updated')
        else:
            log.info("Cann't start Data Sync. You do not have permission. Please, authorize yourself.")

    def check_sync_credentials(self):
        user = utils.get_ftp_user()
        if user:
            if utils.get_sync_is_s3():
                key_id = utils.get_aws_access_key_id(user)
                secret_key = utils.get_aws_secret_access_key(user)
                return True if key_id and secret_key else False
            else:
                return True if utils.get_ftp_password(user) else False
        return False

    def launch_sync(self, mode):
        ftp_credentials = self.check_sync_credentials()
        if not ftp_credentials:
            ftp_credentials = self.set_ftp_credentials()
        if ftp_credentials:
            self.ftp_sync_start(mode)

    def ftp_sync_cancel(self):
        if self.sync_job_thread.isRunning():
            self.sync_job_thread.kill_job()

    def set_ftp_credentials(self):
        diag = login_dialog.LoginDialog()
        username = utils.get_ftp_user()

        is_s3 = utils.get_sync_is_s3()
        if username:
            diag.login_input.setText(username)
        if username:
            if is_s3:
                aws_access_key_id = utils.get_aws_access_key_id(username)
                if aws_access_key_id:
                    diag.aws_access_key_id_input.setText(aws_access_key_id)
                aws_secret_access_key = utils.get_aws_secret_access_key(username)
                if aws_secret_access_key:
                    diag.aws_secret_access_key_input.setText(aws_secret_access_key)
            else:
                password = utils.get_ftp_password(username)
                if password:
                    diag.password_input.setText(password)

        result = diag.exec_()
        if result:
            username = str(diag.login_input.text())
            utils.set_ftp_user(username)

            from sentry_sdk import set_user
            set_user({"username": username})

            if is_s3:
                aws_access_key_id = str(diag.aws_access_key_id_input.text())
                aws_secret_access_key = str(diag.aws_secret_access_key_input.text())
                utils.set_aws_access_key_id(username, aws_access_key_id)
                utils.set_aws_secret_access_key(username, aws_secret_access_key)
            else:
                password = str(diag.password_input.text())
                utils.set_ftp_password(username, password)
        self.app.update_window_title()
        return result

    def set_sync_folder(self):
        res = QtWidgets.QFileDialog.getExistingDirectory(self, "Set Studio Root Folder", utils.get_sync_path() )
        if res:
            log.info("Set Data Root Path for Studio Projects 'W': '%s'" % res)
            utils.set_sync_path(res)
            self.update_work_folder_view()
