"""
InvoiceActivity ORM model.

Activity records are written synchronously in the service layer (not via Kafka).
Each CRUD-level or lifecycle transition on an invoice produces one record.
"""

from datetime import datetime
from typing import Optional

from sqlalchemy import DateTime, ForeignKey, Integer, JSON, String, Text
from sqlalchemy.orm import Mapped, mapped_column, relationship
from sqlalchemy.sql import func

from src.apps.base.models.base import Base


class InvoiceActivity(Base):
    """
    Append-only audit trail for every significant event on an Invoice.

    actor_type is one of: 'merchant' | 'system' | 'customer'
    actor_id   references the relevant entity's PK (user.id, None for system).
    metadata_  stored as JSON; mapped to the column name 'metadata'.
    """

    __tablename__ = "invoice_activities"

    id: Mapped[int] = mapped_column(
        Integer, primary_key=True, index=True, autoincrement=True
    )
    invoice_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("invoices.id"), nullable=False, index=True
    )
    activity_type: Mapped[str] = mapped_column(String(64), nullable=False, index=True)
    description: Mapped[Optional[str]] = mapped_column(Text, nullable=True)
    actor_type: Mapped[Optional[str]] = mapped_column(String(20), nullable=True)
    actor_id: Mapped[Optional[int]] = mapped_column(Integer, nullable=True)
    metadata_: Mapped[Optional[dict]] = mapped_column(
        "metadata", JSON, nullable=True
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default=func.now(), nullable=False
    )

    invoice: Mapped["Invoice"] = relationship(
        "Invoice", back_populates="activities", lazy="select"
    )
