import json
import math
import os
from pathlib import Path

ROOT = Path(".")

INPUT_FIRST = ROOT / "results" / "row20_h0_attribution" / "row20_NZ_CFGL_bridge_operator.json"

OUTPUT_JSON = ROOT / "results" / "row20_h0_attribution" / "row20_second_operator_test.json"
OUTPUT_REPORT = ROOT / "results" / "row20_h0_attribution" / "row20_second_operator_test.md"


def load(path):
    with open(path, "r", encoding="utf-8") as f:
        return json.load(f)


def rss(vals):
    return math.sqrt(sum(v * v for v in vals))


def chi2(vals):
    return sum(v * v for v in vals)


def sign(x):
    if x > 0:
        return "+"
    if x < 0:
        return "-"
    return "0"


def main():
    data = load(INPUT_FIRST)

    # Residuals AFTER first operator
    r = data["transformed_residual_vector"]

    # SECOND OPERATOR (SN-pivot anchored)
    b2 = abs(r["r_SN"])

    transformed2 = {
        "r_ell_A": r["r_ell_A"] - b2,
        "r_H_BAO": r["r_H_BAO"] - b2,
        "r_D_M_BAO": r["r_D_M_BAO"],  # already neutralized
        "r_SN": r["r_SN"] + b2,
        "r_SH0ES": r["r_SH0ES"] + b2,
    }

    original_vals = list(r.values())
    transformed_vals = list(transformed2.values())

    original_rss = rss(original_vals)
    transformed_rss = rss(transformed_vals)

    original_chi2 = chi2(original_vals)
    transformed_chi2 = chi2(transformed_vals)

    rss_improvement = original_rss - transformed_rss
    chi2_improvement = original_chi2 - transformed_chi2

    original_signs = {k: sign(v) for k, v in r.items()}
    transformed_signs = {k: sign(v) for k, v in transformed2.items()}

    # Lawful constraints:
    no_forbidden_flip = (
        transformed2["r_ell_A"] >= 0
        and transformed2["r_H_BAO"] >= 0
        and transformed2["r_SN"] == 0
        and transformed2["r_SH0ES"] <= 0
    )

    tests = {
        "second_anchor_is_SN": b2 == abs(r["r_SN"]),
        "SN_neutralized": transformed2["r_SN"] == 0,
        "sign_structure_preserved": no_forbidden_flip,
        "rss_improves": rss_improvement > 0,
        "rss_improvement_meaningful": rss_improvement >= 0.5,
        "chi2_improves": chi2_improvement > 0,
    }

    score = sum(1 for v in tests.values() if v)
    max_score = len(tests)

    if score == max_score:
        status = "second_operator_supported"
    elif score >= 4:
        status = "second_operator_partial"
    else:
        status = "second_operator_not_supported"

    interpretation = [
        "Second operator anchored to SN pivot residual.",
        "Tests whether remaining tension can be further reduced without breaking layered structure.",
        "If successful, indicates multi-layer resolution path inside UTFANSWF."
    ]

    result = {
        "signature": "ROW20_SECOND_OPERATOR_TEST_v1",
        "context": "DIAGNOSTIC_NON_GATING",
        "second_bridge_strength": b2,
        "input_residual_vector": r,
        "transformed_residual_vector": transformed2,
        "original_rss": original_rss,
        "transformed_rss": transformed_rss,
        "rss_improvement": rss_improvement,
        "original_chi2": original_chi2,
        "transformed_chi2": transformed_chi2,
        "chi2_improvement": chi2_improvement,
        "tests": tests,
        "score": score,
        "max_score": max_score,
        "interpretation": interpretation,
        "verdict": f"{status}; diagnostic only; no physics or parameter changes."
    }

    OUTPUT_JSON.parent.mkdir(parents=True, exist_ok=True)

    with open(OUTPUT_JSON, "w", encoding="utf-8") as f:
        json.dump(result, f, indent=2)

    with open(OUTPUT_REPORT, "w", encoding="utf-8") as f:
        f.write("# UTFANSWF v21 — Second Operator Test\n\n")

        f.write("## Second Operator\n\n")
        f.write("| Quantity | Value |\n")
        f.write("|---|---:|\n")
        f.write(f"| b2 (SN pivot) | {b2:.6f} |\n\n")

        f.write("## Residual transformation\n\n")
        f.write("| Node | Before | After |\n")
        f.write("|---|---:|---:|\n")
        for k in r:
            f.write(f"| {k} | {r[k]:.6f} | {transformed2[k]:.6f} |\n")

        f.write("\n## Metrics\n\n")
        f.write(f"| RSS before | {original_rss:.6f} |\n")
        f.write(f"| RSS after | {transformed_rss:.6f} |\n")
        f.write(f"| RSS improvement | {rss_improvement:.6f} |\n")
        f.write(f"| chi2 improvement | {chi2_improvement:.6f} |\n\n")

        f.write("## Tests\n\n")
        for k, v in tests.items():
            f.write(f"- {k}: {v}\n")

        f.write(f"\nScore: {score}/{max_score}\n")
        f.write(f"Verdict: {status}\n")

    print("Second operator test:")
    print(f"b2={b2:.6f}")
    print(f"RSS before={original_rss:.6f}")
    print(f"RSS after={transformed_rss:.6f}")
    print(f"RSS improvement={rss_improvement:.6f}")
    print(f"score={score}/{max_score}")
    print(f"status={status}")


if __name__ == "__main__":
    main()