"""OCR 行分类：区分印刷题干与手写作答。"""
import re

# 印刷体/题干常见特征
_PRINTED_RE = re.compile(
    r"(第\s*[0-9一二三四五六七八九十百]+题|"
    r"[（(]\s*[0-9一二三四五六七八九十]+\s*[）)]|"
    r"^\s*[0-9]{1,2}\s*[\.．、\)]|"
    r"^[A-Da-d]\s*[\.．、]|"
    r"选择题|填空题|解答题|证明题|计算题|应用题|"
    r"下列|以下|正确|错误|不正确|单选|多选|"
    r"已知|求证|设|若|求|如图|如图所示)",
    re.MULTILINE,
)

# 手写作答常见特征（算式、短碎片）
_HANDWRITE_RE = re.compile(
    r"^[0-9\s+\-×÷*/=≈<>()\[\].,，、%°]+$|"
    r"^[xXyYzZ]\s*[=＝]|"
    r"^\s*\d+\s*[\.．]\s*\d*\s*$"
)


def _line_center_y(line: dict) -> float:
    bbox = line.get("bbox") or [0, 0, 0, 0]
    return (float(bbox[1]) + float(bbox[3])) / 2.0


def _looks_printed(text: str) -> bool:
    t = text.strip()
    if len(t) >= 12 and _PRINTED_RE.search(t):
        return True
    if _PRINTED_RE.match(t):
        return True
    return False


def _looks_handwritten(text: str, confidence: float) -> bool:
    t = text.strip()
    if not t:
        return True
    if _looks_printed(t):
        return False
    if _HANDWRITE_RE.match(t):
        return True
    if len(t) <= 6 and confidence < 0.92:
        return True
    digit_ratio = sum(c.isdigit() or c in "+-×÷*/=≈.%" for c in t) / max(len(t), 1)
    if digit_ratio > 0.55 and len(t) < 20:
        return True
    return False


def split_printed_handwriting(
    lines: list[dict],
    img_height: int,
    *,
    answer_zone_ratio: float = 0.45,
    enabled: bool = True,
) -> tuple[list[int], list[int]]:
    """
    返回 (印刷题干行编号, 手写作答行编号)，编号为 lines 列表下标。
    answer_zone_ratio: 图片高度比例，低于此 y 中心视为题干区，高于视为作答区。
    """
    if not lines or not enabled or img_height <= 0:
        return list(range(len(lines))), []

    split_y = img_height * answer_zone_ratio
    printed_ids: list[int] = []
    handwriting_ids: list[int] = []

    for i, line in enumerate(lines):
        text = line.get("text", "")
        conf = float(line.get("confidence") or 0.0)
        cy = _line_center_y(line)

        if _looks_printed(text):
            printed_ids.append(i)
            continue

        in_answer_zone = cy >= split_y
        if in_answer_zone and _looks_handwritten(text, conf):
            handwriting_ids.append(i)
        elif not in_answer_zone:
            printed_ids.append(i)
        elif in_answer_zone:
            handwriting_ids.append(i)

    if not printed_ids and lines:
        printed_ids = list(range(min(3, len(lines))))

    if not handwriting_ids and len(lines) >= 2:
        handwriting_ids = list(range(max(0, len(lines) - 3), len(lines)))

    return printed_ids, handwriting_ids


def lines_by_indices(lines: list[dict], indices: list[int]) -> list[dict]:
    return [lines[i] for i in indices if 0 <= i < len(lines)]


def text_from_indices(lines: list[dict], indices: list[int]) -> str:
    return "\n".join(lines[i].get("text", "") for i in indices if 0 <= i < len(lines)).strip()
