from __future__ import annotations

from enum import Enum
from typing import Literal
from pydantic import BaseModel, Field


class InstallmentType(str, Enum):
    equal = "equal"
    decreasing = "decreasing"


class OverpaymentEffect(str, Enum):
    shorten = "shorten"
    lower_payment = "lower_payment"


class RateChange(BaseModel):
    month: int = Field(ge=1, description="Miesiac od startu kredytu")
    annual_rate: float = Field(ge=0, le=30, description="Roczne oprocentowanie procentowo")


class Overpayment(BaseModel):
    month: int = Field(ge=1)
    amount: float = Field(gt=0)
    repeat: Literal["once", "monthly", "yearly"] = "once"
    until_month: int | None = Field(default=None, ge=1)


class SimulationRequest(BaseModel):
    principal: float = Field(gt=0)
    years: int = Field(ge=1, le=50)
    margin: float = Field(ge=0, le=20, default=2.0)
    base_rate: float = Field(ge=0, le=30, default=5.75)
    installment_type: InstallmentType = InstallmentType.equal
    overpayment_effect: OverpaymentEffect = OverpaymentEffect.shorten
    rate_changes: list[RateChange] = Field(default_factory=list)
    overpayments: list[Overpayment] = Field(default_factory=list)


class ScheduleRow(BaseModel):
    month: int
    rate: float
    payment: float
    principal_part: float
    interest_part: float
    overpayment: float
    remaining: float


class Summary(BaseModel):
    months: int
    total_paid: float
    total_interest: float
    total_overpayment: float
    interest_saved: float
    months_saved: int
    baseline_interest: float
    baseline_months: int
    average_payment: float
    max_payment: float


class SimulationResponse(BaseModel):
    schedule: list[ScheduleRow]
    summary: Summary
