"""
Payment model for tracking folio payments.
"""
import enum
from datetime import datetime
from sqlalchemy import Column, String, Integer, Float, Enum, ForeignKey, DateTime, Text

from app.models.base import BaseModel
from sqlalchemy.orm import relationship


class PaymentMethod(str, enum.Enum):
    """Payment method types."""
    CASH = "cash"
    CREDIT_CARD = "credit_card"
    DEBIT_CARD = "debit_card"
    BANK_TRANSFER = "bank_transfer"
    CHECK = "check"
    MOBILE_PAYMENT = "mobile_payment"
    VOUCHER = "voucher"
    CREDIT = "credit"
    OTHER = "other"


class PaymentStatus(str, enum.Enum):
    """Payment status."""
    PENDING = "pending"
    COMPLETED = "completed"
    FAILED = "failed"
    REFUNDED = "refunded"
    CANCELLED = "cancelled"


class Payment(BaseModel):
    """
    Payment transaction on a folio.

    Attributes:
        folio_id: Associated folio
        payment_method: Method of payment
        status: Payment status
        amount: Payment amount
        currency: Currency code
        payment_date: Date/time of payment
        reference: External reference (card auth, check number, etc.)
        received_by_id: User who received payment
        notes: Payment notes
    """
    __tablename__ = "payments"

    folio_id = Column(
        Integer,
        ForeignKey("folios.id", ondelete="CASCADE"),
        nullable=False,
        index=True
    )
    payment_method = Column(
        Enum(PaymentMethod),
        nullable=False,
        index=True
    )
    status = Column(
        Enum(PaymentStatus),
        default=PaymentStatus.COMPLETED,
        nullable=False
    )
    amount = Column(Float, nullable=False)
    currency = Column(String(3), default="XOF", nullable=False)
    payment_date = Column(
        DateTime,
        default=datetime.utcnow,
        nullable=False,
        index=True
    )
    reference = Column(String(200), nullable=True)
    received_by_id = Column(
        Integer,
        ForeignKey("users.id", ondelete="SET NULL"),
        nullable=True
    )
    notes = Column(Text, nullable=True)

    # For refunds
    original_payment_id = Column(
        Integer,
        ForeignKey("payments.id", ondelete="SET NULL"),
        nullable=True
    )

    # Relationships
    folio = relationship("Folio", back_populates="payments")

    def __repr__(self) -> str:
        return f"<Payment {self.payment_method.value}: {self.amount} {self.currency}>"
