import Erdos1135.ND.LogTime.Count
import Erdos1135.ND.LogTime.A5Section3Time
import Erdos1135.ND.RhinUnconditional
import Erdos1135.ND.Discrepancy.A5ReferenceND31Main

/-!
# Main logarithmic-time ND31 regime

This assembly keeps the caller-selected Rhin/PhaseGap passage exponent all the
way through the time-carrying Section 3 packet, and combines the three
bounded-time top-block charges without weakening that exponent.
-/

namespace Erdos1135
namespace ND

open Filter
open scoped Topology

noncomputable section

theorem syracuseNoHitWithinWindowProb_taoNy_eq_pmfProb_logOddBlockPMF
    (B T : ℕ) (y : ℝ)
    (hmassTao : 0 < Tao.logFinsetMass
      (Tao.taoNyOddWindow y Tao.taoAlpha))
    (hmassND : 0 < Tao.logFinsetMass (oddBlock y)) :
    Tao.syracuseNoHitWithinWindowProb B T
        (Tao.taoNyLo y) (Tao.taoNyHi y Tao.taoAlpha) hmassTao =
      Tao.pmfProb (logOddBlockPMF y hmassND)
        {N | ¬ Tao.syracuseHitsAtMostWithin N.1 B T} := by
  unfold Tao.syracuseNoHitWithinWindowProb Tao.oddLogWindowPMF
    logOddBlockPMF oddBlock Tao.taoNyOddWindow
  rfl

