import glob
import os
import sys
from multiprocessing.pool import ThreadPool

from PyQt5.QtCore import QThread, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QFileDialog

from base import SharedBase
from ui import Ui_MainWindow


class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super(MyMainWindow, self).__init__()
        self.setupUi(self)
        self.initUI()

    def initUI(self):
        self.pushButton.clicked.connect(self.do)
        self.lineEdit.returnPressed.connect(self.do)
        self.pushButton_browse_file.clicked.connect(self.show_file_dialog)
        self.lineEdit_save_location.setText(os.getcwd())
        self.lineEdit.setFocus()

    def show_file_dialog(self):
        selected_dir = QFileDialog.getExistingDirectory(self, caption='Choose Directory', directory=os.getcwd())
        self.lineEdit_save_location.setText(selected_dir)

    def do(self):
        try:
            self.lineEdit.setDisabled(True)
            self.user_input_url = self.lineEdit.text()
            self.pushButton.setDisabled(True)
            self.checkBox.setDisabled(True)
            self.spinBox_fetch_limit.setDisabled(True)
            self.spinBox_threads.setDisabled(True)
            self.label_chapters.setDisabled(True)
            self.label_threads.setDisabled(True)
            self.label_save.setDisabled(True)
            self.lineEdit_save_location.setDisabled(True)
            self.save_dir = self.lineEdit_save_location.text()
            self.pushButton_browse_file.setDisabled(True)
            self.base = SharedBase(self.user_input_url)
            self.site_name = self.base.get_site_name()
            if self.checkBox.isChecked():
                checkbox_value = self.spinBox_fetch_limit.value()
            else:
                checkbox_value = False
            threads = self.spinBox_threads.value()
            self.work = WorkingThread(self.site_name, self.user_input_url, checkbox_value, threads, self.save_dir)
            self.work.status_report_signal.connect(self.status_receive_signal)
            self.work.progress_report_signal.connect(self.progress_receive_signal)
            self.work.stop_signal.connect(self.stop_signal)
            self.work.chapter_start_signal.connect(self.chapter_start_receive_signal)
            self.work.start()
        except NameError as e:
            self.stop_signal('Website %s illegal or not supported' % e)

    def status_receive_signal(self, text):
        self.statusBar().showMessage(text)

    def progress_receive_signal(self, is_done):
        self.pages_done += 1
        self.progressBar.setProperty('value', self.pages_done / self.total_pages * 100)

    def chapter_start_receive_signal(self, start_tuple):
        parent_title, total_pages = start_tuple
        self.status_receive_signal('Downloading %s' % parent_title)
        self.pages_done = 0
        self.total_pages = total_pages

    def stop_signal(self, text=''):
        self.lineEdit.setDisabled(False)
        self.pushButton.setDisabled(False)
        self.checkBox.setDisabled(False)
        self.spinBox_fetch_limit.setDisabled(False)
        self.spinBox_threads.setDisabled(False)
        self.label_chapters.setDisabled(False)
        self.label_threads.setDisabled(False)
        self.label_save.setDisabled(False)
        self.lineEdit_save_location.setDisabled(False)
        self.pushButton_browse_file.setDisabled(False)
        self.statusBar().showMessage(text)
        self.lineEdit.setFocus()


class WorkingThread(QThread):
    status_report_signal = pyqtSignal(str)
    progress_report_signal = pyqtSignal(bool)
    stop_signal = pyqtSignal(str)
    chapter_start_signal = pyqtSignal(tuple)

    def __init__(self, site_name, url, checkbox_value, threads, save_dir):
        super(WorkingThread, self).__init__()
        self.site_name = site_name
        self.user_input_url = url
        self.latest_limit = checkbox_value
        self.threads = threads
        self.save_dir = save_dir

    def run(self):
        if self.site_name == 'dm5':
            from sites import DM5 as SiteClass
        elif self.site_name == 'ck101':
            from sites import Ck101 as SiteClass
        elif self.site_name == 'dmzj':
            from sites import Dmzj as SiteClass
        elif self.site_name == 'manhua_dmzj':
            from sites import manhua_Dmzj as SiteClass
        elif self.site_name == 'ehentai':
            from sites import Ehentai as SiteClass
        try:
            self.website_object = SiteClass(self.user_input_url)
            self.comic_name = self.website_object.get_name()
            self.ref_box = self.website_object.get_parent_info()
            self.status_report_signal.emit('%s, total %d chapters detected.' % (self.comic_name, len(self.ref_box)))
            if self.latest_limit is not False:
                if self.latest_limit > len(self.ref_box):
                    raise ValueError
                self.ref_box = self.ref_box[-self.latest_limit:]
            self.main_loop(self.ref_box)
        except ValueError:
            self.stop_signal.emit('Chapters selected out of range, maximum %s chapters' % len(self.ref_box))
        except ConnectionError as e:
            self.stop_signal.emit('%s, consider using a proxy or a VPN.' % e)

    def main_loop(self, refer_box):
        # for ref_tuple in refer_box:
        #     title, parent_link = ref_tuple
        #     total_page = self.website_object.get_page_info(parent_link)
        #     for page in range(1, total_page + 1):
        #         vague_path = self.website_object.get_path(self.comic_name, title, page) + '*'
        #         if glob.glob(vague_path):
        #             self.status_report_signal.emit('%s page %d already existed.' % (title, page))
        #         else:
        #             try:
        #                 link = self.website_object.get_image_link(parent_link, page)
        #                 self.status_report_signal.emit('Downloading %s' % title)
        #                 self.website_object.down(self.comic_name, parent_link, link, title, page)
        #                 progress = page / self.website_object.get_page_info(parent_link)
        #                 self.progress_report_signal.emit(progress * 100)
        #             except:
        #                 errlog = 'Error occurred when downloading %s, Page %d.' % (title, page)
        #                 self.status_report_signal.emit(errlog)
        # self.stop_signal.emit('All Done!')
        for refer_tuple in refer_box:
            parent_title, parent_link = refer_tuple
            total_page = self.website_object.get_page_info(parent_link)
            jobs = list()
            for page in range(1, total_page + 1):
                jobs.append((parent_title, parent_link, page, total_page))
            pool_size = self.threads
            pool = ThreadPool(processes=pool_size)
            # self.status_report_signal.emit('Downloading %s' % parent_title)
            self.chapter_start_signal.emit((parent_title, total_page))
            pool.map(self.loop_thread, jobs)
            pool.close()
            pool.join()
        self.stop_signal.emit('All Done!')

    def loop_thread(self, args):
        parent_title, parent_link, page, total_page = args
        vague_path = self.website_object.get_path(self.comic_name, parent_title, page) + '*'
        if glob.glob(vague_path):
            self.status_report_signal.emit('%s page %d already existed.' % (parent_title, page))
        else:
            try:
                link = self.website_object.get_image_link(parent_link, page)
                self.website_object.down(self.comic_name, parent_link, link, parent_title, page, self.save_dir)
                self.progress_report_signal.emit(True)
            except:
                self.status_report_signal.emit('Error occurred when downloading %s, Page %d.' % (parent_title, page))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MyMainWindow()
    window.show()
    sys.exit(app.exec_())