"""
Proof: The mean neutron lifetime measured in beam experiments is more than
1 second shorter than the lifetime obtained from ultracold-neutron bottle
experiments.
Generated: 2026-03-28
"""
import json
import os
import re
import sys

PROOF_ENGINE_ROOT = os.environ.get("PROOF_ENGINE_ROOT")
if not PROOF_ENGINE_ROOT:
    _d = os.path.dirname(os.path.abspath(__file__))
    while _d != os.path.dirname(_d):
        if os.path.isdir(os.path.join(_d, "proof-engine", "skills", "proof-engine", "scripts")):
            PROOF_ENGINE_ROOT = os.path.join(_d, "proof-engine", "skills", "proof-engine")
            break
        _d = os.path.dirname(_d)
    if not PROOF_ENGINE_ROOT:
        raise RuntimeError("PROOF_ENGINE_ROOT not set and skill dir not found via walk-up from proof.py")
sys.path.insert(0, PROOF_ENGINE_ROOT)
from datetime import date

# --- STRUCTURAL IMPORTS ---
from scripts.smart_extract import verify_extraction
from scripts.verify_citations import verify_all_citations, build_citation_detail
from scripts.extract_values import parse_number_from_quote
from scripts.computations import compare, explain_calc, cross_check

# ===========================================================================
# 1. CLAIM INTERPRETATION (Rule 4)
# ===========================================================================
CLAIM_NATURAL = (
    "The mean neutron lifetime measured in beam experiments is more than "
    "1 second shorter than the lifetime obtained from ultracold-neutron "
    "bottle experiments."
)
CLAIM_FORMAL = {
    "subject": "neutron lifetime discrepancy between beam and bottle experiments",
    "property": "difference defined as (beam lifetime) minus (bottle lifetime)",
    "operator": "<",
    "operator_note": (
        "The claim asserts beam < bottle by more than 1 second. Formally: "
        "(beam_lifetime - bottle_lifetime) < -1.0. "
        "If the difference is positive (beam > bottle) or within [-1, 0], "
        "the claim is FALSE. We use the world-average values reported in "
        "the physics literature for each method."
    ),
    "threshold": -1.0,
    "unit": "seconds",
}

# ===========================================================================
# 2. FACT REGISTRY
# ===========================================================================
FACT_REGISTRY = {
    "B1": {
        "key": "doe_source",
        "label": "U.S. DOE: beam lifetime 887.7 +/- 2.2 s, bottle lifetime 878.5 +/- 0.8 s",
    },
    "B2": {
        "key": "quanta_source",
        "label": "Quanta Magazine: beam ~14 min 48 s, bottle ~14 min 39 s, gap ~9 s",
    },
    "A1": {
        "label": "Computed difference (beam - bottle) from DOE values",
        "method": None,
        "result": None,
    },
    "A2": {
        "label": "Computed difference (beam - bottle) from Quanta values",
        "method": None,
        "result": None,
    },
    "A3": {
        "label": "Claim evaluation: is (beam - bottle) < -1.0?",
        "method": None,
        "result": None,
    },
}

# ===========================================================================
# 3. EMPIRICAL FACTS
# ===========================================================================
empirical_facts = {
    "doe_source": {
        "source_name": "U.S. Department of Energy, Office of Science",
        "url": "https://www.energy.gov/science/articles/mystery-neutron-lifetime",
        "quote": (
            "One method measures it as 887.7 seconds, plus or minus 2.2 seconds."
        ),
    },
    "doe_source_bottle": {
        "source_name": "U.S. Department of Energy, Office of Science",
        "url": "https://www.energy.gov/science/articles/mystery-neutron-lifetime",
        "quote": (
            "Another method measures it as 878.5 seconds, plus or minus 0.8 second."
        ),
    },
    "quanta_source": {
        "source_name": "Quanta Magazine",
        "url": "https://www.quantamagazine.org/neutron-lifetime-puzzle-deepens-but-no-dark-matter-seen-20180213/",
        "quote": (
            "The gap between the world-average bottle and beam measurements "
            "has only grown slightly — to nine seconds"
        ),
    },
}

# ===========================================================================
# 4. CITATION VERIFICATION (Rule 2)
# ===========================================================================
citation_results = verify_all_citations(empirical_facts, wayback_fallback=True)

print("\n--- Citation Verification ---")
for key, result in citation_results.items():
    print(f"  {key}: {result['status']} (method: {result.get('method', 'N/A')})")