/-- The powered main regime preserves every caller-selected exponent strictly
below the Rhin cap.  Scheduled no-hit is absorbed from its genuine power rate;
the A5 passage term and the final target rate retain the literal `d`. -/
theorem ndRhinND31LogTimeMainRegime_sameD
    (d : ℝ) (hd : 0 < d) (hdCap : d < 5 / 143) :
    NDM2Bounds (1 / 32000 : ℝ) d ∧
      ∃ Nstar : ℕ, 2 ≤ Nstar ∧
        ∃ Cmain : ℝ, 0 ≤ Cmain ∧
          ∀ (N0 : ℕ), Nstar ≤ N0 →
            ∀ (X : ℝ), (N0 : ℝ) < X →
              oddSyracuseLogTimeBadRatio
                  ndSyracuseLogTimeConstant N0 X ≤
                Cmain * (Real.log (N0 : ℝ)) ^ (-d) := by
  rcases existsPhaseGapRhin with ⟨cPhase, hPhase⟩
  have hd20 : d < 1 / 20 := hdCap.trans (by norm_num)
  have hdk : d < 1 / (2 * (143 / 10 : ℝ)) := by
    calc
      d < 5 / 143 := hdCap
      _ = 1 / (2 * (143 / 10 : ℝ)) := by norm_num
  rcases exists_ndA5ReferenceSection3AmbientTimeTerminal
      hPhase hd hd20 hdk with
    ⟨Csec, Btime, hCsec, hBtimeTwo, htime⟩
  rcases ndRhinRate_sameD d hd hdCap with
    ⟨hM2, _h31Old, _h16Old, _h13Old⟩
  refine ⟨hM2, ?_⟩
  rcases hM2 with
    ⟨_CHit, CTr, x0, _hCHit, hCTr, hx0, hM2bounds⟩
  rcases eventually_atTop.1
      (eventually_rpow_neg_one_div_32000_le_log_rpow_neg d) with
    ⟨Qabs, hQabs⟩
  rcases eventually_atTop.1
      eventually_uniformScheduledNoHitProbability_transportSourceY_le with
    ⟨Qsched, hQsched⟩
  let r : ℝ := Tao.taoSection3AmbientRatio
  let e : ℝ := r ^ 2
  let E : ℝ := e ^ (-d)
  let Cprob : ℝ := (184 + CTr) * E + Csec
  let Cmain : ℝ := 2 + 2 * Cprob
  have he : 0 < e := by
    dsimp only [e, r]
    exact pow_pos Tao.taoSection3AmbientRatio_pos 2
  have hE : 0 ≤ E := Real.rpow_nonneg he.le _
  have hCprob : 0 ≤ Cprob := by
    dsimp only [Cprob]
    exact add_nonneg
      (mul_nonneg (add_nonneg (by norm_num) hCTr) hE) hCsec
  have hCmain : 0 ≤ Cmain := by
    dsimp only [Cmain]
    positivity
  have hpow :
      Tendsto (fun N : ℕ => (N : ℝ) ^ e) atTop atTop := by
    simpa only [Function.comp_def] using
      (tendsto_rpow_atTop he).comp tendsto_natCast_atTop_atTop
  have hlarge : ∀ᶠ N : ℕ in atTop,
      2 ≤ N ∧ Btime ≤ N ∧ Real.exp 1 ≤ (N : ℝ) ∧
        max x0 (max Qabs Qsched) ≤ (N : ℝ) ^ e := by
    filter_upwards
      [eventually_ge_atTop (2 : ℕ), eventually_ge_atTop Btime,
        tendsto_natCast_atTop_atTop.eventually_ge_atTop (Real.exp 1),
        hpow.eventually_ge_atTop (max x0 (max Qabs Qsched))]
      with N hN htimeN hexpN hcutN
    exact ⟨hN, htimeN, hexpN, hcutN⟩
  rcases eventually_atTop.1 hlarge with ⟨Nstar, hNstar⟩
  refine ⟨Nstar, (hNstar Nstar le_rfl).1, Cmain, hCmain, ?_⟩
  intro N0 hNstarN0 X hN0X
  rcases hNstar N0 hNstarN0 with
    ⟨hN0Two, hBtimeN0, hExpN0, hcutN0⟩
  have hN0OneNat : 1 ≤ N0 := by omega
  have hN0One : (1 : ℝ) ≤ (N0 : ℝ) := by exact_mod_cast hN0OneNat
  have hXOne : 1 ≤ X := hN0One.trans hN0X.le
  have hXpos : 0 < X := zero_lt_one.trans_le hXOne
  have hN0nonneg : (0 : ℝ) ≤ (N0 : ℝ) := Nat.cast_nonneg N0
  have hpowStrict : (N0 : ℝ) ^ e < X ^ e :=
    Real.rpow_lt_rpow hN0nonneg hN0X he
  let q : ℝ := Tao.taoSection3AmbientBoundary X 2
  let y : ℝ := transportSourceY q .alpha
  have hqEq : q = X ^ e := by rfl
  have hcutQ : max x0 (max Qabs Qsched) ≤ q := by
    rw [hqEq]
    exact hcutN0.trans hpowStrict.le
  have hqx0 : x0 ≤ q := (le_max_left _ _).trans hcutQ
  have hqQabs : Qabs ≤ q :=
    (le_max_left Qabs Qsched).trans
      ((le_max_right x0 (max Qabs Qsched)).trans hcutQ)
  have hqQsched : Qsched ≤ q :=
    (le_max_right Qabs Qsched).trans
      ((le_max_right x0 (max Qabs Qsched)).trans hcutQ)
  have hqTwo : 2 ≤ q := hx0.trans hqx0
  have hq : 1 ≤ q := one_le_two.trans hqTwo
  have heOne : e ≤ 1 := by
    dsimp only [e, r]
    nlinarith [Tao.taoSection3AmbientRatio_pos,
      Tao.taoSection3AmbientRatio_lt_one]
  have hqX : q ≤ X := by
    rw [hqEq]
    calc
      X ^ e ≤ X ^ (1 : ℝ) :=
        Real.rpow_le_rpow_of_exponent_le hXOne heOne
      _ = X := by simp
  have hQabsX : Qabs ≤ X := hqQabs.trans hqX
  have hqy : q ≤ y := by
    dsimp only [y, transportSourceY]
    exact Real.self_le_rpow_of_one_le hq Tao.taoAlpha_one_lt.le
  have hyTwo : 2 ≤ y := hqTwo.trans hqy
  have hy : 1 ≤ y := one_le_two.trans hyTwo
  have hX0 : 0 ≤ X := zero_le_one.trans hXOne
  have hyBoundary : y = Tao.taoSection3AmbientBoundary X 1 := by
    dsimp only [y, q, transportSourceY, alpha]
    simpa only [Nat.reduceAdd] using
      Tao.taoSection3AmbientBoundary_succ_rpow hX0 1
  have hupper : y ^ alpha = X := by
    calc
      y ^ alpha =
          (Tao.taoSection3AmbientBoundary X 1) ^ Tao.taoAlpha := by
        rw [hyBoundary]
      _ = Tao.taoSection3AmbientBoundary X 0 := by
        simpa only [Nat.reduceAdd] using
          Tao.taoSection3AmbientBoundary_succ_rpow hX0 0
      _ = X := by simp [Tao.taoSection3AmbientBoundary]
  have hM2q := hM2bounds q hqx0 hq .alpha
  change
      ∃ hwindow : (oddBlock y).Nonempty,
        ∃ hmass : 0 < Tao.logFinsetMass (oddBlock y),
          uniformNoHitProbability q y hwindow ≤
              _CHit * q ^ (-(1 / 32000 : ℝ)) ∧
            passFullL1 q y hq hwindow hmass ≤
              CTr * (Real.log q) ^ (-d) at hM2q
  rcases hM2q with ⟨hwindow, hmass, _hOldHit, hPass⟩
  rcases htime hBtimeN0 hN0X with
    ⟨T, hT, hmassTime, hTimeSource⟩
  have hSource :
      Tao.pmfProb (logOddBlockPMF y hmass)
          {N | ¬ Tao.syracuseHitsAtMostWithin N.1 N0 T} ≤
        Csec * (Real.log (N0 : ℝ)) ^ (-d) := by
    have hmassTimeY : 0 < Tao.logFinsetMass
        (Tao.taoNyOddWindow y Tao.taoAlpha) := by
      simpa only [hyBoundary] using hmassTime
    have hTimeSourceY :
        Tao.syracuseNoHitWithinWindowProb N0 T
            (Tao.taoNyLo y) (Tao.taoNyHi y Tao.taoAlpha) hmassTimeY ≤
          Csec * (Real.log (N0 : ℝ)) ^ (-d) := by
      simpa only [hyBoundary] using hTimeSource
    have heq := syracuseNoHitWithinWindowProb_taoNy_eq_pmfProb_logOddBlockPMF
      N0 T y hmassTimeY hmass
    rw [heq] at hTimeSourceY
    exact hTimeSourceY
  have hScheduled := hQsched q hqQsched .alpha hwindow
  have hclock : ∀ N : ℕ, Nat.ceil y ≤ N →
      ((Tao.taoSection5N0 (Nat.floor q) + T : ℕ) : ℝ) ≤
        ndSyracuseLogTimeConstant * Real.log (N : ℝ) := by
    intro N hNy
    have hNy' :
        Nat.ceil (Tao.taoSection3AmbientBoundary X 1) ≤ N := by
      simpa only [hyBoundary] using hNy
    simpa only [q] using
      (ndTopPassageBudget_cast_le_pointwiseLog hXOne hNy' hT)
  have hCount :=
    oddSyracuseLogTimeBadRatio_le_ceil_div_add_two_mul_timeTerms
      hN0OneNat hq hy hXOne hupper hwindow hmass hclock
  let R : ℝ := (Real.log (N0 : ℝ)) ^ (-d)
  have hN0pos : 0 < (N0 : ℝ) := by positivity
  have hN0OneStrict : (1 : ℝ) < (N0 : ℝ) := by
    exact_mod_cast (show 1 < N0 by omega)
  have hlogN0Pos : 0 < Real.log (N0 : ℝ) :=
    Real.log_pos hN0OneStrict
  have hlogN0One : 1 ≤ Real.log (N0 : ℝ) :=
    (Real.le_log_iff_exp_le hN0pos).2 hExpN0
  have hlogNX : Real.log (N0 : ℝ) < Real.log X :=
    Real.log_lt_log hN0pos hN0X
  have hlogXPos : 0 < Real.log X := hlogN0Pos.trans hlogNX
  have hXRate : (Real.log X) ^ (-d) ≤ R := by
    dsimp only [R]
    exact Real.rpow_le_rpow_of_nonpos hlogN0Pos hlogNX.le
      (neg_nonpos.mpr hd.le)
  have hBottomPower :
      (Nat.ceil y : ℝ) / X ≤
        2 * X ^ (-(1 / 32000 : ℝ)) := by
    rw [hyBoundary]
    exact ceil_taoSection3AmbientBoundary_one_div_le_real_power hXOne
  have hBottom : (Nat.ceil y : ℝ) / X ≤ 2 * R := by
    calc
      (Nat.ceil y : ℝ) / X ≤
          2 * X ^ (-(1 / 32000 : ℝ)) := hBottomPower
      _ ≤ 2 * (Real.log X) ^ (-d) :=
        mul_le_mul_of_nonneg_left (hQabs X hQabsX) (by norm_num)
      _ ≤ 2 * R := mul_le_mul_of_nonneg_left hXRate (by norm_num)
  have hlogqPos : 0 < Real.log q :=
    Real.log_pos (one_lt_two.trans_le hqTwo)
  have hlogqEq : Real.log q = e * Real.log X := by
    rw [hqEq]
    exact Real.log_rpow hXpos e
  have hlogqRate : (Real.log q) ^ (-d) =
      E * (Real.log X) ^ (-d) := by
    rw [hlogqEq]
    dsimp only [E]
    exact Real.mul_rpow he.le hlogXPos.le
  have hlogqRateLe : (Real.log q) ^ (-d) ≤ E * R := by
    rw [hlogqRate]
    exact mul_le_mul_of_nonneg_left hXRate hE
  have hScheduledRate :
      uniformScheduledNoHitProbability q y hwindow ≤ 184 * E * R := by
    calc
      uniformScheduledNoHitProbability q y hwindow ≤
          184 * q ^ (-(1 / 32000 : ℝ)) := hScheduled
      _ ≤ 184 * (Real.log q) ^ (-d) :=
        mul_le_mul_of_nonneg_left (hQabs q hqQabs) (by norm_num)
      _ ≤ 184 * (E * R) :=
        mul_le_mul_of_nonneg_left hlogqRateLe (by norm_num)
      _ = 184 * E * R := by ring
  have hPassRate : passFullL1 q y hq hwindow hmass ≤ CTr * E * R := by
    calc
      passFullL1 q y hq hwindow hmass ≤ CTr * (Real.log q) ^ (-d) := hPass
      _ ≤ CTr * (E * R) :=
        mul_le_mul_of_nonneg_left hlogqRateLe hCTr
      _ = CTr * E * R := by ring
  have hSourceRate :
      Tao.pmfProb (logOddBlockPMF y hmass)
          {N | ¬ Tao.syracuseHitsAtMostWithin N.1 N0 T} ≤ Csec * R :=
    by simpa only [R] using hSource
  calc
    oddSyracuseLogTimeBadRatio ndSyracuseLogTimeConstant N0 X ≤
        (Nat.ceil y : ℝ) / X +
          2 *
            (uniformScheduledNoHitProbability q y hwindow +
              passFullL1 q y hq hwindow hmass +
              Tao.pmfProb (logOddBlockPMF y hmass)
                {N | ¬ Tao.syracuseHitsAtMostWithin N.1 N0 T}) := hCount
    _ ≤ 2 * R + 2 *
          (184 * E * R + CTr * E * R + Csec * R) := by
      gcongr
    _ = Cmain * R := by
      dsimp only [Cmain, Cprob]
      ring
    _ = Cmain * (Real.log (N0 : ℝ)) ^ (-d) := by rfl

/-- Compatibility form of the original existential main-regime endpoint.
The witness `1/40` is now selected only at this wrapper; the producer above
retains every admissible caller-selected exponent. -/
theorem exists_ndRhinND31LogTimeMainRegime :
    ∃ d : ℝ, 0 < d ∧ NDM2Bounds (1 / 32000 : ℝ) d ∧
      ∃ Nstar : ℕ, 2 ≤ Nstar ∧
        ∃ Cmain : ℝ, 0 ≤ Cmain ∧
          ∀ (N0 : ℕ), Nstar ≤ N0 →
            ∀ (X : ℝ), (N0 : ℝ) < X →
              oddSyracuseLogTimeBadRatio
                  ndSyracuseLogTimeConstant N0 X ≤
                Cmain * (Real.log (N0 : ℝ)) ^ (-d) := by
  rcases ndRhinND31LogTimeMainRegime_sameD
      (1 / 40 : ℝ) (by norm_num) (by norm_num) with
    ⟨hM2, hMain⟩
  exact ⟨1 / 40, by norm_num, hM2, hMain⟩

end


end ND
end Erdos1135
