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


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: 5px;
        """)
        self.setAlignment(Qt.AlignCenter)

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

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

    def set_color(self, color):
        self.setStyleSheet(f"""
            background: {color};
            color: white;
            border-radius: 4px;
            padding-left: 5px;
        """)


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)
        self.tree.doubleClicked.connect(self.open_item)
        self.tree.setDragEnabled(True)
        self.tree.setDragDropMode(QTreeView.DragOnly)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.show_tree_context_menu)
        self.tree.setEditTriggers(QTreeView.DoubleClicked | QTreeView.EditKeyPressed)

    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.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.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.isdir(path):
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))
        else:
            QDesktopServices.openUrl(QUrl.fromLocalFile(path))

    def resizeEvent(self, event):
        self.size_grip.move(self.width() - 16, self.height() - 16)
        super().resizeEvent(event)

    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'
            title_color = config.get('title_color', '#616161')
            self.title_bar.set_color(title_color)
            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),
            'title_color': self.title_bar.palette().color(self.title_bar.backgroundRole()).name()
        }
        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()
        opacity_menu = menu.addMenu("🎨 透明度")
        lock_action = menu.addAction("🔒 锁定" if not self.is_locked else "🔓 解锁")
        color_action = menu.addAction("🎨 修改标题颜色")
        delete_action = menu.addAction("🗑 删除文件夹")

        for value in [0.2, 0.4, 0.6, 0.8, 1.0]:
            opacity_menu.addAction(f"{int(value * 100)}%",
                                   lambda v=value: self.set_opacity(v))

        lock_action.triggered.connect(self.toggle_lock)
        color_action.triggered.connect(self.change_title_color)
        delete_action.triggered.connect(self.delete_folder)

        menu.exec_(pos)

    def show_tree_context_menu(self, pos):
        index = self.tree.indexAt(pos)
        if not index.isValid():
            return

        menu = QMenu()
        rename_action = menu.addAction("📝 重命名")
        delete_action = menu.addAction("🗑 删除")

        rename_action.triggered.connect(lambda: self.rename_file(index))
        delete_action.triggered.connect(lambda: self.delete_file(index))

        menu.exec_(self.tree.viewport().mapToGlobal(pos))

    def set_opacity(self, value):
        self.setWindowOpacity(value)
        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)
            os.rename(self.folder_path, new_path)
            self.folder_name = new_name
            self.folder_path = new_path
            self.title_bar.setText(new_name)
            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 dragEnterEvent(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()

    def dropEvent(self, event):
        for url in event.mimeData().urls():
            src = url.toLocalFile()
            dst = os.path.join(self.folder_path, os.path.basename(src))
            try:
                shutil.move(src, dst)
            except Exception as e:
                QMessageBox.warning(self, "操作失败", f"无法移动文件: {str(e)}")
        self.model.setRootPath(self.folder_path)

    def change_title_color(self):
        color = QColorDialog.getColor(self.title_bar.palette().color(self.title_bar.backgroundRole()), self)
        if color.isValid():
            self.title_bar.set_color(color.name())
            self.update_config()

    def rename_file(self, index):
        path = self.model.filePath(index)
        if os.path.isdir(path):
            return

        new_name, ok = QInputDialog.getText(self, "重命名文件", "新名称:", text=os.path.basename(path))
        if ok and new_name:
            new_path = os.path.join(os.path.dirname(path), new_name)
            try:
                os.rename(path, new_path)
                self.model.setRootPath(self.folder_path)
            except Exception as e:
                QMessageBox.warning(self, "操作失败", f"无法重命名文件: {str(e)}")

    def delete_file(self, index):
        path = self.model.filePath(index)
        if os.path.isdir(path):
            return

        reply = QMessageBox.question(self, "删除文件", f"确定要删除文件 {os.path.basename(path)} 吗？",
                                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            try:
                os.remove(path)
                self.model.setRootPath(self.folder_path)
            except Exception as e:
                QMessageBox.warning(self, "操作失败", f"无法删除文件: {str(e)}")

    def delete_folder(self):
        reply = QMessageBox.question(self, "删除文件夹", f"确定要删除文件夹 {self.folder_name} 吗？",
                                      QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
        if reply == QMessageBox.Yes:
            self.move_files_to_desktop(self.folder_path)
            try:
                shutil.rmtree(self.folder_path)
                self.close()
                self.update_config()
                QMessageBox.information(self, "删除成功", f"文件夹 {self.folder_name} 已成功删除")
            except Exception as e:
                QMessageBox.warning(self, "操作失败", f"无法删除文件夹: {str(e)}")

    def move_files_to_desktop(self, folder_path):
        desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
        for root, dirs, files in os.walk(folder_path):
            for file in files:
                file_path = os.path.join(root, file)
                dest_path = os.path.join(desktop_path, file)
                if os.path.exists(dest_path):
                    # 生成新的文件名
                    base_name, ext = os.path.splitext(file)
                    i = 1
                    while os.path.exists(dest_path):
                        new_name = f"{base_name}_{i}{ext}"
                        dest_path = os.path.join(desktop_path, new_name)
                        i += 1
                shutil.move(file_path, dest_path)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Delete:
            index = self.tree.currentIndex()
            if index.isValid():
                self.delete_file(index)

class TrayManager(QSystemTrayIcon):
    def __init__(self, config_manager):
        super().__init__()
        self.config_manager = config_manager
        self.setIcon(QIcon.fromTheme("folder"))
        self.setup_menu()
        self.windows = []

        QTimer.singleShot(0, self.init_windows)

    def setup_menu(self):
        menu = QMenu()
        new_folder = menu.addAction("➕ 新建文件夹")
        menu.addSeparator()
        exit_action = menu.addAction("⏏ 退出程序")

        new_folder.triggered.connect(self.create_folder)
        exit_action.triggered.connect(self.exit_app)

        self.setContextMenu(menu)

    def init_windows(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):
                window = FolderWindow(folder_path, self.config_manager)
                window.show()
                self.windows.append(window)

    def create_folder(self):
        name, ok = QInputDialog.getText(None, "新建文件夹", "文件夹名称:")
        if ok and name:
            path = os.path.join(self.config_manager.base_dir, name)
            if not os.path.exists(path):
                os.makedirs(path)
                window = FolderWindow(path, self.config_manager)
                window.show()
                self.windows.append(window)

    def exit_app(self):
        for window in self.windows:
            window.close()
        QCoreApplication.quit()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyle("Fusion")
    app.setQuitOnLastWindowClosed(False)

    config = ConfigManager()
    tray = TrayManager(config)
    tray.show()

    sys.exit(app.exec_())
