"""Finance models for student ledger, payments, and device financing."""

from datetime import datetime
from enum import Enum as PyEnum
from uuid import uuid4

from sqlalchemy import (
    Boolean, Column, Date, DateTime, Enum, ForeignKey, Integer, Numeric, String, Text
)
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship

from app.database import Base


class LedgerEntryType(str, PyEnum):
    """Ledger entry type."""
    TUITION = "tuition"
    ACCEPTANCE_FEE = "acceptance_fee"
    APPLICATION_FEE = "application_fee"
    DEVICE_LOAN = "device_loan"
    MISCELLANEOUS = "miscellaneous"


class LedgerEntryStatus(str, PyEnum):
    """Ledger entry status."""
    PENDING = "pending"
    PAID = "paid"
    OVERDUE = "overdue"
    CANCELLED = "cancelled"


class StudentLedger(Base):
    """Student financial ledger (invoices, charges, payments)."""
    __tablename__ = "student_ledger"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4, index=True)
    student_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False, index=True)
    academic_session_id = Column(UUID(as_uuid=True), ForeignKey("academic_sessions.id"), nullable=True, index=True)
    
    entry_type = Column(Enum(LedgerEntryType), nullable=False, index=True)
    description = Column(String(255), nullable=False)
    amount = Column(Numeric(10, 2), nullable=False)
    status = Column(Enum(LedgerEntryStatus), default=LedgerEntryStatus.PENDING, nullable=False, index=True)
    
    due_date = Column(Date, nullable=True)
    paid_date = Column(DateTime, nullable=True)
    payment_reference = Column(String(100), nullable=True, index=True)
    payment_gateway = Column(String(50), nullable=True)  # paystack, flutterwave, etc.
    
    notes = Column(Text, nullable=True)
    
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    student = relationship("User", foreign_keys=[student_id])
    academic_session = relationship("AcademicSession")

    def __repr__(self):
        return f"<StudentLedger {self.entry_type.value}: {self.amount} - {self.status.value}>"


class DeviceLoanStatus(str, PyEnum):
    """Device loan status."""
    PENDING = "pending"
    ACTIVE = "active"
    COMPLETED = "completed"
    DEFAULTED = "defaulted"
    CANCELLED = "cancelled"


class DeviceLoan(Base):
    """Device financing loan for students."""
    __tablename__ = "device_loans"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4, index=True)
    student_id = Column(UUID(as_uuid=True), ForeignKey("users.id"), nullable=False, index=True)
    
    device_type = Column(String(100), nullable=False)  # e.g., "Laptop", "Tablet"
    device_model = Column(String(255), nullable=True)
    device_serial = Column(String(100), nullable=True, unique=True, index=True)
    
    loan_amount = Column(Numeric(10, 2), nullable=False)
    monthly_payment = Column(Numeric(10, 2), nullable=False)
    total_months = Column(Integer, default=12, nullable=False)
    months_paid = Column(Integer, default=0, nullable=False)
    
    status = Column(Enum(DeviceLoanStatus), default=DeviceLoanStatus.PENDING, nullable=False, index=True)
    
    disbursement_date = Column(Date, nullable=True)
    start_date = Column(Date, nullable=True)
    completion_date = Column(Date, nullable=True)
    
    notes = Column(Text, nullable=True)
    
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False)
    
    # Relationships
    student = relationship("User", foreign_keys=[student_id])
    payments = relationship("DeviceLoanPayment", back_populates="loan", cascade="all, delete-orphan")

    def __repr__(self):
        return f"<DeviceLoan {self.device_type}: {self.loan_amount} - {self.status.value}>"


class DeviceLoanPayment(Base):
    """Individual payment for a device loan."""
    __tablename__ = "device_loan_payments"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid4, index=True)
    loan_id = Column(UUID(as_uuid=True), ForeignKey("device_loans.id"), nullable=False, index=True)
    
    amount = Column(Numeric(10, 2), nullable=False)
    payment_date = Column(DateTime, nullable=False)
    payment_reference = Column(String(100), nullable=True, unique=True, index=True)
    payment_gateway = Column(String(50), nullable=True)
    
    month_number = Column(Integer, nullable=False)  # Which month payment (1, 2, 3, ...)
    
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
    
    # Relationships
    loan = relationship("DeviceLoan", back_populates="payments")

    def __repr__(self):
        return f"<DeviceLoanPayment {self.loan_id}: {self.amount} for month {self.month_number}>"
