#!/usr/bin/env python3
"""
verify_P066.py -- Addendum 66: reactor angle and CP phase.

This verifier checks P66's PMNS reactor-angle and CP-phase arithmetic:
  * theta13 = asin(sin(pi/14)/sqrt(2))
  * the dihedral half-angle / full CP-angle formulas
  * Bryant 3-form calibration numerics
  * the PMNS Jarlskog estimate and residual table

P66 contains self-corrections inside the TeX.  The verifier therefore treats
some "wait/revised" sections as part of the audit trail and flags formulas
that remain inconsistent with the final summary.
"""

import math
import sys
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent))
from verify_common import CheckResult, Verifier


class ModernVerifier(Verifier):
    """Local output adapter: tolerance logic byte-identical to
    verify_common.Verifier.check; emits the modern corpus line format
    ("  [PASS] {n:>2}. {desc}") with computed/claimed/tolerance values
    kept as indented info lines, and the modern RESULT footer."""

    def __init__(self, name: str):
        self.name = name
        self.results = []
        self._n = 0
        print(name)

    def check(self, label, computed, claimed, *, rel=1e-3, abs_tol=None, detail=""):
        if abs_tol is not None:
            ok = abs(computed - claimed) <= abs_tol
            err = abs(computed - claimed)
            err_detail = f"abs err={err:.6g}, tol={abs_tol:.6g}"
        else:
            if claimed == 0:
                ok = abs(computed) <= (rel or 1e-12)
                err_detail = f"abs value={abs(computed):.6g}, tol={rel:.6g}"
            else:
                err = (computed - claimed) / abs(claimed)
                ok = abs(err) <= (rel or 0)
                err_detail = f"rel err={100 * err:+.6g}%, tol={100 * (rel or 0):.6g}%"
        return self._emit(label, ok, computed, claimed, err_detail, detail)

    def record(self, label, ok, computed="", claimed="", detail=""):
        return self._emit(label, ok, computed, claimed, "", detail)

    def _emit(self, label, ok, computed, claimed, info, ann):
        full_detail = (info + (f"; {ann}" if ann else "")) if info else ann
        self.results.append(CheckResult(label, ok, computed, claimed, full_detail))
        self._n += 1
        desc = f"{label} -- {ann}" if ann else label
        print(f"  [{'PASS' if ok else 'FAIL'}] {self._n:>2}. {desc}")
        if computed != "" or claimed != "":
            print(f"        computed: {computed}")
            print(f"        claimed : {claimed}")
        if info:
            print(f"        {info}")
        return ok

    def summary(self):
        passed = sum(bool(r.ok) for r in self.results)
        failed = len(self.results) - passed
        print(f"\n{'='*60}\nRESULT: {passed} PASS / {failed} FAIL")
        return 1 if failed else 0


v = ModernVerifier("P066 -- Reactor Angle and CP Phase")

ROOT = Path(__file__).resolve().parents[1]
TEX = (ROOT / "66_Addendum_ReactorAngleCP.tex").read_text()

PI = math.pi
LAM = math.sin(PI / 14)
PDG_SIN13 = 0.14993
PDG_THETA13 = 8.620
PDG_THETA12 = 33.44
PDG_THETA23 = 42.20
PDG_DELTA_CP = -67.0
PDG_DELTA_CKM = 65.6
PDG_J = 0.0265


def deg(rad: float) -> float:
    return math.degrees(rad)


def pct(value: float, target: float) -> float:
    return 100 * (value - target) / abs(target)


theta13_sin = LAM / math.sqrt(2)
theta13_deg = deg(math.asin(theta13_sin))
theta13_nlo_sin = theta13_sin * (1 - LAM**2 / 2)

v.check("lambda = sin(pi/14)", LAM, 0.22252, rel=5e-6)
v.check("theta13 sin LO", theta13_sin, 0.15731, rel=3e-4)
v.check("theta13 angle LO", theta13_deg, 9.05, rel=5e-4)
v.check("theta13 sine residual percent", pct(theta13_sin, PDG_SIN13), 4.9, rel=2e-2)
v.check("theta13 angle residual percent", pct(theta13_deg, PDG_THETA13), 5.0, rel=1e-2)
v.check("theta13 Wolfenstein corrected sine", theta13_nlo_sin, 0.1534, rel=5e-4)
v.check("theta13 corrected residual percent", pct(theta13_nlo_sin, 0.1499), 2.3, rel=5e-2)

trace_claim_wrong = (
    "which has trace\n$\\frac{1}{2}$ in the normalised sense where $\\mathrm{Tr}(E_{ii}) = 1$"
    in TEX
)
v.record(
    "Peirce norm trace arithmetic",
    not trace_claim_wrong,
    "1/2*(Tr Eii + Tr Ejj) = 1 if Tr(Eii)=1",
    "paper says trace 1/2",
    "Expected fail: the written trace arithmetic for the off-diagonal norm is internally inconsistent.",
)

