import ctypes
import os
import time

from win32com.client import Dispatch

from tools.log import logger


class Dm:
    def __init__(self):
        """创建当前大漠对象。"""
        self.dm = Dispatch('dm.dmsoft')

    @staticmethod
    def reg_free(dm_path):
        """
        免注册加载大漠插件的 DLL 文件。

        :param dm_path: DLL 文件路径
        """
        try:
            dm_dll = os.path.join(dm_path, 'dm.dll')
            dm_reg_dll = os.path.join(dm_path, 'DmReg.dll')
            # 确保 DLL 文件存在
            if not os.path.exists(dm_dll):
                return False, f"{dm_dll} not found."

            # 加载 DLL 并创建大漠插件对象
            patch = ctypes.windll.LoadLibrary(dm_reg_dll)
            patch.SetDllPathW(dm_dll, 0)
            dm = Dispatch('dm.dmsoft')  # 创建对象
            ver = dm.ver()
            return True, ver
        except Exception as e:
            return False, f"加载大漠插件失败: - {e}"

    def __getattr__(self, name):
        """
        通过代理调用大漠插件的 COM 方法。

        :param name: 大漠插件的方法名
        :return: 对应的方法
        """

        def method(*args):
            return getattr(self.dm, name)(*args)
        return method

    def register_vip(self, reg_code: str, extra_code: str):
        """
        注册大漠插件。

        :param reg_code: 注册码
        :param extra_code: 附加码
        :return: 0 - 失败，1 - 成功
        """
        return self.dm.Reg(reg_code, extra_code)

    def get_version(self):
        """
        获取大漠插件版本号。

        :return: 版本号字符串
        """
        return self.dm.Ver()

    def get_path(self):
        """
        获取全局路径
        :return:当前设置的全局路径
        """
        return self.dm.GetPath()

    def set_path(self, path):
        """
        设置大漠插件的工作路径。

        :param path: 工作路径
        :return: 0 - 失败，1 - 成功
        """
        return self.dm.SetPath(path)

    def bind_window(self, hwnd, display="gdi", mouse="windows", keypad="windows", mode=0):
        """
        绑定指定的窗口。

        :param hwnd: 窗口句柄
        :param display: 显示模式
        :param mouse: 鼠标模式
        :param keypad: 键盘模式
        :param mode: 绑定模式
        :return: 0 - 失败，1 - 成功
        """
        return self.dm.BindWindow(hwnd, display, mouse, keypad, mode)

    def unbind_window(self):
        """
        解除绑定窗口。
        :return: 0 - 失败，1 - 成功
        """
        return self.dm.UnBindWindow()

    def findPic(self, x1, y1, x2, y2, pic_name, delta_color, sim, direction):
        """
        查找图片。

        :param x1: 起始坐标 x
        :param y1: 起始坐标 y
        :param x2: 结束坐标 x
        :param y2: 结束坐标 y
        :param pic_name: 图片文件名
        :param delta_color: 颜色容差
        :param sim: 相似度
        :param direction: 查找方向
        :return:
        """
        intX = -1
        intY = -1
        return self.dm.FindPic(x1, y1, x2, y2, pic_name, delta_color, sim, direction, intX, intY)

    def findMultiColor(self, x1, y1, x2, y2, first_color, offset_color, sim=0.9, direction=0):
        """
        查找多个颜色。
        long FindMultiColor(x1, y1, x2, y2,first_color,offset_color,sim, dir,intX,intY)
        :param x1: 起始坐标 x
        :param y1: 起始坐标 y
        :param x2: 结束坐标 x
        :param y2: 结束坐标 y
        :param first_color: 颜色字符串
        :param offset_color: 颜色容差
        :param sim: 相似度
        :param direction: 查找方向
        :return: (1, intX, intY) 1表示找到 0没找到
        """
        intX = -1
        intY = -1
        ret = self.dm.FindMultiColor(x1, y1, x2, y2, first_color, offset_color, sim, direction, intX, intY)
        return ret

    def find_window(self, class_name, title_name):
        """
        查找窗口句柄。

        :param class_name: 窗口类名
        :param title_name: 窗口标题
        :return: 窗口句柄
        """
        return self.dm.FindWindow(class_name, title_name)

    def capture_screen(self, x1, y1, x2, y2, file_name):
        """
        屏幕截图。

        :param x1: 起始坐标 x
        :param y1: 起始坐标 y
        :param x2: 结束坐标 x
        :param y2: 结束坐标 y
        :param file_name: 截图文件保存路径
        :return: 0 - 失败，1 - 成功
        """
        return self.dm.Capture(x1, y1, x2, y2, file_name)

    # 可以继续添加更多的大漠插件方法

    def MoveTo(self, x, y):
        self.dm.MoveTo(x, y)

    # 鼠标左键点击
    def LeftClick(self):
        self.dm.LeftClick()

    # 移动点击
    def MoveClick(self, x, y, offset_x=0, offset_y=0):
        self.MoveTo(x + offset_x, y + offset_y)
        time.sleep(0.8)
        self.LeftClick()

    # 双击鼠标左键
    def DoubleClick(self, x, y, offset_x=0, offset_y=0):
        self.MoveTo(x + offset_x, y + offset_y)
        time.sleep(0.5)
        self.LeftDoubleClick()

    # 左键长按
    def LeftLongClick(self, x, y, offset_x=0, offset_y=0, duration=2000):
        self.MoveTo(x + offset_x, y + offset_y)
        time.sleep(0.5)
        self.LeftDown()
        time.sleep(duration)
        self.LeftUp()

    def DeleteText(self):
        for i in range(20):
            self.dm.KeyPress(8)
            time.sleep(0.1)

    def SendString(self, handle, text):
        ds = self.dm.SendString(handle, text)
        return ds

    def Capture(self, x1, y1, x2, y2, file):
        """抓取指定区域(x1, y1, x2, y2)的图像,保存为file(24位位图)"""
        return self.dm.Capture(x1, y1, x2, y2, file)

    def Drag(self, x1, y1, x2, y2, duration=1):
        """
        滑动坐标
        :param duration: 耗时
        :param x1: x1
        :param y1: y1
        :param x2: x2
        :param y2: y2
        :return:
        """
        self.dm.MoveTo(x1, y1)
        time.sleep(0.5)
        self.dm.LeftDown()
        time.sleep(0.5)
        x = x2 - x1
        y = y2 - y1
        for i in range(1, 10):
            a = x1 + x / 10 * i
            b = y1 + y / 10 * i
            self.dm.MoveTo(a, b)
            time.sleep(duration / 10)
        self.dm.LeftUp()
        time.sleep(0.5)
