"""Scan swept .tables.json for stacked-table boundary defects.

For every page that holds two or more tables (stacked), check each adjacent
pair for the two failure signatures the title-anchored seam is meant to remove:

  - LEAK/DUP: a data row that appears in both the upper and the lower table
    (the boundary row got captured twice, or pulled into the wrong table).
  - ORPHAN TITLE: a table whose title is a data-bearing string (digits), a sign
    the correction stage swallowed a stray boundary row as a caption.

Reports per document; silent where a page has a single table. Read-only.
"""

from __future__ import annotations

import json
import re
import sys
from pathlib import Path
from typing import Dict, List, Tuple

OUT = Path("output")

SWEEP = [
    "Q1FY26-Visa-Operational-Performance-Data",
    "Q1FY25-Visa-Operational-Performance-Data-FINAL",
    "Q2FY25-Visa-Operational-Performance-Data-FINAL",
    "Q2FY26-Visa-Operational-Performance-Data",
    "Q4FY25-Visa-Operational-Performance-Data",
    "Q1-2026-Earnings-Release_vF",
    "Q2-2026-Earnings-Release_vF",
    "VISA_991_Q126",
    "VISA_991_Q425",
    "Visa-Inc-First-Quarter-2026-Financial-Results-Presentation",
    "Visa-Inc-Fourth-Quarter-2025-Financial-Results-Presentation",
    "Visa-Inc-Second-Quarter-2026-Financial-Results-Presentation",
    "Q1-2026-Investor-Factbook-vFinal",
    "TMUS_992_Q324",
    "TMUS_992_Q224",
    "TMUS_992_Q323",
    "TMUS_992_Q423",
]


VALUE = re.compile(r"^\$?\(?-?[\d,]+\.?\d*%?\)?$")  # a numeric value cell: $1,234 / (5.1%) / -12


def data_rows(md: str) -> List[str]:
    """Normalized DATA rows of a markdown table — rows carrying actual values.

    A data row has at least two cells that are numeric values. This excludes
    the column-header row (whose cells are names, even when one carries a
    footnote marker like "Income Tax Provision(1)") and the `---` separator, so
    two adjacent tables sharing a header are not mistaken for a row leak.
    """
    rows = []
    for line in md.splitlines():
        if not line.strip().startswith("|"):
            continue
        cells = [c.strip() for c in line.strip().strip("|").split("|")]
        value_cells = [c for c in cells if VALUE.match(c.replace(" ", ""))]
        if len(value_cells) < 2:
            continue
        rows.append(re.sub(r"\s+", " ", line.strip()).lower())
    return rows


def has_digit(s: str) -> bool:
    return bool(re.search(r"\d", s or ""))


def analyze(name: str) -> Tuple[int, List[str]]:
    path = OUT / f"{name}.tables.json"
    if not path.exists():
        return 0, [f"  (missing {path.name})"]
    tables = json.loads(path.read_text())
    by_page: Dict[int, List[dict]] = {}
    for t in tables:
        by_page.setdefault(t.get("page", 0), []).append(t)

    findings: List[str] = []
    stacked_pages = 0
    for page, group in sorted(by_page.items()):
        if len(group) < 2:
            continue
        stacked_pages += 1
        rowsets = [(t, set(data_rows(t.get("markdown", "")))) for t in group]
        for (ta, ra), (tb, rb) in zip(rowsets, rowsets[1:]):
            shared = ra & rb
            if shared:
                findings.append(
                    f"  p{page} LEAK: {len(shared)} row(s) in both "
                    f"{ta.get('title','')!r} and {tb.get('title','')!r}; e.g. {next(iter(shared))[:60]!r}"
                )
        for t, _ in rowsets:
            title = t.get("title", "")
            if has_digit(title) and re.search(r"\d[\d,]{2,}", title):
                findings.append(f"  p{page} ORPHAN-TITLE: {title!r}")
    return stacked_pages, findings


def main() -> None:
    total_stacked = 0
    total_findings = 0
    for name in SWEEP:
        stacked, findings = analyze(name)
        total_stacked += stacked
        total_findings += len(findings)
        flag = "OK" if not findings else f"{len(findings)} FINDING(S)"
        print(f"[{flag}] {name}  (stacked pages: {stacked})")
        for f in findings:
            print(f)
    print(f"\nTOTAL stacked pages scanned: {total_stacked}; total findings: {total_findings}")
    sys.exit(0)


if __name__ == "__main__":
    main()
