"""Code-lines scene: highlight a contiguous line range in a code view.

Default pattern targets GitHub's React blob view (``[data-line-number="{n}"]``),
which also covers diff views. Override ``linePattern`` to target the old blob
table (``#LC{n}``) or any other line-keyed element.
"""
from __future__ import annotations

from .. import js_loader
from ..browser import resolve_locator
from . import register


@register("code-lines")
def scene_code_lines(page, scene: dict) -> None:
    start = int(scene["startLine"])
    end = int(scene.get("endLine", start))
    if end < start:
        start, end = end, start
    pattern: str = scene.get("linePattern", '[data-line-number="{n}"]')
    sels = [pattern.replace("{n}", str(n)) for n in range(start, end + 1)]

    resolve_locator(page, sels[0])
    boxes: list[dict] = []
    for sel in sels:
        try:
            loc = page.locator(sel).first
            box = loc.bounding_box()
        except Exception:
            continue
        if box:
            boxes.append(box)
    if not boxes:
        raise RuntimeError(
            f"code-lines: nothing matched pattern {pattern!r} for L{start}..L{end}"
        )

    x = min(b["x"] for b in boxes)
    y = min(b["y"] for b in boxes)
    right = max(b["x"] + b["width"] for b in boxes)
    bottom = max(b["y"] + b["height"] for b in boxes)
    union = {"x": x, "y": y, "width": right - x, "height": bottom - y}

    page.evaluate(
        js_loader.load("highlight"),
        {
            "box": union,
            "pad": scene.get("padding", 4),
            "color": scene.get("color", "#ff9500"),
            "lw": scene.get("lineWidth", 3),
            "label": scene.get("label", f"L{start}–L{end}"),
        },
    )
    page.wait_for_timeout(scene.get("duration", 3500))
