"""
Windows平台拖拽检测器

使用Windows API实现系统级拖拽检测。
"""

import os
import sys
import time
import threading
from typing import List, Optional
from .base_detector import BaseDragDetector


class WindowsDragDetector(BaseDragDetector):
    """Windows平台拖拽检测器"""
    
    def __init__(self, supported_formats: List[str] = None):
        """
        初始化Windows拖拽检测器
        
        Args:
            supported_formats: 支持的文件格式列表
        """
        super().__init__(supported_formats)
        self._hwnd = None
        self._old_win_proc = None
        self._is_com_initialized = False
        self._ole_initialized = False
        
    def _initialize_com(self) -> bool:
        """初始化COM"""
        try:
            import ctypes
            from ctypes import wintypes
            
            # 初始化COM
            ctypes.windll.ole32.CoInitializeEx(None, 0)  # COINIT_APARTMENTTHREADED
            self._is_com_initialized = True
            return True
        except Exception as e:
            print(f"COM初始化失败: {e}")
            return False
            
    def _initialize_ole(self) -> bool:
        """初始化OLE"""
        try:
            import ctypes
            from ctypes import wintypes
            
            # 初始化OLE
            ctypes.windll.ole32.OleInitialize(None)
            self._ole_initialized = True
            return True
        except Exception as e:
            print(f"OLE初始化失败: {e}")
            return False
            
    def _get_window_handle(self) -> Optional[int]:
        """获取Panda3D窗口句柄"""
        try:
            # 这里需要获取Panda3D窗口的句柄
            # 可能需要通过Panda3D的API获取
            # 暂时返回None，需要进一步实现
            return None
        except Exception as e:
            print(f"获取窗口句柄失败: {e}")
            return None
            
    def _setup_drag_drop(self) -> bool:
        """设置拖拽接收"""
        try:
            import ctypes
            from ctypes import wintypes
            
            hwnd = self._get_window_handle()
            if not hwnd:
                return False
                
            # 注册拖拽接收窗口
            # 这里需要实现Windows拖拽API的调用
            # 暂时返回False，需要进一步实现
            return False
        except Exception as e:
            print(f"设置拖拽接收失败: {e}")
            return False
            
    def _monitor_clipboard_drag(self):
        """通过剪贴板监控拖拽"""
        try:
            import ctypes
            from ctypes import wintypes
            
            user32 = ctypes.windll.user32
            kernel32 = ctypes.windll.kernel32
            
            # 监控剪贴板变化
            while self.is_running:
                # 检查剪贴板是否包含文件
                if user32.OpenClipboard(None):
                    try:
                        # 检查是否是文件格式
                        format_id = 15  # CF_HDROP
                        if user32.IsClipboardFormatAvailable(format_id):
                            # 获取拖拽文件列表
                            h_drop = user32.GetClipboardData(format_id)
                            if h_drop:
                                files = self._parse_drop_files(h_drop)
                                for file_path in files:
                                    self.add_dropped_file(file_path)
                    finally:
                        user32.CloseClipboard()
                        
                time.sleep(0.1)
                
        except Exception as e:
            print(f"剪贴板监控错误: {e}")
            
    def _parse_drop_files(self, h_drop) -> List[str]:
        """解析拖拽文件列表"""
        try:
            import ctypes
            from ctypes import wintypes
            
            kernel32 = ctypes.windll.kernel32
            shell32 = ctypes.windll.shell32
            
            # 获取文件数量
            file_count = shell32.DragQueryFileW(h_drop, 0xFFFFFFFF, None, 0)
            files = []
            
            # 获取每个文件路径
            for i in range(file_count):
                # 获取文件路径长度
                length = shell32.DragQueryFileW(h_drop, i, None, 0)
                if length > 0:
                    # 分配缓冲区
                    buffer = ctypes.create_unicode_buffer(length + 1)
                    # 获取文件路径
                    shell32.DragQueryFileW(h_drop, i, buffer, length + 1)
                    files.append(buffer.value)
                    
            return files
        except Exception as e:
            print(f"解析拖拽文件失败: {e}")
            return []
            
    def _monitor_file_drag(self):
        """通过文件系统变化监控拖拽"""
        # 监控用户桌面和下载目录
        import winreg
        
        try:
            # 获取桌面路径
            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, 
                               r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders")
            desktop_path = winreg.QueryValueEx(key, "Desktop")[0]
            downloads_path = winreg.QueryValueEx(key, "{374DE290-123F-4565-9164-39C4925E467B}")[0]  # 下载文件夹
            winreg.CloseKey(key)
        except Exception:
            # 降级到默认路径
            desktop_path = os.path.expanduser("~/Desktop")
            downloads_path = os.path.expanduser("~/Downloads")
            
        watch_dirs = [desktop_path, downloads_path]
        
        while self.is_running:
            try:
                current_time = time.time()
                for watch_dir in watch_dirs:
                    if not os.path.exists(watch_dir):
                        continue
                        
                    for filename in os.listdir(watch_dir):
                        filepath = os.path.join(watch_dir, filename)
                        try:
                            file_time = os.path.getmtime(filepath)
                            # 如果文件是最近1秒内创建的
                            if current_time - file_time < 1.0:
                                if self._is_supported_format(filepath):
                                    self.add_dropped_file(filepath)
                        except OSError:
                            continue
                            
            except Exception as e:
                print(f"文件拖拽监控错误: {e}")
                
            time.sleep(0.5)
            
    def _monitor_loop(self):
        """主监控循环"""
        # 尝试初始化COM和OLE
        com_ready = self._initialize_com()
        ole_ready = self._initialize_ole()
        
        if com_ready and ole_ready:
            # 尝试设置真正的拖拽接收
            if self._setup_drag_drop():
                # 使用Windows API拖拽检测
                pass
            else:
                # 降级到剪贴板监控
                self._monitor_clipboard_drag()
        else:
            # 降级到文件系统监控
            self._monitor_file_drag()
            
        # 清理COM和OLE
        try:
            if self._ole_initialized:
                import ctypes
                ctypes.windll.ole32.OleUninitialize()
            if self._is_com_initialized:
                import ctypes
                ctypes.windll.ole32.CoUninitialize()
        except Exception:
            pass
            
    def is_supported(self) -> bool:
        """检查Windows平台是否支持"""
        return sys.platform.startswith('win')