import numpy as np
import matplotlib.pyplot as plt

# ======================================================
# PARAMETRI MODEL
# ======================================================

# Dinamica activitatii economice
A = 1.2
B = 0.10
m = 0.006   # coeficient de absorbtie / limitare

# Legatura dintre activitate si costuri
c_0 = 10.0
c_1 = 0.08

# Legatura dintre costuri si rata dobanzii
r_0 = 2.0
r_1 = 0.5

# Consum si investitii
C0 = 8.0
I0 = 6.0

b = 0.7
e = 0.9

a = 0.35
d = 0.30

# Venit disponibil si venit asteptat
alpha = 0.75
beta = 0.65

# ======================================================
# SIMULARE NUMERICA - METODA EULER
# ======================================================

dt = 0.05
T = 15
N = int(T / dt)

timp = np.zeros(N + 1)

# -------------------------
# Varianta fara absorbtie
# -------------------------
activitate_fara = np.zeros(N + 1)
costuri_fara = np.zeros(N + 1)
rata_dobanzii_fara = np.zeros(N + 1)
consum_fara = np.zeros(N + 1)
investitii_fara = np.zeros(N + 1)
venit_disponibil_fara = np.zeros(N + 1)
venit_asteptat_fara = np.zeros(N + 1)

# -------------------------
# Varianta cu absorbtie
# -------------------------
activitate_cu = np.zeros(N + 1)
costuri_cu = np.zeros(N + 1)
rata_dobanzii_cu = np.zeros(N + 1)
consum_cu = np.zeros(N + 1)
investitii_cu = np.zeros(N + 1)
venit_disponibil_cu = np.zeros(N + 1)
venit_asteptat_cu = np.zeros(N + 1)

# conditii initiale
activitate_initiala = 5.0
activitate_fara[0] = activitate_initiala
activitate_cu[0] = activitate_initiala

# ======================================================
# FUNCTII AUXILIARE
# ======================================================

def calculeaza_costuri(activitate):
    return c_0 - c_1 * activitate

def calculeaza_rata_dobanzii(costuri):
    return r_0 + r_1 * costuri

def calculeaza_venit_disponibil(activitate):
    return alpha * activitate

def calculeaza_venit_asteptat(activitate):
    return beta * activitate

def calculeaza_consum(venit_disponibil, rata_dobanzii):
    return C0 + a * venit_disponibil - b * rata_dobanzii

def calculeaza_investitii(venit_asteptat, rata_dobanzii):
    return I0 + d * venit_asteptat - e * rata_dobanzii

# ======================================================
# BUCLE EULER
# ======================================================

for i in range(N):
    timp[i + 1] = timp[i] + dt

    # -----------------------------------------
    # VARIANTA FARA ABSORBTIE
    # lant feedback:
    # Y ↑ -> costuri ↓ -> r ↓ -> C,I ↑ -> Yd,Ye ↑ -> Y ↑
    # -----------------------------------------
    costuri_fara[i] = calculeaza_costuri(activitate_fara[i])
    rata_dobanzii_fara[i] = calculeaza_rata_dobanzii(costuri_fara[i])
    venit_disponibil_fara[i] = calculeaza_venit_disponibil(activitate_fara[i])
    venit_asteptat_fara[i] = calculeaza_venit_asteptat(activitate_fara[i])
    consum_fara[i] = calculeaza_consum(venit_disponibil_fara[i], rata_dobanzii_fara[i])
    investitii_fara[i] = calculeaza_investitii(venit_asteptat_fara[i], rata_dobanzii_fara[i])

    activitate_fara[i + 1] = activitate_fara[i] + dt * (
        A + B * activitate_fara[i]
    )

    # -----------------------------------------
    # VARIANTA CU ABSORBTIE
    # -----------------------------------------
    costuri_cu[i] = calculeaza_costuri(activitate_cu[i])
    rata_dobanzii_cu[i] = calculeaza_rata_dobanzii(costuri_cu[i])
    venit_disponibil_cu[i] = calculeaza_venit_disponibil(activitate_cu[i])
    venit_asteptat_cu[i] = calculeaza_venit_asteptat(activitate_cu[i])
    consum_cu[i] = calculeaza_consum(venit_disponibil_cu[i], rata_dobanzii_cu[i])
    investitii_cu[i] = calculeaza_investitii(venit_asteptat_cu[i], rata_dobanzii_cu[i])

    activitate_cu[i + 1] = activitate_cu[i] + dt * (
        A + B * activitate_cu[i] - m * activitate_cu[i]**2
    )

# ultimul punct din grafic
costuri_fara[N] = calculeaza_costuri(activitate_fara[N])
rata_dobanzii_fara[N] = calculeaza_rata_dobanzii(costuri_fara[N])
venit_disponibil_fara[N] = calculeaza_venit_disponibil(activitate_fara[N])
venit_asteptat_fara[N] = calculeaza_venit_asteptat(activitate_fara[N])
consum_fara[N] = calculeaza_consum(venit_disponibil_fara[N], rata_dobanzii_fara[N])
investitii_fara[N] = calculeaza_investitii(venit_asteptat_fara[N], rata_dobanzii_fara[N])

