import uuid
from sqlalchemy import Column, String, Integer, Date, ForeignKey, Numeric, DateTime
from sqlalchemy.orm import relationship
from utils.utils import Base, utc_now


class CalculationSettings(Base):
    __tablename__ = "calculation_settings"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    settings_id = Column(String(100), nullable=False, unique=True, index=True)
    default_loan_amount = Column(Numeric(15, 2), nullable=False)
    default_interest_rate = Column(Numeric(5, 2), nullable=False)
    default_loan_term = Column(Integer, nullable=False)
    currency_symbol = Column(String(10), nullable=False)
    decimal_precision = Column(Integer, nullable=False)
    date_format = Column(String(50), nullable=False)
    created_at = Column(DateTime(timezone=True), default=utc_now, nullable=False)
    updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now, nullable=False)

    loan_calculations = relationship("LoanCalculation", back_populates="settings")


class LoanCalculation(Base):
    __tablename__ = "loan_calculations"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    calculation_id = Column(String(100), nullable=False, unique=True, index=True)
    settings_id = Column(String(36), ForeignKey("calculation_settings.id", ondelete="SET NULL"), nullable=True, index=True)
    principal_amount = Column(Numeric(15, 2), nullable=False)
    annual_interest_rate = Column(Numeric(5, 2), nullable=False)
    loan_term_months = Column(Integer, nullable=False)
    monthly_payment = Column(Numeric(15, 2), nullable=False)
    total_interest = Column(Numeric(15, 2), nullable=False)
    total_amount_paid = Column(Numeric(15, 2), nullable=False)
    calculation_timestamp = Column(DateTime(timezone=True), nullable=False)
    created_at = Column(DateTime(timezone=True), default=utc_now, nullable=False)
    updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now, nullable=False)

    settings = relationship("CalculationSettings", back_populates="loan_calculations")
    amortization_entries = relationship("AmortizationEntry", back_populates="calculation", cascade="all, delete-orphan", passive_deletes=True)


class AmortizationEntry(Base):
    __tablename__ = "amortization_entries"

    id = Column(String(36), primary_key=True, default=lambda: str(uuid.uuid4()))
    entry_id = Column(String(100), nullable=False, unique=True, index=True)
    calculation_id = Column(String(36), ForeignKey("loan_calculations.id", ondelete="CASCADE"), nullable=False, index=True)
    payment_number = Column(Integer, nullable=False)
    payment_date = Column(Date, nullable=False)
    payment_amount = Column(Numeric(15, 2), nullable=False)
    principal_portion = Column(Numeric(15, 2), nullable=False)
    interest_portion = Column(Numeric(15, 2), nullable=False)
    remaining_balance = Column(Numeric(15, 2), nullable=False)
    created_at = Column(DateTime(timezone=True), default=utc_now, nullable=False)
    updated_at = Column(DateTime(timezone=True), default=utc_now, onupdate=utc_now, nullable=False)

    calculation = relationship("LoanCalculation", back_populates="amortization_entries")