import sys
import os
import shutil
import configparser
from PyQt5.QtWidgets import (QApplication, QSystemTrayIcon, QMenu, QWidget, QVBoxLayout, 
                            QTreeView, QFileSystemModel, QInputDialog, QMessageBox, QSizeGrip,
                            QLabel, QAction, QFileDialog)
from PyQt5.QtGui import QIcon, QCursor, QMouseEvent, QDrag, QKeySequence, QDesktopServices
from PyQt5.QtCore import (Qt, QPoint, QSettings, QSize, QTimer, QMimeData, QCoreApplication,
                         QUrl, QDir, QMargins)

class ConfigManager:
    def __init__(self):
        self.home = os.path.expanduser("~")
        self.base_dir = os.path.join(self.home, ".DeskManager")
        self.config_path = os.path.join(self.base_dir, "Config.ini")
        
        self._init_directory()
        self.config = configparser.ConfigParser()
        self.config.read(self.config_path)
    
    def _init_directory(self):
        if not os.path.exists(self.base_dir):
            os.makedirs(self.base_dir)
        if not os.path.exists(self.config_path):
            with open(self.config_path, 'w') as f:
                pass
    
    def get_config(self, folder):
        if self.config.has_section(folder):
            return dict(self.config[folder])
        return None
    
    def update_config(self, folder, data):
        if not self.config.has_section(folder):
            self.config.add_section(folder)
        for key, value in data.items():
            self.config.set(folder, key, str(value))
        with open(self.config_path, 'w') as f:
            self.config.write(f)

class TitleBar(QLabel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.parent = parent
        self.setFixedHeight(30)
        self.setStyleSheet("""
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #616161, stop:1 #333333);
            color: white;
            border-radius: 4px;
            padding-left: 10px;
            qproperty-alignment: 'AlignCenter';
        """)
        self.setAlignment(Qt.AlignCenter)

    def mousePressEvent(self, event):
        self.parent.handleTitleBarEvent(event)
    
    def mouseDoubleClickEvent(self, event):
        self.parent.rename_folder()

class FolderWindow(QWidget):
    def __init__(self, folder_path, config_manager):
        super().__init__()
        self.folder_path = folder_path
        self.config_manager = config_manager
        self.folder_name = os.path.basename(folder_path)
        self.is_locked = False
        self.resize_margin = 8
        self.setup_ui()
        self.load_config()
        
        self.setAcceptDrops(True)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnBottomHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
    
    def setup_ui(self):
        self.main_layout = QVBoxLayout(self)
        self.main_layout.setContentsMargins(2, 2, 2, 2)
        self.main_layout.setSpacing(0)
        
        self.title_bar = TitleBar(self)
        self.title_bar.setText(self.folder_name)
        
        self.content_widget = QWidget()
        self.content_layout = QVBoxLayout(self.content_widget)
        self.content_layout.setContentsMargins(0, 0, 0, 0)
        
        self.model = QFileSystemModel()
        self.model.setRootPath(self.folder_path)
        self.model.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs | QDir.Files)
        
        self.tree = QTreeView()
        self.tree.setModel(self.model)
        self.tree.setRootIndex(self.model.index(self.folder_path))
        self.tree.setHeaderHidden(True)
        self.tree.hideColumn(1)
        self.tree.hideColumn(2)
        self.tree.hideColumn(3)
        self.tree.setIndentation(10)
        self.tree.setStyleSheet("""
            QTreeView {
                background: #f0f0f0;
                border: 1px solid #cccccc;
                border-radius: 3px;
            }
        """)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.show_context_menu)
        self.tree.doubleClicked.connect(self.open_item)
        
        self.content_layout.addWidget(self.tree)
        self.main_layout.addWidget(self.title_bar)
        self.main_layout.addWidget(self.content_widget)
        
        self.size_grip = QSizeGrip(self)
        self.size_grip.setStyleSheet("width: 16px; height: 16px;")
    
    def open_item(self, index):
        path = self.model.filePath(index)
        if os.path.isfile(path):
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))
        elif os.path.isdir(path):
            os.startfile(path)
    
    def load_config(self):
        config = self.config_manager.get_config(self.folder_name)
        if config:
            self.resize(int(config['width']), int(config['height']))
            self.move(int(config['x']), int(config['y']))
            self.setWindowOpacity(float(config['alpha']))
            self.is_locked = config.get('locked', 'False') == 'True'
            self.size_grip.setVisible(not self.is_locked)
        else:
            screen = QApplication.primaryScreen().geometry()
            self.resize(400, 400)
            x = (screen.width() - 400) // 2
            y = (screen.height() - 400) // 2
            self.move(x, y)
            self.update_config()
    
    def update_config(self):
        data = {
            'x': self.x(),
            'y': self.y(),
            'width': self.width(),
            'height': self.height(),
            'alpha': self.windowOpacity(),
            'locked': str(self.is_locked)
        }
        self.config_manager.update_config(self.folder_name, data)
    
    def handleTitleBarEvent(self, event):
        if event.button() == Qt.LeftButton and not self.is_locked:
            if event.type() == QMouseEvent.MouseButtonDblClick:
                self.rename_folder()
            else:
                self.__startDrag(event.globalPos())
        elif event.button() == Qt.RightButton:
            self.show_context_menu(event.globalPos())
    
    def __startDrag(self, global_pos):
        self.drag_start_position = global_pos - self.frameGeometry().topLeft()
    
    def mouseMoveEvent(self, event):
        if not self.is_locked and hasattr(self, 'drag_start_position'):
            self.move(event.globalPos() - self.drag_start_position)
            self.update_config()
    
    def mouseReleaseEvent(self, event):
        if hasattr(self, 'drag_start_position'):
            del self.drag_start_position
    
    def show_context_menu(self, pos):
        menu = QMenu()
        rename_action = menu.addAction("ð éå½å")
        opacity_menu = menu.addMenu("ð¨ éæåº¦")
        lock_action = menu.addAction("ð éå®" if not self.is_locked else "ð è§£é")
        
        # éæåº¦è®¾ç½®
        for value in [0.3, 0.5, 0.7, 1.0]:
            opacity_action = opacity_menu.addAction(f"{int(value*100)}%")
            opacity_action.triggered.connect(
                lambda checked, v=value: self.set_opacity(v))
        
        # åè½è¿æ¥
        rename_action.triggered.connect(self.rename_folder)
        lock_action.triggered.connect(self.toggle_lock)
        
        # æä»¶å³é®èå
        if isinstance(pos, QPoint):  # æ é¢æ å³é®
            menu.exec_(pos)
        else:  # æä»¶åè¡¨å³é®
            global_pos = self.tree.viewport().mapToGlobal(pos)
            menu.exec_(global_pos)
    
    def set_opacity(self, value):
        self.setWindowOpacity(value)
        self.update_config()
    
    def toggle_lock(self):
        self.is_locked = not self.is_locked
        self.size_grip.setVisible(not self.is_locked)
        self.update_config()
    
    def rename_folder(self):
        new_name, ok = QInputDialog.getText(
            self, "éå½å", "è¾å¥æ°åç§°:", text=self.folder_name)
        if ok and new_name:
            new_path = os.path.join(os.path.dirname(self.folder_path), new_name)
            try:
                os.rename(self.folder_path, new_path)
                self.folder_path = new_path
                self.folder_name = new_name
                self.title_bar.setText(new_name)
                self.config_manager.config.remove_section(self.folder_name)
                self.update_config()
            except Exception as e:
                QMessageBox.warning(self, "éè¯¯", str(e))
    
    def dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
    
    def dropEvent(self, event):
        for url in event.mimeData().urls():
            src_path = url.toLocalFile()
            dst_path = os.path.join(self.folder_path, os.path.basename(src_path))
            try:
                if os.path.isdir(src_path):
                    shutil.move(src_path, dst_path)
                else:
                    shutil.move(src_path, dst_path)
            except Exception as e:
                QMessageBox.warning(self, "ç§»å¨å¤±è´¥", str(e))
        self.model.refresh()

