#!/usr/bin/env python3
"""
T_DM_NULL/run.py

Direct dark-matter null tracker. DCT prediction: sigma_SI = 0 exactly.
This script records the current published exclusion limits from the
three flagship direct-detection experiments (LZ 2023, XENONnT 2023,
PandaX-4T 2023), DAMA/LIBRA's contested claim, and computes the
joint extending-agreement summary for DCT vs LCDM-WIMP.
"""
from __future__ import annotations
import json, hashlib, datetime as _dt, math
from pathlib import Path
import numpy as np
import matplotlib

matplotlib.use("Agg")
import matplotlib.pyplot as plt

HERE = Path(__file__).parent.resolve()

EXPERIMENTS = [
    {"name": "LZ Phase 1 (2023)", "limit_cm2": 9.2e-48, "m_chi_GeV": 36.0,
     "ref": "PRL 131 041002"},
    {"name": "XENONnT (2023)",    "limit_cm2": 2.58e-47, "m_chi_GeV": 28.0,
     "ref": "PRL 131 041003"},
    {"name": "PandaX-4T (2023)",  "limit_cm2": 3.3e-47,  "m_chi_GeV": 40.0,
     "ref": "PRL 127 261802"},
]
DAMA_LIBRA = {"name": "DAMA/LIBRA (2018)", "claimed": "13-sigma annual modulation",
              "ref": "Bernabei 2018", "status": "contested - excluded by xenon"}

CANONICAL_NEUTRALINO_SI = 1e-45  # cm^2, MSSM benchmark
DCT_SIGMA_SI = 0.0


def main() -> None:
    rows = []
    for ex in EXPERIMENTS:
        margin_to_canonical = math.log10(CANONICAL_NEUTRALINO_SI / ex["limit_cm2"])
        rows.append({
            **ex,
            "log10_excludes_below_canonical_neutralino": margin_to_canonical,
            "consistent_with_DCT_zero": True,  # 0 < limit by definition
        })

    classification = "NEUTRAL_EXTENDING_AGREEMENT"
    summary = {
        "test_id": "T_DM_NULL",
        "ran_at_utc": _dt.datetime.utcnow().isoformat(timespec="seconds") + "Z",
        "dct_prediction_sigma_SI_cm2": DCT_SIGMA_SI,
        "canonical_neutralino_sigma_SI_cm2": CANONICAL_NEUTRALINO_SI,
        "experiments": rows,
        "DAMA_LIBRA": DAMA_LIBRA,
        "classification": classification,
        "interpretation": (
            "DCT predicts sigma_SI = 0 exactly. The three flagship xenon-target "
            "direct-detection experiments (LZ, XENONnT, PandaX-4T) all report "
            "null at 90% CL. The strongest exclusion (LZ 2023, 9.2e-48 cm^2) is "
            "100x below the canonical MSSM neutralino expectation, ruling out "
            "wide swaths of WIMP parameter space. DCT remains consistent. The "
            "DAMA/LIBRA annual modulation claim is contested and excluded by "
            "the xenon experiments using the same target. A future positive "
            "WIMP detection at >5 sigma at any direct-detection experiment "
            "would falsify the DCT dark-sector treatment."
        ),
    }

    with open(HERE / "recipe.md", "rb") as fh:
        digest = hashlib.sha256(fh.read()).hexdigest()
    summary["recipe_sha256"] = digest
    (HERE / "recipe.sha256").write_text(digest + "\n")
    (HERE / "result.json").write_text(json.dumps(summary, indent=2))

    md = [
        "# T_DM_NULL — result",
        "",
        f"**Run:** {summary['ran_at_utc']}",
        f"**Recipe SHA-256:** `{digest}`",
        "",
        "## Tracker",
        "",
        "| Experiment | Limit (cm²) | m_χ (GeV) | log₁₀(canonical / limit) | Consistent with DCT (σ_SI=0)? |",
        "|---|---|---|---|---|",
    ]
    for r in rows:
        md.append(f"| {r['name']} | {r['limit_cm2']:.2e} | {r['m_chi_GeV']:.0f} "
                  f"| {r['log10_excludes_below_canonical_neutralino']:+.2f} | YES |")
    md += [
        "",
        f"DAMA/LIBRA: claimed {DAMA_LIBRA['claimed']}; status: contested, "
        f"excluded by xenon experiments. Treated as not-confirmed.",
        "",
        f"**Classification:** **{classification}**.",
        "",
        "## Interpretation",
        "",
        summary["interpretation"],
        "",
        "## Caveat",
        "",
        "- This is an anti-prediction class: DCT cannot generate a positive",
        "  1919-class detection in this channel. Continued nulls extend the",
        "  agreement; a positive detection would clearly falsify.",
        "- A non-WIMP dark-matter candidate (axion, sterile neutrino) detected",
        "  via a non-WIMP channel would also be inconsistent with DCT's",
        "  no-particle-DM stance.",
    ]
    (HERE / "result.md").write_text("\n".join(md) + "\n")

    # figure
    fig, ax = plt.subplots(1, 1, figsize=(7.5, 4))
    names = [r["name"] for r in rows]
    limits = [r["limit_cm2"] for r in rows]
    ax.barh(names, limits, color="C0", alpha=0.6, label="exclusion limit (90% CL)")
    ax.axvline(CANONICAL_NEUTRALINO_SI, color="C3", ls="--",
               label=f"Canonical MSSM neutralino = {CANONICAL_NEUTRALINO_SI:.0e}")
    ax.axvline(1e-50, color="C2", ls=":",
               label="DCT prediction σ_SI = 0 (off-scale)")
    ax.set_xscale("log")
    ax.set_xlabel("σ_SI (cm²)")
    ax.set_xlim(1e-50, 1e-44)
    ax.set_title("T_DM_NULL — direct DM exclusion limits vs DCT prediction (zero) and canonical WIMP")
    ax.legend(loc="lower right", fontsize=7)
    fig.tight_layout()
    fig.savefig(HERE / "figure.png", dpi=140)
    plt.close(fig)

    print(json.dumps(summary, indent=2)[:800] + "\n...")


if __name__ == "__main__":
    main()
