import cv2
import numpy as np
from XZGUtil.ImagePositioning import window_rectangle
from rapidocr import RapidOCR

# 终极兼容：无参数初始化引擎（适配所有RapidOCR版本，避免参数报错）
engine = RapidOCR()

def search_keyword_in_news_list(win, target_word, score_threshold=0.5):
    """
    新闻列表中精准搜索指定关键词（兼容所有RapidOCR版本，解决文本粘连）
    :param win: 窗口对象（新闻列表所在窗口）
    :param target_word: 要搜索的关键词（如"文章"）
    :param score_threshold: 置信度阈值（过滤低质量识别结果）
    :return: 所有匹配项的坐标列表
    """
    # 1. 截取新闻列表窗口截图
    screenshot = window_rectangle(win)
    window_rect = win.rectangle()
    win_left = window_rect.left
    win_top = window_rect.top

    # 输入校验
    if not isinstance(screenshot, np.ndarray) or screenshot.ndim != 3:
        return []
    img_np = screenshot[:, :, :3]

    # 2. 新闻列表专用预处理（替代use_angle_cls=False的优化效果）
    # 步骤1：强制转为灰度图+正向角度（避免旋转文本干扰）
    gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
    # 步骤2：形态学开运算，去除噪点，分离行文本（提升列表识别准确率）
    kernel = np.ones((2, 2), np.uint8)
    opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
    # 步骤3：自适应二值化，增强行文本对比度（减少粘连）
    processed_gray = cv2.adaptiveThreshold(
        opening, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
        cv2.THRESH_BINARY, blockSize=15, C=3
    )
    # 转回RGB（适配所有RapidOCR版本的输入要求）
    processed_img = cv2.cvtColor(processed_gray, cv2.COLOR_GRAY2RGB)

    # 3. 执行OCR识别（兼容新版RapidOCROutput对象）
    ocr_result_obj = engine(processed_img)
    # 兼容极旧版RapidOCR（返回元组：(结果列表, 耗时)）
    if isinstance(ocr_result_obj, tuple):
        ocr_result = ocr_result_obj[0]
        boxes = [item[0] for item in ocr_result]
        txts = [item[1] for item in ocr_result]
        scores = [item[2] for item in ocr_result]
    else:
        # 新版RapidOCR（RapidOCROutput对象）
        if not hasattr(ocr_result_obj, 'boxes') or len(ocr_result_obj.boxes) == 0:
            return []
        boxes = ocr_result_obj.boxes
        txts = ocr_result_obj.txts
        scores = ocr_result_obj.scores

    # 4. 核心：遍历所有OCR结果，精准匹配关键词（解决文本粘连）
    matched_results = []
    for box, text, score in zip(boxes, txts, scores):
        # 过滤低置信度结果
        score_float = float(score)
        if score_float < score_threshold:
            continue

        text_str = str(text).strip()
        if not text_str or target_word not in text_str:
            continue

        # 转换为屏幕绝对坐标（原始文本框）
        box_list = box.tolist() if hasattr(box, 'tolist') else box
        screen_box = []
        for (x, y) in box_list:
            screen_box.append([int(x) + win_left, int(y) + win_top])
        x1, y1 = screen_box[0]
        x3, y3 = screen_box[2]
        total_width = x3 - x1  # 原始文本框总宽度
        char_width = total_width / len(text_str)  # 每个字符的平均宽度

        # 找到关键词在文本中的位置，计算精准坐标
        start_idx = text_str.index(target_word)
        end_idx = start_idx + len(target_word)
        # 关键词的精准矩形框（适配新闻列表行文本）
        kw_x1 = x1 + int(start_idx * char_width)
        kw_x3 = x1 + int(end_idx * char_width)
        kw_y1 = y1
        kw_y3 = y3

        # 构建匹配结果（保留完整文本+关键词精准坐标）
        matched_results.append({
            'full_text': text_str,       # 列表项完整文本（便于核对）
            'keyword': target_word,      # 匹配的关键词
            'scores': score_float,       # 识别置信度
            'keyword_box': [             # 关键词的精准矩形框
                [kw_x1, kw_y1],
                [kw_x3, kw_y1],
                [kw_x3, kw_y3],
                [kw_x1, kw_y3]
            ],
            'keyword_center': [          # 关键词的精准中心点（便于点击）
                kw_x1 + (kw_x3 - kw_x1) // 2,
                kw_y1 + (kw_y3 - kw_y1) // 2
            ],
            'item_box': screen_box       # 列表项完整文本框（便于定位整行）
        })

    return matched_results
