import Mathlib.Data.Fin.Tuple.Basic
import Mathlib.Analysis.Complex.Basic
import Mathlib.Analysis.Complex.TaylorSeries
import Mathlib.Analysis.Calculus.LineDeriv.Basic
import Mathlib.Analysis.Calculus.ContDiff.Defs
import Mathlib.Analysis.Calculus.FDeriv.Basic
import Mathlib.Analysis.Calculus.FDeriv.Symmetric
import Nevanlinna.cauchyRiemann
import Nevanlinna.partialDeriv


noncomputable def Complex.laplace : (ℂ → ℂ) → (ℂ → ℂ) := by
  intro f
  let fx  := Real.partialDeriv 1 f
  let fxx := Real.partialDeriv 1 fx
  let fy  := Real.partialDeriv Complex.I f
  let fyy := Real.partialDeriv Complex.I fy
  exact fxx + fyy


def Harmonic (f : ℂ → ℂ) : Prop :=
  (ContDiff ℝ 2 f) ∧ (∀ z, Complex.laplace f z = 0)


theorem holomorphic_is_harmonic {f : ℂ → ℂ} (h : Differentiable ℂ f) :
  Harmonic f := by

  -- f is real C²
  have f_is_real_C2 : ContDiff ℝ 2 f :=
    ContDiff.restrict_scalars ℝ (Differentiable.contDiff h)

  have fI_is_real_differentiable : Differentiable ℝ (Real.partialDeriv 1 f) := by
    exact (partialDeriv_contDiff f_is_real_C2 1).differentiable (Submonoid.oneLE.proof_2 ℕ∞)

  constructor
  · -- f is two times real continuously differentiable
    exact f_is_real_C2

  · -- Laplace of f is zero
    unfold Complex.laplace
    rw [CauchyRiemann₄ h]

    let l : ℂ →L[ℝ] ℂ := by
      --
      sorry --(fun x ↦ Complex.I • x)
    have : (Complex.I • Real.partialDeriv 1 f) = (l ∘ (Real.partialDeriv 1 f)) := by
      sorry
    rw [this]
    rw [partialDeriv_compContLin]

    --rw [partialDeriv_smul₂ fI_is_real_differentiable]

    rw [partialDeriv_comm f_is_real_C2 Complex.I 1]
    rw [CauchyRiemann₄ h]
    rw [partialDeriv_smul₂ fI_is_real_differentiable]
    rw [← smul_assoc]
    simp