costuri_cu[N] = calculeaza_costuri(activitate_cu[N])
rata_dobanzii_cu[N] = calculeaza_rata_dobanzii(costuri_cu[N])
venit_disponibil_cu[N] = calculeaza_venit_disponibil(activitate_cu[N])
venit_asteptat_cu[N] = calculeaza_venit_asteptat(activitate_cu[N])
consum_cu[N] = calculeaza_consum(venit_disponibil_cu[N], rata_dobanzii_cu[N])
investitii_cu[N] = calculeaza_investitii(venit_asteptat_cu[N], rata_dobanzii_cu[N])

# ======================================================
# AFISARE VALORI FINALE
# ======================================================

print("=== VARIANTA FARA ABSORBTIE ===")
print(f"Activitate economica finala   = {activitate_fara[-1]:.4f}")
print(f"Costuri finale                = {costuri_fara[-1]:.4f}")
print(f"Rata dobanzii finala          = {rata_dobanzii_fara[-1]:.4f}")
print(f"Consum final                  = {consum_fara[-1]:.4f}")
print(f"Investitii finale             = {investitii_fara[-1]:.4f}")
print(f"Venit disponibil final        = {venit_disponibil_fara[-1]:.4f}")
print(f"Venit asteptat final          = {venit_asteptat_fara[-1]:.4f}")

print("\n=== VARIANTA CU ABSORBTIE ===")
print(f"Activitate economica finala   = {activitate_cu[-1]:.4f}")
print(f"Costuri finale                = {costuri_cu[-1]:.4f}")
print(f"Rata dobanzii finala          = {rata_dobanzii_cu[-1]:.4f}")
print(f"Consum final                  = {consum_cu[-1]:.4f}")
print(f"Investitii finale             = {investitii_cu[-1]:.4f}")
print(f"Venit disponibil final        = {venit_disponibil_cu[-1]:.4f}")
print(f"Venit asteptat final          = {venit_asteptat_cu[-1]:.4f}")

# ======================================================
# GRAFICE
# ======================================================

fig, axs = plt.subplots(3, 2, figsize=(14, 12))

# 1. Activitate economica
axs[0, 0].plot(timp, activitate_fara, label="Fara absorbtie")
axs[0, 0].plot(timp, activitate_cu, label="Cu absorbtie")
axs[0, 0].set_title("Activitate economica Y")
axs[0, 0].set_xlabel("Timp")
axs[0, 0].set_ylabel("Nivel")
axs[0, 0].grid(True)
axs[0, 0].legend()

# 2. Costuri
axs[0, 1].plot(timp, costuri_fara, label="Fara absorbtie")
axs[0, 1].plot(timp, costuri_cu, label="Cu absorbtie")
axs[0, 1].set_title("Costuri")
axs[0, 1].set_xlabel("Timp")
axs[0, 1].set_ylabel("Nivel")
axs[0, 1].grid(True)
axs[0, 1].legend()

# 3. Rata dobanzii
axs[1, 0].plot(timp, rata_dobanzii_fara, label="Fara absorbtie")
axs[1, 0].plot(timp, rata_dobanzii_cu, label="Cu absorbtie")
axs[1, 0].set_title("Rata dobanzii r")
axs[1, 0].set_xlabel("Timp")
axs[1, 0].set_ylabel("Nivel")
axs[1, 0].grid(True)
axs[1, 0].legend()

# 4. Consum
axs[1, 1].plot(timp, consum_fara, label="Fara absorbtie")
axs[1, 1].plot(timp, consum_cu, label="Cu absorbtie")
axs[1, 1].set_title("Consum C")
axs[1, 1].set_xlabel("Timp")
axs[1, 1].set_ylabel("Nivel")
axs[1, 1].grid(True)
axs[1, 1].legend()

# 5. Investitii
axs[2, 0].plot(timp, investitii_fara, label="Fara absorbtie")
axs[2, 0].plot(timp, investitii_cu, label="Cu absorbtie")
axs[2, 0].set_title("Investitii I")
axs[2, 0].set_xlabel("Timp")
axs[2, 0].set_ylabel("Nivel")
axs[2, 0].grid(True)
axs[2, 0].legend()

# 6. Venituri
axs[2, 1].plot(timp, venit_disponibil_fara, label="Venit disponibil - fara absorbtie")
axs[2, 1].plot(timp, venit_disponibil_cu, label="Venit disponibil - cu absorbtie")
axs[2, 1].plot(timp, venit_asteptat_fara, label="Venit asteptat - fara absorbtie")
axs[2, 1].plot(timp, venit_asteptat_cu, label="Venit asteptat - cu absorbtie")
axs[2, 1].set_title("Venit disponibil si venit asteptat")
axs[2, 1].set_xlabel("Timp")
axs[2, 1].set_ylabel("Nivel")
axs[2, 1].grid(True)
axs[2, 1].legend(fontsize=8)

plt.tight_layout()
plt.show()