#!/usr/bin/env python
import os
import sys

from PyQt6.QtCore import QThreadPool
from PyQt6.QtWidgets import QMainWindow, QApplication
from PyQt6.QtGui import QIcon,QPixmap

from configure import CONFIG_FILE, Configure
from file_stuff import is_file
from BitMover_MainWindow import Ui_MainWindow
from media import Media
from lumberjack import timber
from thread_my_stuff import Worker
from img_preview import ImgPreview

log = timber(__name__)
basedir = os.path.dirname(__file__)

# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, *args, **kwargs):
        super(MainWindow,self).__init__(*args,**kwargs)

        self.setupUi(self)
        self.setWindowTitle("BitMover")
        self.setWindowIcon(QIcon(os.path.join(basedir,'assets', 'forklift.ico')))

        c = Configure(CONFIG_FILE)
        self.config = c.load_config()
        self.src_dir = self.config['folders']['source']['base']
        self.dst_dir = self.config['folders']['destination']['base']
        self.file_types = self.config['file_types']
        self.lineEdit_src_dir.setText(self.src_dir)
        self.lineEdit_dst_dir.setText(self.dst_dir)

        # Button Setup
        self.pushButton_src_browse.clicked.connect(self.select_src_directory)
        self.pushButton_dst_browse.clicked.connect(self.select_dst_directory)
        self.pushButton_3_scan_dir.clicked.connect(self.find_files)
        self.toggle_scan_button(True)

        # Initialize widgets
        self.lcd_files_found.display(int(0))
        self.set_progress_processing(0)
        self.set_progress_importing(0)
        self.img_preview.setPixmap(QPixmap(os.path.join(basedir,
                                                        'assets',
                                                        'preview_placeholder.jpg')))
        self.img_preview.setScaledContents(True)
        self.file_list.currentItemChanged.connect(self.index_changed)

        # File Stuff
        self.total_files = 0
        self.file_total = 0
        self.files = {}

        # Setup thread pool
        self.threadpool = QThreadPool()
        print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

    def toggle_scan_button(self,enable=True):
            self.pushButton_3_scan_dir.setEnabled(enable)

    def update_preview(self,i):
        preview = ImgPreview(file=i.text(), event=self.get_event(), config=self.config)

        self.label_data_date_time_created.setText(preview.dtc)
        path_hash = preview.path_hash

        self.l_data_file_source_path.setText(
            self.files[path_hash]['folders']['source_path'])
        self.l_data_file_dest_path.setText(
            self.files[path_hash]['folders']['destination'])

        self.img_preview.setPixmap(QPixmap(preview.thumbnail))
        self.img_preview.setFixedHeight(self.img_preview.width() / preview.thumbnail_ratio)

        if preview.file_type == 'image':
            self.label_data_width_height.setText(str(preview.size))
            self.label_data_dpi.setText(str(preview.dpi))
            self.label_data_iso.setText(str(preview.iso))
            self.label_data_lens.setText(str(preview.lens))
            self.label_data_zoom.setText(str(preview.zoom))
            self.label_data_camera.setText(str(preview.camera))
            self.label_data_aperture.setText(str(preview.aperture))
            self.label_data_megapixels.setText(str(preview.mpixels))

    def index_changed(self,i):
        if i is None:
            self.img_preview.setPixmap(QPixmap(os.path.join(basedir,
                                                            'assets',
                                                            'preview_placeholder.jpg')))
        else:
            self.update_preview(i)

    def select_src_directory(self):
        directory = QFileDialog.getExistingDirectory(self,
                                                     "Select Directory",
                                                     self.src_dir)
        if directory:
            print("Selected Directory:", directory)
            # path = Path(directory)
            self.src_dir = directory
            self.lineEdit_src_dir.setText(self.src_dir)

    def select_dst_directory(self):
        directory = QFileDialog.getExistingDirectory(self,
                                                     "Select Directory",
                                                     self.dst_dir)
        if directory:
            print("Selected Directory:", directory)
            # path = Path(directory)
            self.dst_dir = directory
            self.lineEdit_dst_dir.setText(self.dst_dir)

    def set_total_files(self,t):
        self.total_files = t
        self.lcd_files_found.display(self.total_files)

    def set_progress_processing(self, n):
        # print("%d%% done" % n)
        self.progressBar_processing.setValue(int(n))

    def set_progress_importing(self, n):
        # print("%d%% done" % n)
        self.progressBar_importing.setValue(int(n))

    def get_t_files(self,search_types):
        for folder, subfolders, filename in os.walk(self.src_dir):
            for f_type in search_types:
                for ext in self.file_types[f_type]:
                    for file in filename:
                        if file.lower().endswith(ext):
                            current_file = os.path.join(folder, file)
                            if is_file(current_file):
                                self.file_total += int(1)
                            else:
                                print(f"Skipping {current_file} as it does not look like a real file.")

    def t_find_files(self,progress_callback):
        file_count = int(0)


        search_types = []

        if self.checkBox_search_for_images.isChecked():
            search_types.append('image')
        if self.checkBox_search_for_video.isChecked():
            search_types.append('video')
        if self.checkBox_search_for_audio.isChecked():
            search_types.append('audio')

        self.get_t_files(search_types)
        self.set_total_files(self.file_total)

        if len(search_types) > 0:
            for folder, subfolders, filename in os.walk(self.src_dir):
                for f_type in search_types:
                    for ext in self.file_types[f_type]:
                        for file in filename:
                            if file.lower().endswith(ext):
                                current_file = os.path.join(folder, file)
                                if is_file(current_file):
                                    file_count += int(1)
                                    self.process_file(current_file)


                                else:
                                    print(f"Skipping {current_file} as it does not look like a real file.")

                                progress_callback.emit(round((file_count / self.file_total) * 100, 0))
        else:
            print("Nothing to search for.")

        return "Done."

    @staticmethod
    def print_output(s):
        print(s)

    def scan_thread_started(self):
        print('scan thread started')
        self.toggle_scan_button(False)

    def scan_thread_done(self):
        print('scan thread complete.')
        self.toggle_scan_button(True)

    @staticmethod
    def thread_complete():
        print("THREAD COMPLETE.")

    def find_files(self):
        """ find files to build a dictionary out of """

        # Initialize widgets
        self.lcd_files_found.display(int(0))
        self.set_progress_processing(0)
        self.set_progress_importing(0)
        self.img_preview.setPixmap(QPixmap(os.path.join(basedir,
                                                        'assets',
                                                        'preview_placeholder.jpg')))
        self.file_list.clear()

        # File Stuff
        self.total_files = 0
        self.file_total = 0
        self.files = {}

        worker = Worker(self.t_find_files)
        worker.signals.started.connect(self.scan_thread_started)
        worker.signals.result.connect(self.print_output)
        worker.signals.finished.connect(self.thread_complete)
        worker.signals.finished.connect(self.scan_thread_done)
        worker.signals.progress.connect(self.set_progress_processing)

        # Execute.
        self.threadpool.start(worker)

    def get_event(self):
        event_name = self.eventName.text()
        return event_name

    def process_file(self,p):
        """ gather information and add to dictionary """

        path_name = os.path.dirname(p)
        f_name = os.path.basename(p)

        event = self.get_event()
        c = self.config

        log.debug(f'process_file({path_name}, {f_name}, {event}, {c})')

        m = Media(os.path.join(path_name,f_name),event, c)
        i = m.source_path_hash
        # log.debug(f'Source Path Hash: {i}')

        self.files[i] = {
            'folders': {},
            'date': {},
            'event': {}
        }

        self.files[i]['folders']['source_path'] = m.source_path_dir
        self.files[i]['type'] = m.file_type
        self.files[i]['name'] = m.file_name
        self.files[i]['extension'] = m.file_ext
        self.files[i]['date']['capture_date'] = {}
        self.files[i]['date']['capture_date']['y'] = m.capture_date[0]
        self.files[i]['date']['capture_date']['m'] = m.capture_date[1]
        self.files[i]['date']['capture_date']['d'] = m.capture_date[2]
        self.files[i]['folders']['destination'] = m.destination_path
        self.files[i]['folders']['destination_original'] = m.destination_originals_path
        self.files[i]['event']['name'] = m.event_name
        self.file_list.addItem(f"{self.files[i]['folders']['source_path']}/{self.files[i]['name']}")

app = QApplication(sys.argv)

window = MainWindow()
window.show()

app.exec()