# ===========================================================================
# 5. VALUE EXTRACTION (Rule 1)
# ===========================================================================

# Extract beam lifetime from DOE source
beam_lifetime = parse_number_from_quote(
    empirical_facts["doe_source"]["quote"],
    r"([\d.]+)\s+seconds",
    "B1_beam",
)
print(f"\nExtracted beam lifetime from DOE: {beam_lifetime} s")

# Extract bottle lifetime from DOE source
bottle_lifetime = parse_number_from_quote(
    empirical_facts["doe_source_bottle"]["quote"],
    r"([\d.]+)\s+seconds",
    "B1_bottle",
)
print(f"Extracted bottle lifetime from DOE: {bottle_lifetime} s")

# Extract gap from Quanta source (in minutes:seconds for cross-check)
# Quanta says beam is "14 minutes and 48 seconds" and bottle is "14 minutes and 39 seconds"
# The gap quote says "nine seconds"
quanta_gap_quote = empirical_facts["quanta_source"]["quote"]
# Extract "nine" as a number
gap_word_match = re.search(r'\b(nine)\b', quanta_gap_quote.lower())
if gap_word_match:
    word_to_num = {"nine": 9}
    quanta_gap = float(word_to_num[gap_word_match.group(1)])
    print(f"Extracted gap from Quanta: {quanta_gap} s")
else:
    quanta_gap = None
    print("WARNING: Could not extract gap from Quanta quote")

# Verify extractions are present in the quotes
beam_in_quote = verify_extraction(beam_lifetime, empirical_facts["doe_source"]["quote"], "B1_beam")
bottle_in_quote = verify_extraction(bottle_lifetime, empirical_facts["doe_source_bottle"]["quote"], "B1_bottle")

# ===========================================================================
# 6. COMPUTATION (Rule 7)
# ===========================================================================

# A1: Compute difference from DOE values
difference_doe = explain_calc(
    "beam_lifetime - bottle_lifetime",
    {"beam_lifetime": beam_lifetime, "bottle_lifetime": bottle_lifetime},
    label="A1: beam minus bottle (DOE)",
)

# A2: Cross-check with Quanta's stated gap
# Quanta says the gap is 9 seconds (beam > bottle)
if quanta_gap is not None:
    difference_quanta = quanta_gap  # Quanta states beam is longer by 9 s
    print(f"\nA2: Quanta reports gap of {quanta_gap} s (beam > bottle)")

# ===========================================================================
# 7. CROSS-CHECK (Rule 6)
# ===========================================================================

# Cross-check: DOE difference vs Quanta gap
if quanta_gap is not None:
    cross_check(
        abs(difference_doe),
        quanta_gap,
        tolerance=0.5,
        mode="absolute",
        label="DOE difference vs Quanta gap",
    )

# ===========================================================================
# 8. CLAIM EVALUATION
# ===========================================================================

# The claim says beam is MORE THAN 1 second SHORTER than bottle.
# Formally: (beam - bottle) < -1.0
# We found beam - bottle = +9.2 (beam is LONGER, not shorter)
claim_holds = compare(
    difference_doe,
    CLAIM_FORMAL["operator"],
    CLAIM_FORMAL["threshold"],
    label="A3: Is (beam - bottle) < -1.0?",
)

# ===========================================================================
# 9. ADVERSARIAL CHECKS (Rule 5)
# ===========================================================================
adversarial_checks = [
    {
        "question": (
            "Could the claim be using a non-standard definition where 'beam' "
            "refers to a different measurement technique?"
        ),
        "verification_performed": (
            "Searched web for 'neutron lifetime beam experiment definition method'. "
            "All sources consistently define beam experiments as measuring decay "
            "products (protons) from cold neutron beams, yielding ~887-888 s. "
            "Bottle experiments trap ultracold neutrons and count survivors, "
            "yielding ~878-879 s. No alternative definition found."
        ),
        "finding": (
            "The two methods are universally defined consistently across all "
            "sources. Beam always gives the longer lifetime."
        ),
        "breaks_proof": False,
    },
    {
        "question": (
            "Is there any recent measurement where a beam experiment "
            "produced a shorter lifetime than the bottle average?"
        ),
        "verification_performed": (
            "Searched web for 'neutron lifetime beam experiment new result 2024 2025'. "
            "Checked PDG 2024 data. The most recent beam measurement is YUE 2013 "
            "at 887.7 +/- 1.2 s. No beam experiment has ever produced a result "
            "below the bottle average of ~878 s. The BL2 experiment at NIST is "
            "ongoing but has not published a result contradicting this."
        ),
        "finding": (
            "No beam experiment result is shorter than the bottle average. "
            "The discrepancy has persisted since the 2000s with beam consistently higher."
        ),
        "breaks_proof": False,
    },
    {
        "question": (
            "Could 'shorter' in the claim refer to something other than "
            "the numerical value (e.g., measurement duration)?"
        ),
        "verification_performed": (
            "Linguistic analysis of the claim. 'The mean neutron lifetime "
            "measured in beam experiments is more than 1 second shorter' "
            "unambiguously refers to the numerical value of the measured lifetime."
        ),
        "finding": (
            "The claim clearly refers to the measured lifetime value, "
            "not the experiment duration. No alternative reading is plausible."
        ),
        "breaks_proof": False,
    },
]

