from datetime import date
from decimal import Decimal
from typing import Optional
from uuid import UUID

from sqlalchemy import Date, ForeignKey, Index, Numeric, String, Text
from sqlalchemy.dialects.postgresql import UUID as PG_UUID
from sqlalchemy.orm import Mapped, mapped_column, relationship

from src.database.base import BaseModel


class PlatformPayment(BaseModel):
    __tablename__ = "platform_payments"

    account_id: Mapped[UUID] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("accounts.id", ondelete="CASCADE"),
        nullable=False,
        index=True,
    )
    subscription_id: Mapped[Optional[UUID]] = mapped_column(
        PG_UUID(as_uuid=True),
        ForeignKey("subscriptions.id", ondelete="SET NULL"),
        nullable=True,
    )
    plan: Mapped[str] = mapped_column(String(50), nullable=False)
    amount_cad: Mapped[Decimal] = mapped_column(Numeric(10, 2), nullable=False)
    method: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    invoice_no: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    source: Mapped[str] = mapped_column(String(20), nullable=False, default="portal")
    status: Mapped[str] = mapped_column(String(20), nullable=False, default="paid")
    payment_date: Mapped[date] = mapped_column(Date, nullable=False)
    stripe_payment_intent_id: Mapped[Optional[str]] = mapped_column(String(255), nullable=True)
    notes: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    pdf_s3_key: Mapped[Optional[str]] = mapped_column(Text, nullable=True)

    account: Mapped[object] = relationship("Account", foreign_keys=[account_id])

    __table_args__ = (
        Index("ix_platform_payments_payment_date", "payment_date"),
        Index("ix_platform_payments_source", "source"),
        Index("ix_platform_payments_plan", "plan"),
        Index("ix_platform_payments_status", "status"),
    )
