# ---
# jupyter:
#   jupytext:
#     text_representation:
#       extension: .py
#       format_name: percent
# ---

# %% [markdown]
# # Nile River Flow: Detecting the Aswan Dam Break
#
# The annual flow of the Nile at Aswan is a standard dataset in structural
# break literature. The Aswan Low Dam (completed 1902) caused a permanent
# reduction in measured annual flow.
#
# Expected break: around 1898 (when dam construction began).

# %%
import numpy as np
from xtbreak import test, estimate

# Load the Nile river flow data (1871-1970)
# Source: Cobb (1978), available in R datasets
nile_flow = np.array([
    1120, 1160, 963, 1210, 1160, 1160, 813, 1230, 1370, 1140,
    995, 935, 1110, 994, 1020, 960, 1180, 799, 958, 1140,
    1100, 1210, 1150, 1250, 1260, 1220, 1030, 1100, 774, 840,
    874, 694, 940, 833, 701, 916, 692, 1020, 1050, 969,
    831, 726, 456, 824, 702, 1120, 1100, 832, 764, 821,
    768, 845, 864, 862, 698, 845, 744, 796, 1040, 759,
    781, 865, 845, 944, 984, 897, 822, 1010, 771, 676,
    649, 846, 812, 742, 801, 1040, 860, 874, 848, 890,
    744, 749, 838, 1050, 918, 986, 797, 923, 975, 815,
    1020, 906, 901, 1170, 912, 746, 919, 718, 714, 740,
], dtype=np.float64)

years = np.arange(1871, 1971)
x = np.ones((100, 1))  # Constant-only model (testing for mean shift)

# %% [markdown]
# ## Step 1: Test for a structural break
#
# We use the SupF test (H0: 0 breaks vs H1: 1 break) with SSR-based
# variance estimation.

# %%
test_result = test(nile_flow, x, breaks=1, trimming=0.15, vce="ssr")
print("=" * 50)
print("Structural Break Test (SupF)")
print("=" * 50)
print(f"  Hypothesis: H0 (0 breaks) vs H1 (1 break)")
print(f"  SupF statistic: {test_result.statistic:.4f}")
print(f"  Break indices:  {test_result.breaks}")
print()

# %% [markdown]
# ## Step 2: Estimate the break date
#
# We estimate the breakpoint location using SSR-minimizing dynamic
# programming, with time labels corresponding to calendar years.

# %%
est_result = estimate(nile_flow, x, breaks=1, trimming=0.15,
                      time_values=tuple(years.tolist()))

break_est = est_result.break_estimates[0]
print("=" * 50)
print("Break Date Estimation")
print("=" * 50)
print(f"  Estimated break year: {break_est.time_value}")
print(f"  Break index:          {break_est.index}")
print(f"  95% CI (time):        [{break_est.ci_time_value[0]}, "
      f"{break_est.ci_time_value[1]}]")
print(f"  95% CI (index):       [{break_est.ci_index[0]}, "
      f"{break_est.ci_index[1]}]")
print(f"  Global SSR:           {est_result.ssr:.4f}")
print()

# %% [markdown]
# ## Step 3: Examine regime statistics
#
# After estimating the break, we can inspect per-regime regression
# statistics: the mean flow in each regime, standard errors, and fit.

# %%
print("=" * 50)
print("Regime Statistics")
print("=" * 50)
for regime in est_result.regime_statistics:
    print(f"  Regime {regime.regime_index}:")
    start_year = years[regime.start_index] if regime.start_index < len(years) else years[-1]
    end_year = years[min(regime.end_index - 1, len(years) - 1)]
    print(f"    Period:       {start_year}–{end_year}")
    print(f"    Mean flow:    {regime.coefficients[0]:.1f} m³/s")
    print(f"    Std. error:   {regime.standard_errors[0]:.1f}")
    print(f"    Observations: {regime.n_observations}")
    print(f"    R²:           {regime.r_squared:.6f}")
    print(f"    SSR:          {regime.ssr:.2f}")
    print()

# %% [markdown]
# ## Step 4: Chow tests for regime equality

# %%
if est_result.chow_tests:
    print("=" * 50)
    print("Chow Test (Regime Coefficient Equality)")
    print("=" * 50)
    for ct in est_result.chow_tests:
        print(f"  Regime {ct.regime_j} vs Regime {ct.regime_j_plus_1}:")
        print(f"    F-statistic:  {ct.f_statistic:.4f}")
        p_str = f"{ct.p_value:.6f}" if ct.p_value is not None else "N/A"
        print(f"    p-value:      {p_str}")
        print(f"    df:           {ct.degrees_of_freedom}")
    print()

# %% [markdown]
# ## Step 5: Summary output

# %%
print("=" * 50)
print("Summary")
print("=" * 50)
print(est_result.summary())

# %% [markdown]
# ## Interpretation
#
# The break is estimated at **1898**, consistent with the dam construction
# timeline. Mean annual flow dropped from roughly 1100 m³/s to 850 m³/s
# after the break, a reduction of about 23%.
#
# The workflow:
# 1. Test whether a break exists (SupF)
# 2. Estimate the break location with confidence intervals
# 3. Inspect regime-specific statistics
