"""Everything computed AFTER seeing the data. Nothing here is a verdict.

    python after.py > after.txt

The sealed rule is scored by analyse.py and that file alone. This one exists
because the result raised four questions the rule did not ask, and the honest
place for an answer to a question you thought of afterwards is a file that
says so in its first line.

    1. The rule's own statistic put Friday against the Mon..Fri average. The
       histogram says Monday is quieter than Friday. Which weekday is actually
       the smallest?
    2. The six clock offsets were registered as "reported, not scored", and
       they move the answer across both bars. With intervals, which clocks
       would have survived the sealed rule and which would have killed it?
    3. Claim B's proxy is void because the 72 h window holds a different number
       of working days depending on which day it starts. A 168 h window holds
       exactly five working days from EVERY start. Is the negative control
       clean there?
    4. What does the follow-up rate look like against the number of working
       days the window actually contains?
"""

import collections
import datetime as dt
import pathlib
import sys

sys.path.insert(0, str(pathlib.Path(__file__).resolve().parent))

import rule
from analyse import DAYS, follow_ups, load, rr_for, share_table


def main():
    rows, _ = load()
    print("AFTER THE DATA — not part of the sealed rule, not a verdict\n")

    # 1. which weekday is smallest
    counts, _, weekday_n = share_table(rows)
    print("1. the quietest weekday, with intervals on each day's share of Mon..Fri")
    for d in range(5):
        lo, hi = rule.wilson(counts[d], weekday_n)
        print(f"   {DAYS[d]}  {counts[d]/weekday_n:.4f}  [{lo:.4f}, {hi:.4f}]")
    order = sorted(range(5), key=lambda d: counts[d])
    print(f"   smallest: {DAYS[order[0]]}, then {DAYS[order[1]]}")
    lo_m, hi_m = rule.wilson(counts[0], counts[0] + counts[4])
    print(f"   Monday's share of (Mon + Fri): {counts[0]/(counts[0]+counts[4]):.4f} "
          f"[{lo_m:.4f}, {hi_m:.4f}]  — 0.5 would be a tie")

    # 2. the clocks, with intervals against the sealed bars
    print("\n2. the sealed bars applied to each clock (survived hi < "
          f"{rule.A_SURVIVE_HI}, killed lo > {rule.A_KILL_LO})")
    for off in rule.CLOCK_OFFSETS_H:
        c2, f2, n2 = share_table(rows, off)
        lo, hi = rule.wilson(f2, n2)
        print(f"   UTC{off:+.1f}  {f2/n2:.4f}  [{lo:.4f}, {hi:.4f}]  "
              f"-> {rule.verdict_a(lo, hi)}")

    # 3. the day-balanced window
    print("\n3. claim B's negative control at 168 h (a week holds five working")
    print("   days no matter which day it starts on)")
    for w in (24, 72, 168):
        pairs = follow_ups(rows, w)
        *_, trr, tlo, thi = rr_for(pairs, 1, (0, 2, 3))
        *_, frr, flo, fhi = rr_for(pairs, 4, (0, 1, 2, 3))
        clean = rule.CONTROL_TOLERANCE[0] <= trr <= rule.CONTROL_TOLERANCE[1]
        print(f"   {w:>3} h   control(Tue) RR {trr:.4f} [{tlo:.4f}, {thi:.4f}] "
              f"{'clean' if clean else 'DIRTY'}"
              f"   |   Friday RR {frr:.4f} [{flo:.4f}, {fhi:.4f}]")

    # 4. follow-up rate against working days in the window
    print("\n4. the 72 h follow-up rate against the number of Mon..Fri days the")
    print("   window covers (a release at day d covers days d+1, d+2, d+3)")
    pairs = follow_ups(rows, 72)
    for d in range(7):
        n = sum(1 for dd, _ in pairs if dd == d)
        k = sum(1 for dd, hit in pairs if dd == d and hit)
        working = sum(1 for j in range(1, 4) if (d + j) % 7 < 5)
        print(f"   {DAYS[d]}  window holds {working} working days   rate {k/n:.4f}")
    by_working = collections.defaultdict(lambda: [0, 0])
    for d, hit in pairs:
        working = sum(1 for j in range(1, 4) if (d + j) % 7 < 5)
        by_working[working][1] += 1
        by_working[working][0] += hit
    print("   collapsed:")
    for w in sorted(by_working):
        k, n = by_working[w]
        print(f"     {w} working days in the window   {k/n:.4f}   n = {n:,}")


if __name__ == "__main__":
    main()