# ===========================================================================
# 10. VERDICT AND STRUCTURED OUTPUT
# ===========================================================================
if __name__ == "__main__":
    any_unverified = any(
        cr["status"] != "verified" for cr in citation_results.values()
    )

    if claim_holds and not any_unverified:
        verdict = "PROVED"
    elif claim_holds and any_unverified:
        verdict = "PROVED (with unverified citations)"
    elif not claim_holds and not any_unverified:
        verdict = "DISPROVED"
    elif not claim_holds and any_unverified:
        verdict = "DISPROVED (with unverified citations)"
    else:
        verdict = "UNDETERMINED"

    FACT_REGISTRY["A1"]["method"] = "explain_calc('beam_lifetime - bottle_lifetime')"
    FACT_REGISTRY["A1"]["result"] = f"{difference_doe} s"
    FACT_REGISTRY["A2"]["method"] = "Quanta Magazine reported gap"
    FACT_REGISTRY["A2"]["result"] = f"{quanta_gap} s (beam > bottle)"
    FACT_REGISTRY["A3"]["method"] = "compare(difference, '<', -1.0)"
    FACT_REGISTRY["A3"]["result"] = str(claim_holds)

    citation_detail = build_citation_detail(
        FACT_REGISTRY, citation_results, empirical_facts
    )

    extractions = {
        "B1_beam": {
            "value": str(beam_lifetime),
            "value_in_quote": beam_in_quote,
            "quote_snippet": empirical_facts["doe_source"]["quote"][:80],
        },
        "B1_bottle": {
            "value": str(bottle_lifetime),
            "value_in_quote": bottle_in_quote,
            "quote_snippet": empirical_facts["doe_source_bottle"]["quote"][:80],
        },
        "B2_gap": {
            "value": str(quanta_gap),
            "value_in_quote": True,
            "quote_snippet": empirical_facts["quanta_source"]["quote"][:80],
        },
    }

    summary = {
        "fact_registry": {
            fid: {k: v for k, v in info.items()}
            for fid, info in FACT_REGISTRY.items()
        },
        "claim_formal": CLAIM_FORMAL,
        "claim_natural": CLAIM_NATURAL,
        "citations": citation_detail,
        "extractions": extractions,
        "cross_checks": [
            {
                "description": "DOE computed difference vs Quanta reported gap",
                "values_compared": [str(abs(difference_doe)), str(quanta_gap)],
                "agreement": abs(abs(difference_doe) - quanta_gap) <= 0.5,
            },
        ],
        "adversarial_checks": adversarial_checks,
        "verdict": verdict,
        "key_results": {
            "beam_lifetime_s": beam_lifetime,
            "bottle_lifetime_s": bottle_lifetime,
            "difference_beam_minus_bottle_s": difference_doe,
            "claim_threshold_s": CLAIM_FORMAL["threshold"],
            "operator": CLAIM_FORMAL["operator"],
            "claim_holds": claim_holds,
            "actual_direction": "beam is LONGER than bottle (opposite of claim)",
        },
        "generator": {
            "name": "proof-engine",
            "version": open(os.path.join(PROOF_ENGINE_ROOT, "VERSION")).read().strip(),
            "repo": "https://github.com/yaniv-golan/proof-engine",
            "generated_at": date.today().isoformat(),
        },
    }

    print("\n=== PROOF SUMMARY (JSON) ===")
    print(json.dumps(summary, indent=2, default=str))
