#!/usr/bin/env python3
"""
Worklist parity harness — compares the NEW backend worklist endpoints against
the OLD /lis/results data, for every request, across multiple days + sections.
Paginates /lis/results FULLY (it caps at 25/page). Reports any real mismatch.

OLD worklist truth = distinct requests in /lis/results for the day (the old
screen ignored its `statuses` param, so it showed every LabResult of the day)
+ pre-bench pivots. NEW = /lis/worklist/cards?status_filter=worklist.
"""
import sys, json, urllib.request, urllib.parse, collections

BASE = "https://moonui.elbaset.com/moon-erp-be/api"


def login():
    req = urllib.request.Request(
        BASE + "/auth/login",
        data=json.dumps({"email": "hazem@gt4it.com", "password": "123456789"}).encode(),
        headers={"Content-Type": "application/json", "Accept": "application/json"},
        method="POST",
    )
    return json.load(urllib.request.urlopen(req))["token"]


TOKEN = login()
H = {"X-Authorization": "Bearer " + TOKEN, "Accept": "application/json"}


def get(path):
    req = urllib.request.Request(BASE + path, headers=H)
    return json.load(urllib.request.urlopen(req))


def old_results_all(date, section=None):
    """Fetch ALL pages of /lis/results for a day (caps at 25/page)."""
    fr = urllib.parse.quote(f"{date} 00:00:00")
    to = urllib.parse.quote(f"{date} 23:59:59")
    sec = f"&lab_section_id={section}" if section else ""
    out, page = [], 1
    while True:
        d = get(f"/lis/results?date_from={fr}&date_to={to}&per_page=25&page={page}{sec}")
        rows = d.get("data", [])
        out.extend(rows)
        meta = d.get("meta", {})
        last = meta.get("last_page", 1)
        if page >= last or not rows:
            break
        page += 1
    return out


def status_of(r):
    s = r.get("status")
    return s.get("value") if isinstance(s, dict) else s


def run_day(date, section, label):
    old = old_results_all(date, section)
    old_by_req = collections.defaultdict(dict)
    for r in old:
        rid = r.get("lab_request_id")
        if rid:
            old_by_req[rid][r.get("investigation_id")] = status_of(r)
    old_ids = set(old_by_req)

    cards = get(
        f"/lis/worklist/cards?status_filter=worklist&date_from={date}&date_to={date}"
        + (f"&lab_section_id={section}" if section else "")
    )["data"]
    new_ids = set(c["request_id"] for c in cards)

    missing = sorted(old_ids - new_ids)          # in OLD, not NEW = REAL bug
    extra = sorted(new_ids - old_ids)            # in NEW, not OLD = pre-bench? check

    # per-request test-set comparison (common requests)
    row_mismatch = []
    for rid in sorted(old_ids & new_ids):
        nr = get(f"/lis/worklist/requests/{rid}/rows" + (f"?lab_section_id={section}" if section else ""))
        new_tests = {x["investigation_id"]: x["status"] for x in nr["rows"] if x["display_type"] == "test"}
        old_tests = old_by_req[rid]
        miss = set(old_tests) - set(new_tests)   # test in old not new
        if miss:
            row_mismatch.append((rid, sorted(miss)))

    # classify extras: pre-bench (no LabResult) is acceptable
    extra_prebench, extra_bad = [], []
    for rid in extra:
        has_old = rid in old_by_req
        (extra_bad if has_old else extra_prebench).append(rid)

    ok = (not missing) and (not row_mismatch)
    print(f"  [{label}] old_reqs={len(old_ids)} new_reqs={len(new_ids)} "
          f"| missing={missing or '—'} | extra(prebench)={len(extra_prebench)} "
          f"| row_mismatch={row_mismatch or '—'} -> {'OK' if ok else 'FAIL'}")
    return ok


def main():
    dates = sys.argv[1].split(",") if len(sys.argv) > 1 else ["2026-06-08"]
    sections = get("/lis/sections")["data"]
    sec_ids = [s["id"] for s in sections]
    print(f"Sections: {sec_ids}\n")
    all_ok = True
    for date in dates:
        print(f"=== {date} ===")
        all_ok &= run_day(date, None, "All-Departments")
        for sid in sec_ids:
            all_ok &= run_day(date, sid, f"section {sid}")
        print()
    print("OVERALL:", "ALL MATCH ✅" if all_ok else "MISMATCHES FOUND ❌")
    sys.exit(0 if all_ok else 1)


if __name__ == "__main__":
    main()
