# -*- coding: utf-8 -*-
import pyautogui
import random
import time
import numpy as np
import cv2
from PIL import Image
import pyscreeze

pyscreeze.USE_IMAGE_NOT_FOUND_EXCEPTION = False

g_isDown = False

def set_isDown(value):
    global g_isDown
    g_isDown = value


def color_string_to_rgb(color_string):
    r = int(color_string[0:2], 16)
    g = int(color_string[2:4], 16)
    b = int(color_string[4:6], 16)
    return (r, g, b)

def savePic(screenshot, fileName):
    image = Image.frombytes('RGB', screenshot.size, screenshot.bgra, 'raw', 'BGRX')
    image.save(fileName)  # 保存为PNG格式的图像文件

def find_center_point(pointArr):
    min_distance = float('inf')
    center_point = None

    for point in pointArr:
        total_distance = 0
        for other_point in pointArr:
            distance = ((other_point[0] - point[0]) ** 2 + (other_point[1] - point[1]) ** 2) ** 0.5
            total_distance += distance

        if total_distance < min_distance:
            min_distance = total_distance
            center_point = point

    return center_point

class pcacc_img:
    def __init__(specifically):
        random.seed()
    
    @staticmethod
    def find_maxColor_position(cur_region, colorArr): #(left, top, width, height)
        left = cur_region[0]
        top = cur_region[1]
        width = cur_region[2]
        height = cur_region[3]
        region = (left, top, width, height)
        # 目标颜色和容差值
         
        tolerance = 10  # 容差值

        # 在指定区域获取屏幕图像
        screenshotSrc = pyautogui.screenshot(region=region)
        print(region)
        
        
        screenshot = np.array(screenshotSrc)
        dstPointArr = []

        # 创建颜色范围的上下界
        for color_str in colorArr:
            target_color = color_string_to_rgb(color_str)
            lower_color = np.array(target_color) - tolerance
            upper_color = np.array(target_color) + tolerance

            # 在图像中查找匹配的像素
            mask = cv2.inRange(screenshot, lower_color, upper_color)
            # 显示 mask 图像
            #plt.imshow(mask, cmap='gray')
            #plt.show()
            points = np.transpose(np.where(mask > 0))

            if len(points) < 5:
                continue

            # 转换坐标到全局坐标系
            points[:, 0] += region[0]
            points[:, 1] += region[1]   
            '''
            # 使用K-means聚类将匹配点分为不同的簇
            n_clusters = 5  # 簇的数量，可根据需要进行调整
            kmeans = KMeans(n_clusters=n_clusters)
            kmeans.fit(points)

            # 找到最大的簇
            max_cluster_label = np.argmax(np.bincount(kmeans.labels_))
            max_cluster_points = points[kmeans.labels_ == max_cluster_label]
            '''
            # 输出最集中的像素区域的位置
            for point in points:
                dstPointArr.append(point)

        if len(dstPointArr) > 0:
            return True, find_center_point(dstPointArr)
        else:
            return False, (-1, -1)
    



    @staticmethod
    def find_img_position(image_path):
        # 设置查找的置信度（confidence）阈值，范围从0到1，默认为0.999
        confidence_threshold = 0.85

        # 查找模糊图片在屏幕上的位置
        position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)

        if position is not None:
            return True, position
        else:
            return False, None
        
    @staticmethod
    def choose_two_point_from_position(position):
        dst_x1 = random.randint(position.left, position.left + position.width)
        dst_y1 = random.randint(position.top, position.top + position.height)

        dst_x2 = random.randint(position.left, position.left + position.width)
        dst_y2 = random.randint(position.top, position.top + position.height)

        return (dst_x1, dst_y1), (dst_x2, dst_y2)

    @staticmethod
    def choose_one_point_from_position(position):
        dst_x1 = random.randint(position.left, position.left + position.width)
        dst_y1 = random.randint(position.top, position.top + position.height)
        return (dst_x1, dst_y1)

    @staticmethod
    def find_all_img(image_path):

        # 设置查找的置信度（confidence）阈值，范围从0到1，默认为0.999
        confidence_threshold = 0.95

        # 查找模糊图片在屏幕上的位置
        positions = pyautogui.locateAllOnScreen(image_path, confidence=confidence_threshold)

        if len(positions) == 0:
            return False, []

        return True, positions
    
    @staticmethod
    def find_img_cv(image_path, region=None, search_order='bottom-up'):
        """
        改进版的模板匹配函数，支持从下往上搜索
        :param image_path: 模板图片路径
        :param region: 截图区域 (left, top, width, height)
        :param search_order: 搜索顺序 ('top-down'或'bottom-up')
        :return: (是否找到, 随机点坐标)
        """
        # 读取模板和屏幕截图
        confidence_threshold = 0.95
        template = cv2.imread(image_path, cv2.IMREAD_COLOR)
        screenshot = cv2.cvtColor(np.array(pyautogui.screenshot(region=region)), cv2.COLOR_RGB2BGR)
        
        # 模板匹配
        result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
        width, height = template.shape[1], template.shape[0]
        
        # 获取所有匹配位置[3,5](@ref)
        loc = np.where(result >= confidence_threshold)
        matches = list(zip(*loc[::-1]))  # 转换为(x,y)坐标列表
        
        if len(matches) == 0:
            return False, (-1, -1)
        
        # 根据搜索顺序排序匹配结果[7](@ref)
        if search_order == 'bottom-up':
            # 从下往上排序：先按y坐标降序，再按x坐标升序
            matches.sort(key=lambda m: (-m[1], m[0]))
        else:  # 默认从上往下
            matches.sort(key=lambda m: (m[1], m[0]))
        
        # 选择第一个匹配结果（根据搜索顺序）
        left, top = matches[0]
        
        # 计算中间区域（避免点击边缘）
        mid_left = int(left + width / 4)
        mid_right = int(left + width / 4 * 3)
        mid_top = int(top + height / 4)
        mid_bottom = int(top + height / 4 * 3)
        
        # 生成随机点击位置
        want_x = random.randint(mid_left, mid_right)
        want_y = random.randint(mid_top, mid_bottom)
        
        # 添加随机偏移（避免每次都点击相同位置）
        dst_x = random.randint(int(want_x - width / 3), int(want_x + width / 3))
        dst_y = random.randint(int(want_y - height / 3), int(want_y + height / 3))
        
        print(f"{image_path}：({dst_x}, {dst_y}) [搜索顺序: {search_order}]")
        return True, (dst_x, dst_y)
    
    @staticmethod
    def find_img_origin(image_path):
        # 设置查找的置信度（confidence）阈值，范围从0到1，默认为0.999
        confidence_threshold = 0.95

        # 查找模糊图片在屏幕上的位置
        position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)

        if position is not None:

            #dst_position
            dst_x = position.left
            dst_y = position.top

            print(f"{image_path} origin：({dst_x}, {dst_y})")
            return True, (dst_x, dst_y)
        else:
            return False, (-1, -1)
        
    def find_img_down(image_path):
        # 设置查找的置信度（confidence）阈值，范围从0到1，默认为0.999
        confidence_threshold = 0.95

        # 查找模糊图片在屏幕上的位置
        positionAll = pyautogui.locateAllOnScreen(image_path, confidence=confidence_threshold)

        location_list = list(positionAll)
        localtion_sort = sorted(location_list, key=lambda x: x.top, reverse=True)

        if len(localtion_sort) == 0:
            return False, (-1, -1)

        position = localtion_sort[0]
        if position is not None:
            # 图片找到了，获取图片的中心点坐标
            #mid
            mid_left = int(position.left + position.width / 4)
            mid_right = int(position.left + position.width / 4 * 3)
            mid_top = int(position.top + position.height / 4)
            mid_bottom = int(position.top + position.height / 4 * 3)

            #want_position
            want_x = random.randint(mid_left, mid_right)
            want_y = random.randint(mid_top, mid_bottom)

            #dst_position
            dst_x = random.randint(int(want_x - position.width / 3), int(want_x + position.width / 3))
            dst_y = random.randint(int(want_y - position.height / 3), int(want_y + position.height / 3))
            

            print(f"down {image_path}：({dst_x}, {dst_y})")
            return True, (dst_x, dst_y)
        else:
            return False, (-1, -1)





    def find_img(image_path):

        # 设置查找的置信度（confidence）阈值，范围从0到1，默认为0.999
        confidence_threshold = 0.92

        # 查找模糊图片在屏幕上的位置
        position = pyautogui.locateOnScreen(image_path, confidence=confidence_threshold)

        if position is not None:
            # 图片找到了，获取图片的中心点坐标
            #mid
            mid_left = int(position.left + position.width / 4)
            mid_right = int(position.left + position.width / 4 * 3)
            mid_top = int(position.top + position.height / 4)
            mid_bottom = int(position.top + position.height / 4 * 3)

            #want_position
            want_x = random.randint(mid_left, mid_right)
            want_y = random.randint(mid_top, mid_bottom)

            #dst_position
            dst_x = random.randint(int(want_x - position.width / 3), int(want_x + position.width / 3))
            dst_y = random.randint(int(want_y - position.height / 3), int(want_y + position.height / 3))
            

            print(f"{image_path}：({dst_x}, {dst_y})")
            return True, (dst_x, dst_y)
        else:
            return False, (-1, -1)

    @staticmethod
    def find_imgArr(imgArr):
        global g_isDown
        for cur_img in imgArr:
            if g_isDown:
                ret, pos = pcacc_img.find_img_down(cur_img)
            else:
                ret, pos = pcacc_img.find_img(cur_img)
            if ret:
                return ret, pos
        return False, None
    
    @staticmethod
    def find_imgArr_cv(imgArr):
        for cur_img in imgArr:
            ret, pos = pcacc_img.find_img_cv(cur_img)
            if ret:
                return ret, pos
        return False, None

    @staticmethod
    def find_imgs(images, is_cv=False):
        global g_isDown
        if is_cv:
            return pcacc_img.find_imgs_cv(images)
        else:
            if isinstance(images, str):
                if g_isDown:
                    return pcacc_img.find_img_down(images)
                else:
                    return pcacc_img.find_img(images)
            elif isinstance(images, (list, tuple)):
                return pcacc_img.find_imgArr(images)
            else:
                raise ValueError("Invalid input type for 'images' parameter.")
        
    @staticmethod
    def find_imgs_cv(images):
        if isinstance(images, str):
            return pcacc_img.find_img_cv(images)
        elif isinstance(images, (list, tuple)):
            return pcacc_img.find_imgArr_cv(images)
        else:
            raise ValueError("Invalid input type for 'images' parameter.")

    @staticmethod
    def find_all_image_locations(image):
        confidence_threshold = 0.90
        # 查找所有符合条件的图片位置
        locations = pyautogui.locateAllOnScreen(image, confidence=confidence_threshold)

        # 将位置信息保存到列表中
        image_locations = []
        for location in locations:
            # 获取位置信息的左上角坐标和宽高
            x, y, width, height = location
            # 将位置信息添加到列表中
            image_locations.append((x, y, width, height))

        return image_locations
    @staticmethod
    def find_img_in_area(image,region=None):
        confidence_threshold = 0.85
        location = pyautogui.locateOnScreen(image,region=region, confidence=confidence_threshold)
        if location is not None:
            return True
        return False
    

if __name__ == '__main__':
    time.sleep(2)
    begin = time.time()
    pcacc_img.find_maxColor_position((200, 200, 800, 200), {'2EA043'})
    cost = time.time() - begin
    print("函数执行耗时：", cost, "秒")