#!/usr/bin/env python3
"""
简化的拖拽检测器

使用文件系统监控和剪贴板检测实现拖拽功能
"""

import os
import sys
import time
import subprocess
import threading
from typing import List, Optional, Callable
from collections import deque
import tempfile

class SimpleDragDetector:
    """简化的拖拽检测器"""
    
    def __init__(self, supported_formats: List[str]):
        self.supported_formats = supported_formats
        self.is_running = False
        self.drop_callback = None
        self.dropped_files = deque()
        self.monitor_thread = None
        self.last_clipboard = ""
        
    def set_drop_callback(self, callback: Callable[[List[str]], None]):
        """设置拖拽回调函数"""
        self.drop_callback = callback
        
    def start_monitoring(self):
        """开始监控"""
        if self.is_running:
            return
            
        self.is_running = True
        self.monitor_thread = threading.Thread(target=self._monitor_loop)
        self.monitor_thread.daemon = True
        self.monitor_thread.start()
        print("✓ 简化拖拽监控已启动")
        
    def stop_monitoring(self):
        """停止监控"""
        self.is_running = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=1)
            
    def get_dropped_files(self) -> List[str]:
        """获取拖拽的文件列表"""
        files = list(self.dropped_files)
        self.dropped_files.clear()
        return files
        
    def add_dropped_file(self, file_path: str):
        """添加拖拽的文件"""
        if os.path.exists(file_path):
            file_ext = os.path.splitext(file_path)[1].lower()
            if file_ext in self.supported_formats:
                self.dropped_files.append(file_path)
                print(f"检测到拖拽文件: {file_path}")
                
    def _monitor_loop(self):
        """监控循环"""
        watch_dirs = self._get_watch_directories()
        known_files = set()
        
        # 初始化已知文件
        for watch_dir in watch_dirs:
            self._scan_directory(watch_dir, known_files)
            
        print(f"监控目录: {watch_dirs}")
        print(f"已知文件数量: {len(known_files)}")
        
        while self.is_running:
            try:
                current_time = time.time()
                
                # 1. 检查剪贴板变化
                self._check_clipboard()
                
                # 2. 检查文件系统变化
                for watch_dir in watch_dirs:
                    if not os.path.exists(watch_dir):
                        continue
                        
                    try:
                        current_files = set()
                        for filename in os.listdir(watch_dir):
                            filepath = os.path.join(watch_dir, filename)
                            if self._is_supported_format(filepath):
                                try:
                                    stat = os.stat(filepath)
                                    current_files.add(filepath)
                                    
                                    # 检查新文件
                                    if filepath not in known_files:
                                        time_diff = current_time - stat.st_mtime
                                        if time_diff < 5.0:  # 5秒内创建的文件
                                            if self._is_file_stable(filepath):
                                                print(f"检测到新文件: {filepath}")
                                                self.add_dropped_file(filepath)
                                                if self.drop_callback:
                                                    self.drop_callback([filepath])
                                                
                                except OSError:
                                    continue
                                    
                        known_files.update(current_files)
                        
                    except PermissionError:
                        continue
                    except Exception as e:
                        print(f"监控目录 {watch_dir} 时出错: {e}")
                        
            except Exception as e:
                print(f"监控循环错误: {e}")
                
            time.sleep(0.3)  # 更频繁的检查
            
    def _check_clipboard(self):
        """检查剪贴板变化"""
        try:
            # 检查剪贴板
            result = subprocess.run(['xclip', '-selection', 'clipboard', '-o'],
                                  capture_output=True, text=True, timeout=0.5)
            if result.returncode == 0 and result.stdout.strip():
                current_clipboard = result.stdout.strip()
                if current_clipboard != self.last_clipboard:
                    self.last_clipboard = current_clipboard
                    files = self._parse_clipboard_content(current_clipboard)
                    if files:
                        print(f"剪贴板检测到文件: {files}")
                        for file_path in files:
                            self.add_dropped_file(file_path)
                        if self.drop_callback:
                            self.drop_callback(files)
                            
        except Exception:
            # 尝试使用xsel
            try:
                result = subprocess.run(['xsel', '--clipboard', '--output'],
                                      capture_output=True, text=True, timeout=0.5)
                if result.returncode == 0 and result.stdout.strip():
                    current_clipboard = result.stdout.strip()
                    if current_clipboard != self.last_clipboard:
                        self.last_clipboard = current_clipboard
                        files = self._parse_clipboard_content(current_clipboard)
                        if files:
                            for file_path in files:
                                self.add_dropped_file(file_path)
                            if self.drop_callback:
                                self.drop_callback(files)
            except Exception:
                pass
                
    def _parse_clipboard_content(self, content: str) -> List[str]:
        """解析剪贴板内容"""
        files = []
        for line in content.split('\n'):
            line = line.strip()
            if line.startswith('file://'):
                file_path = line[7:]
                file_path = file_path.replace('%20', ' ')
                if os.path.exists(file_path):
                    files.append(file_path)
            elif os.path.isabs(line) and os.path.exists(line):
                files.append(line)
        return files
        
    def _get_watch_directories(self) -> List[str]:
        """获取监控目录"""
        dirs = [
            os.path.expanduser('~/Desktop'),
            os.path.expanduser('~/Downloads'),
            tempfile.gettempdir()
        ]
        
        # 添加一些常见的拖拽目标目录
        additional_dirs = [
            os.path.expanduser('~/Documents'),
            os.path.expanduser('~'),
            '/tmp'
        ]
        
        for dir_path in additional_dirs:
            if os.path.exists(dir_path) and os.path.isdir(dir_path):
                dirs.append(dir_path)
                
        return [d for d in dirs if os.path.exists(d)]
        
    def _scan_directory(self, directory: str, known_files: set):
        """扫描目录"""
        try:
            for filename in os.listdir(directory):
                filepath = os.path.join(directory, filename)
                if self._is_supported_format(filepath):
                    try:
                        known_files.add(filepath)
                    except OSError:
                        pass
        except Exception:
            pass
            
    def _is_supported_format(self, file_path: str) -> bool:
        """检查文件格式是否支持"""
        if not os.path.isfile(file_path):
            return False
        file_ext = os.path.splitext(file_path)[1].lower()
        return file_ext in self.supported_formats
        
    def _is_file_stable(self, file_path: str, wait_time: float = 0.5) -> bool:
        """检查文件是否稳定"""
        try:
            initial_size = os.path.getsize(file_path)
            time.sleep(wait_time)
            current_size = os.path.getsize(file_path)
            return initial_size == current_size
        except:
            return False
            
    def is_supported(self) -> bool:
        """检查是否支持"""
        return True  # 这个版本总是支持的
        
    def get_platform_info(self) -> dict:
        """获取平台信息"""
        return {
            'system': 'Linux',
            'detector_type': 'SimpleDragDetector',
            'supported': True,
            'method': 'File system + clipboard monitoring'
        }
