"""跨段关系 check：例如二级标题以句号结尾后又新起一段。"""

import re
from fastapi_modules.fastapi_leaudit.govdoc_engine.engine.checks import register
from fastapi_modules.fastapi_leaudit.govdoc_engine.engine.checks.base import CheckBase, CheckContext, CheckHit, CheckResult


# 单个附件项末尾的标点：编号(数字+点) + 内容 + 末尾标点
_ATTACH_ITEM_TRAIL_PUNCT = re.compile(r"\d+[\.．][^\d；。，;,.]+?[；。，;,.]")
# 整段是一个附件项
_ATTACH_ITEM_LINE = re.compile(r"^\d+[\.．].+[；。，;,.]\s*$")


@register("cross_role")
class CrossRoleCheck(CheckBase):
    def run(self, ctx: CheckContext) -> CheckResult:
        rules = ctx.stage.rules or []
        paras = ctx.document.paragraphs
        hits: list[CheckHit] = []
        for r in rules:
            t = r.get("type")
            if t == "h2_no_period_then_break":
                for i, p in enumerate(paras):
                    if p.role == "heading_2" and p.text.rstrip().endswith(("。", ".")):
                        if i + 1 < len(paras) and paras[i + 1].text.strip():
                            hits.append(CheckHit(
                                paragraph=p,
                                char_start=len(p.text) - 1, char_end=len(p.text),
                                actual={"text": p.text},
                                message="二级标题在换行分段时不应使用句号；如使用句号则应紧接正文",
                            ))
            elif t == "attachment_item_no_trailing_punct":
                hits.extend(_attachment_item_hits(paras))
        return CheckResult(passed=not hits, hits=hits)


def _attachment_item_hits(paras):
    """从 attachment_marker 起扫描附件区块，找末尾带标点的附件项。"""
    hits: list[CheckHit] = []
    in_attachment = False
    for p in paras:
        text = p.text.strip()
        if not text:
            continue

        if p.role == "attachment_marker":
            in_attachment = True
            # 同段内可能出现 "附件：1.xxx；2.yyy。" 多项一行
            for m in _ATTACH_ITEM_TRAIL_PUNCT.finditer(text):
                hits.append(CheckHit(
                    paragraph=p,
                    char_start=m.start(), char_end=m.end(),
                    actual={"snippet": m.group(0)},
                    message=f'附件项末尾不应有标点："{m.group(0)}"',
                ))
            continue

        if p.role in ("signature", "date", "heading_1"):
            in_attachment = False
            continue

        if in_attachment and _ATTACH_ITEM_LINE.match(text):
            hits.append(CheckHit(
                paragraph=p,
                char_start=len(p.text) - 1, char_end=len(p.text),
                actual={"text": p.text},
                message=f'附件项末尾不应有标点："{text}"',
            ))
    return hits
