"""Tests for eta-splitting exploration (Theorems CO-CR)."""

import pytest
from watkins_nn.eta_splitting import (
    global_attractor_search,
    temperature_sweep,
    asymmetric_response_function,
    exchange_coherence_separation,
)


class TestTheoremCO:
    """Global Z3 Attractor (Theorem CO)."""

    def test_all_converge_to_z3(self):
        """1000 random starts all converge to Z3 equilibrium."""
        r = global_attractor_search(n_starts=500)
        assert r['z3_is_unique_attractor']

    def test_basin_fraction_100_percent(self):
        """Basin of attraction covers 100% of the simplex."""
        r = global_attractor_search(n_starts=500)
        assert r['basin_fraction'] > 0.999

    def test_max_deviation_tiny(self):
        """All endpoints within 1e-6 of Z3."""
        r = global_attractor_search(n_starts=200)
        assert r['max_deviation_from_z3'] < 1e-6


class TestTheoremCP:
    """Temperature-Dependent Z3 Stability (Theorem CP)."""

    def test_no_phase_transition(self):
        """Z3 symmetric at all temperatures 0.3 to 3.0."""
        r = temperature_sweep(n_temps=20)
        assert r['no_phase_transition']

    def test_delta_always_zero(self):
        """|eta_s - eta_d| < 1e-6 at all temperatures."""
        r = temperature_sweep(n_temps=20)
        assert r['max_delta'] < 1e-6

    def test_lambda_varies_with_T(self):
        """Equilibrium lambda shifts with temperature (expected)."""
        r = temperature_sweep(n_temps=20)
        assert r['lambda_eq_varies_with_T']


class TestTheoremCQ:
    """Asymmetric Response Function (Theorem CQ)."""

    def test_linear_response(self):
        """Small-eps response is linear (R² > 0.99)."""
        r = asymmetric_response_function(n_eps=20)
        assert r['linear_regime']

    def test_susceptibility_nonzero(self):
        """Susceptibility chi is nonzero (system responds)."""
        r = asymmetric_response_function(n_eps=20)
        assert abs(r['susceptibility_chi']) > 0.01

    def test_response_opposes_perturbation(self):
        """Adding eps*eta_s penalty decreases eta_s (chi < 0)."""
        r = asymmetric_response_function(n_eps=20)
        assert r['susceptibility_chi'] < 0


class TestTheoremCR:
    """Exchange-Coherence Timescale Separation (Theorem CR)."""

    def test_exchange_faster_than_coherence(self):
        """Exchange mode relaxes faster than coherence mode."""
        r = exchange_coherence_separation()
        assert r['exchange_faster']

    def test_separation_ratio_approx_1_5(self):
        """Eigenvalue ratio mu_exchange/mu_coherence ≈ 1.54."""
        r = exchange_coherence_separation()
        assert 1.4 < r['eigenvalue_separation'] < 1.7

    def test_empirical_matches_theory(self):
        """Measured timescale ratio matches eigenvalue prediction."""
        r = exchange_coherence_separation()
        assert r['separation_consistent']

    def test_mu_exchange_about_8(self):
        """Exchange eigenvalue ≈ 8.04."""
        r = exchange_coherence_separation()
        assert 7.5 < r['mu_exchange'] < 8.5

    def test_mu_coherence_about_5(self):
        """Coherence eigenvalue ≈ 5.22."""
        r = exchange_coherence_separation()
        assert 4.8 < r['mu_coherence'] < 5.6
