"""Entropyk vs TESPy — Migration Guide.

Side-by-side comparison showing how common TESPy patterns translate
to Entropyk's Python API.

This file is a reference guide, not a runnable script.
"""

# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 1. Component Construction                                              │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   from tespy.components import Compressor
#   comp = Compressor("compressor")
#   comp.set_attr(eta_s=0.85)

# Entropyk:
import entropyk

comp = entropyk.Compressor(
    speed_rpm=2900.0,
    efficiency=0.85,
    fluid="R134a",
)


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 2. Condenser / Evaporator                                              │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   from tespy.components import Condenser
#   cond = Condenser("condenser")
#   cond.set_attr(pr=0.98, Q=-50000)

# Entropyk — UA-based heat exchangers:
cond = entropyk.Condenser(ua=5000.0)  # W/K
evap = entropyk.Evaporator(ua=3000.0)  # W/K


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 3. Expansion Valve                                                      │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   from tespy.components import Valve
#   valve = Valve("expansion_valve")

# Entropyk:
valve = entropyk.ExpansionValve(fluid="R134a", opening=0.8)


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 4. Building the Network / System                                        │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   from tespy.networks import Network
#   nw = Network(fluids=["R134a"])
#   nw.add_conns(c1, c2, c3, c4)
#   nw.solve("design")

# Entropyk:
system = entropyk.System()
c = system.add_component(comp)
d = system.add_component(cond)
e = system.add_component(valve)
v = system.add_component(evap)
system.add_edge(c, d)
system.add_edge(d, e)
system.add_edge(e, v)
system.add_edge(v, c)
system.finalize()


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 5. Solving                                                              │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   nw.solve("design")
#   print(nw.res[-1])

# Entropyk — multiple solver strategies:

# Option A: Newton-Raphson (fast, may diverge)
newton = entropyk.NewtonConfig(max_iterations=200, tolerance=1e-6)

# Option B: Picard / Sequential Substitution (slower, more robust)
picard = entropyk.PicardConfig(max_iterations=500, tolerance=1e-4)

# Option C: Fallback (Newton first, then Picard if divergence)
fallback = entropyk.FallbackConfig(newton=newton, picard=picard)

try:
    result = fallback.solve(system)
    print(f"Converged in {result.iterations} iterations")
    print(f"State vector: {result.state_vector}")
except entropyk.TimeoutError as e:
    print(f"Solver timed out: {e}")
except entropyk.SolverError as e:
    print(f"Solver failed: {e}")


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 6. Physical Units                                                       │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy uses raw floats with implicit units.
# Entropyk provides type-safe physical quantities:

p = entropyk.Pressure(bar=12.0)
print(f"Pressure: {p.to_pascals()} Pa = {p.to_bar()} bar = {p.to_kpa()} kPa")

t = entropyk.Temperature(celsius=45.0)
print(f"Temperature: {t.to_kelvin()} K = {t.to_celsius()} °C")

h = entropyk.Enthalpy(kj_per_kg=420.0)
print(f"Enthalpy: {h.to_j_per_kg()} J/kg = {h.to_kj_per_kg()} kJ/kg")

m = entropyk.MassFlow(kg_per_s=0.05)
print(f"Mass flow: {m.to_kg_per_s()} kg/s = {m.to_g_per_s()} g/s")

# Arithmetic on physical types
dp = entropyk.Pressure(bar=10.0) - entropyk.Pressure(bar=3.0)
print(f"Pressure drop: {dp.to_bar()} bar")


# ┌─────────────────────────────────────────────────────────────────────────┐
# │ 7. Error Handling                                                       │
# └─────────────────────────────────────────────────────────────────────────┘

# TESPy:
#   try:
#       nw.solve("design")
#   except Exception:
#       ...

# Entropyk — typed exception hierarchy:
#   EntropykError (base)
#     ├── SolverError
#     │     ├── TimeoutError
#     │     └── ControlSaturationError
#     ├── FluidError
#     ├── ComponentError
#     ├── TopologyError
#     └── ValidationError

try:
    result = newton.solve(system)
except entropyk.TimeoutError:
    print("Increase timeout or use fallback solver")
except entropyk.SolverError:
    print("Try different solver config or initial conditions")
except entropyk.EntropykError:
    print("Catch-all for any Entropyk error")
