import os
import shutil
import sys
from datetime import datetime
from PyQt6.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QLabel, QPushButton, QFileDialog, QProgressBar, QMessageBox
)
from PyQt6.QtCore import Qt, QThread, pyqtSignal

class BackupThread(QThread):
    progress = pyqtSignal(int)
    finished = pyqtSignal(str)
    error = pyqtSignal(str)
    
    def __init__(self, source_folder, destination_folder):
        super().__init__()
        self.source_folder = source_folder
        self.destination_folder = destination_folder
    
    def run(self):
        if not os.path.exists(self.source_folder):
            self.error.emit("Source folder not found.")
            return
        
        timestamp = datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
        backup_name = f'calibre_backup_{timestamp}'
        backup_path = os.path.join(self.destination_folder, backup_name)
        
        try:
            self.progress.emit(10)
            shutil.make_archive(backup_path, 'zip', self.source_folder)
            self.progress.emit(100)
            self.finished.emit(f"Backup created at: {backup_path}.zip")
        except Exception as e:
            self.error.emit(str(e))

class BackupApp(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        
    def init_ui(self):
        self.setWindowTitle("Calibre Backup")
        self.setGeometry(100, 100, 400, 250)
        
        self.layout = QVBoxLayout()
        
        self.label_info = QLabel("Create a backup of a folder", self)
        self.layout.addWidget(self.label_info)
        
        self.btn_select_source = QPushButton("Select Source Folder", self)
        self.btn_select_source.clicked.connect(self.select_source_folder)
        self.layout.addWidget(self.btn_select_source)
        
        self.label_source = QLabel("Source folder: ~/.config/calibre", self)
        self.layout.addWidget(self.label_source)
        self.source_folder = os.path.expanduser('~/.config/calibre')
        
        self.btn_select_dest = QPushButton("Select Destination Folder", self)
        self.btn_select_dest.clicked.connect(self.select_destination_folder)
        self.layout.addWidget(self.btn_select_dest)
        
        self.label_dest = QLabel("Destination folder: ~/Desktop", self)
        self.layout.addWidget(self.label_dest)
        self.destination_folder = os.path.join(os.path.expanduser('~'), 'Desktop')
        
        self.btn_backup = QPushButton("Start Backup", self)
        self.btn_backup.clicked.connect(self.start_backup)
        self.layout.addWidget(self.btn_backup)
        
        self.progress_bar = QProgressBar(self)
        self.progress_bar.setValue(0)
        self.layout.addWidget(self.progress_bar)
        
        self.setLayout(self.layout)
    
    def select_source_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Select Source Folder")
        if folder:
            self.source_folder = folder
            self.label_source.setText(f"Source folder: {folder}")
    
    def select_destination_folder(self):
        folder = QFileDialog.getExistingDirectory(self, "Select Destination Folder")
        if folder:
            self.destination_folder = folder
            self.label_dest.setText(f"Destination folder: {folder}")
    
    def start_backup(self):
        self.progress_bar.setValue(0)
        self.thread = BackupThread(self.source_folder, self.destination_folder)
        self.thread.progress.connect(self.progress_bar.setValue)
        self.thread.finished.connect(self.show_success_message)
        self.thread.error.connect(self.show_error_message)
        self.thread.start()
    
    def show_success_message(self, message):
        QMessageBox.information(self, "Success", message)
    
    def show_error_message(self, message):
        QMessageBox.critical(self, "Error", message)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = BackupApp()
    window.show()
    sys.exit(app.exec())