class TrayIcon(QSystemTrayIcon):
    def __init__(self, config_manager):
        super().__init__()
        self.config_manager = config_manager
        self.setIcon(QIcon.fromTheme("folder"))
        self.setup_menu()
        self.windows = []
        
        self.activated.connect(self.on_tray_activate)
        QTimer.singleShot(0, self.init_folders)
    
    def setup_menu(self):
        menu = QMenu()
        create_action = menu.addAction("æ°å»ºæä»¶å¤¹")
        exit_action = menu.addAction("éåº")
        create_action.triggered.connect(self.create_folder)
        exit_action.triggered.connect(QCoreApplication.quit)
        self.setContextMenu(menu)
    
    def init_folders(self):
        base_dir = self.config_manager.base_dir
        for folder in os.listdir(base_dir):
            folder_path = os.path.join(base_dir, folder)
            if os.path.isdir(folder_path) and not folder.startswith('.'):
                self.create_window(folder_path)
    
    def create_window(self, folder_path):
        window = FolderWindow(folder_path, self.config_manager)
        window.show()
        self.windows.append(window)
    
    def on_tray_activate(self, reason):
        if reason == QSystemTrayIcon.DoubleClick:
            self.create_folder()
    
    def create_folder(self):
        folder_name, ok = QInputDialog.getText(
            None, "æ°å»ºæä»¶å¤¹", "è¾å¥æä»¶å¤¹åç§°:")
        if ok and folder_name:
            folder_path = os.path.join(self.config_manager.base_dir, folder_name)
            try:
                os.makedirs(folder_path, exist_ok=True)
                self.create_window(folder_path)
            except Exception as e:
                QMessageBox.warning(None, "åå»ºå¤±è´¥", str(e))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    config = ConfigManager()
    tray = TrayIcon(config)
    tray.show()
    sys.exit(app.exec_())
