"""
PRD-HWONB-006 §1 — merchant_onboarding_accounts

The "<=3 accounts" cap is CERT-confirmed real (PRD-001 §13.1 C-23) but is
enforced in crud.py, not via a DB constraint here — no UniqueConstraint is
placed on application_id so that cap check remains possible in application code.
"""
from typing import Optional, TYPE_CHECKING
from sqlalchemy import String, Boolean, Integer, DateTime, JSON, ForeignKey, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func
from src.apps.base.models.base import Base
from datetime import datetime

if TYPE_CHECKING:
    from src.apps.merchant_onboarding.models.application import MerchantOnboardingApplication


class MerchantOnboardingAccount(Base):
    __tablename__ = "merchant_onboarding_accounts"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, index=True, autoincrement=True)
    application_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("merchant_onboarding_applications.id"), nullable=False, index=True
    )

    # Fernet-encrypted (src/apps/payment_providers/helpers/credentials.py)
    routing_number_enc: Mapped[str] = mapped_column(Text, nullable=False)  # exact 9 digits, plaintext
    account_number_enc: Mapped[str] = mapped_column(Text, nullable=False)  # 1-17 digits, plaintext

    account_type: Mapped[str] = mapped_column(String(1), nullable=False)  # C | S | B

    # array of enum values 1-4 chars each: ACHF, ACHS, C, M, D. Mandatory once >1 account exists;
    # each usage type may be assigned to only one account across the whole set (enforced in crud.py).
    usage_types: Mapped[Optional[list]] = mapped_column(JSON, nullable=True)

    # Exactly one account may be true at a time (enforced in crud.py); first account defaults true if omitted.
    is_default: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)

    tsys_account_ref: Mapped[Optional[str]] = mapped_column(String(100), nullable=True)
    tsys_synced_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)
    tsys_errors: Mapped[Optional[dict]] = mapped_column(JSON, nullable=True)

    created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True, onupdate=func.now())
    deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True), nullable=True)

    application: Mapped["MerchantOnboardingApplication"] = relationship(
        "MerchantOnboardingApplication", back_populates="accounts"
    )
