"""
拖拽检测器基类

定义所有平台拖拽检测器的通用接口。
"""

import os
import platform
from abc import ABC, abstractmethod
from typing import List, Optional, Callable
import threading
import queue
import time


class BaseDragDetector(ABC):
    """拖拽检测器基类"""
    
    def __init__(self, supported_formats: List[str] = None):
        """
        初始化拖拽检测器
        
        Args:
            supported_formats: 支持的文件格式列表，如 ['.gltf', '.glb', '.fbx']
        """
        self.supported_formats = supported_formats or ['.gltf', '.glb', '.fbx', '.bam', '.egg', '.obj']
        self.is_running = False
        self.monitor_thread = None
        self.file_queue = queue.Queue()
        self.drop_callback: Optional[Callable[[List[str]], None]] = None
        
    def set_drop_callback(self, callback: Callable[[List[str]], None]):
        """
        设置文件拖拽回调函数
        
        Args:
            callback: 接收文件路径列表的回调函数
        """
        self.drop_callback = callback
        
    def start_monitoring(self):
        """开始监控拖拽事件"""
        if not self.is_running:
            self.is_running = True
            self.monitor_thread = threading.Thread(target=self._monitor_loop, daemon=True)
            self.monitor_thread.start()
            
    def stop_monitoring(self):
        """停止监控拖拽事件"""
        self.is_running = False
        if self.monitor_thread:
            self.monitor_thread.join(timeout=1.0)
            
    def get_dropped_files(self) -> List[str]:
        """获取拖拽的文件列表"""
        files = []
        while not self.file_queue.empty():
            try:
                files.append(self.file_queue.get_nowait())
            except queue.Empty:
                break
        return files
        
    def add_dropped_file(self, file_path: str):
        """
        添加拖拽的文件路径
        
        Args:
            file_path: 拖拽的文件路径
        """
        if self._is_supported_format(file_path):
            self.file_queue.put(file_path)
            if self.drop_callback:
                self.drop_callback([file_path])
                
    def _is_supported_format(self, file_path: str) -> bool:
        """检查文件格式是否支持"""
        _, ext = os.path.splitext(file_path.lower())
        return ext in self.supported_formats
        
    @abstractmethod
    def _monitor_loop(self):
        """监控循环，由子类实现"""
        pass
        
    @abstractmethod
    def is_supported(self) -> bool:
        """检查当前平台是否支持此检测器"""
        pass


class DragDetectorFactory:
    """拖拽检测器工厂类"""
    
    @staticmethod
    def create_detector(supported_formats: List[str] = None) -> BaseDragDetector:
        """
        根据当前平台创建合适的拖拽检测器
        
        Args:
            supported_formats: 支持的文件格式列表
            
        Returns:
            适合当前平台的拖拽检测器实例
        """
        system = platform.system().lower()
        
        if system == 'windows':
            from .windows_detector import WindowsDragDetector
            return WindowsDragDetector(supported_formats)
        elif system == 'linux':
            from .linux_detector import LinuxDragDetector
            return LinuxDragDetector(supported_formats)
        elif system == 'darwin':  # macOS
            from .macos_detector import MacOSDragDetector
            return MacOSDragDetector(supported_formats)
        else:
            # 降级到基础检测器
            from .fallback_detector import FallbackDragDetector
            return FallbackDragDetector(supported_formats)