phi_half = PI / 6 + PI / 28
phi_theorem_bad_fraction = (14 * PI + PI) / (28 * 3 / 2)
phi_proposition_fraction = 17 * PI / 42
ckm_phase = PI / 3 + PI / 28
v.check("dihedral half-angle pi/6 + thetaC/2", deg(phi_half), 36.43, rel=5e-4)
v.check(
    "Theorem displayed intermediate fraction",
    deg(phi_theorem_bad_fraction),
    36.43,
    rel=5e-3,
    detail="Expected fail: (14*pi + pi)/(28*3/2) equals about 64.29 degrees, not pi/6 + pi/28.",
)
v.check(
    "SU3 proposition fraction 17*pi/42",
    deg(phi_proposition_fraction),
    36.43,
    rel=5e-3,
    detail="Expected fail: 17*pi/42 is 72.86 degrees; pi/6 + pi/28 is 17*pi/84.",
)
v.check("CKM phase pi/3 + thetaC/2", deg(ckm_phase), 66.43, rel=5e-4)
v.check("delta_CKM residual percent", pct(deg(ckm_phase), PDG_DELTA_CKM), 1.3, rel=5e-2)
v.check("delta_CP final value", -deg(ckm_phase), -66.43, rel=5e-4)
v.check(
    "delta_CP signed residual percent",
    pct(-deg(ckm_phase), PDG_DELTA_CP),
    -0.9,
    rel=5e-2,
    detail="Expected fail under TOE-minus-PDG convention: -66.43 - (-67) is +0.85% of |PDG|, not -0.9%.",
)

psi = 5 * PI / 28
c1, s1 = math.sin(PI / 14), math.cos(PI / 14)
c2, s2 = math.sin(2 * PI / 14), math.cos(2 * PI / 14)
a1 = s1 * math.cos(psi)
a2 = s1 * math.sin(psi)
b1 = s2
minimal_calibration = 0.0
calibration_final = -math.cos(psi) * s1 * s2
alpha_final = deg(math.acos(calibration_final))
v.check("psi = 5*pi/28", deg(psi), 32.14, rel=5e-4)
v.check(
    "u12 e1 component in minimal embedding",
    a1,
    0.8516,
    rel=1e-3,
    detail="Expected fail: with psi=5*pi/28, s1*cos(psi) is about 0.8255.",
)
v.check(
    "u12 e2 component in minimal embedding",
    a2,
    0.4840,
    rel=1e-3,
    detail="Expected fail: with psi=5*pi/28, s1*sin(psi) is about 0.5187.",
)
v.check("u13 e1 component", b1, 0.9010, rel=1e-3)
v.check("minimal Bryant calibration", minimal_calibration, 0.0, abs_tol=1e-12)
v.check(
    "cos(5*pi/28) used in final calibration",
    math.cos(psi),
    0.8526,
    rel=5e-4,
    detail="Expected fail: cos(5*pi/28) is about 0.846724.",
)
v.check(
    "final Bryant calibration product",
    calibration_final,
    -0.7490,
    rel=5e-4,
    detail="Expected fail: exact product is about -0.743745; 0.7490 is the same stale Bryant product seen in later CKM papers.",
)
v.check(
    "final calibration angle alpha",
    alpha_final,
    138.5,
    rel=2e-3,
    detail="Expected fail: exact calibration angle is about 138.05 degrees.",
)
v.record(
    "rotated-calibration proposition matches its proof",
    "Then\n\\begin{equation}\\label{eq:phi-rotated}" not in TEX,
    "proposition states s1*s2*sin(psi)*sin(theta); proof first computes zero for trial rotations, then changes embedding",
    "single derived formula",
    "Expected fail: the displayed rotated formula is not what the proof actually derives for the nonzero Fano-plane embedding.",
)
v.record(
    "CP phase is not defined as arg of a real scalar alone",
    "arg\\bigl(\\varphi(\\hat{u}_{12}, \\hat{u}_{13}, e_7)\\bigr)" not in TEX,
    "arg(varphi(...)) with varphi real",
    "phase from complex/Jarlskog structure",
    "Expected fail: the Bryant calibration is real-valued; its argument alone can only be 0 or pi without extra complex structure.",
)

theta12 = 5 * PI / 28
theta23 = PI / 4
delta_cp = -ckm_phase
j_toe = (
    math.sin(theta12)
    * math.cos(theta12)
    * math.sin(math.asin(theta13_sin))
    * math.cos(math.asin(theta13_sin)) ** 2
    * math.sin(theta23)
    * math.cos(theta23)
    * abs(math.sin(delta_cp))
)
v.check("theta12 prediction", deg(theta12), 32.14, rel=5e-4)
v.check("theta12 residual percent", pct(deg(theta12), PDG_THETA12), -3.9, rel=2e-2)
v.check("theta23 prediction", deg(theta23), 45.0, rel=1e-12)
v.check("theta23 residual percent", pct(deg(theta23), PDG_THETA23), 6.6, rel=1e-2)
v.check(
    "PMNS Jarlskog from TOE angles",
    j_toe,
    0.0297,
    rel=2e-2,
    detail="Expected fail: using the paper's stated angles and the standard J formula gives about 0.0317.",
)
v.check(
    "PMNS Jarlskog residual percent",
    pct(j_toe, PDG_J),
    12.0,
    rel=5e-2,
    detail="Expected fail: exact recomputation gives about +19.5% vs 0.0265.",
)

theta23_sublead = 45 - deg(PI / 28)
v.check("theta23 subleading correction example", theta23_sublead, 38.57, rel=5e-4)
v.check("theta23 subleading residual", pct(theta23_sublead, PDG_THETA23), -8.8, rel=5e-2)

v.record(
    "Phase 5b-ii closure is consistent with structural/open status",
    "Phase~5b-ii is closed" not in TEX,
    "summary says Phase 5b-ii is closed",
    "multiple ingredients remain structural/open",
    "Expected fail: the same paper classifies the CP sign, CKM formula, calibration optimisation, and Cabibbo corrections as structural or open.",
)

sys.exit(v.summary())
