"""
SubscriptionActivity ORM model.

Append-only audit trail for every significant lifecycle event on a Subscription.
Written synchronously in the service layer (not via Kafka) — same pattern as
InvoiceActivity.

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'.
"""

from datetime import datetime
from typing import Optional, TYPE_CHECKING

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

if TYPE_CHECKING:
    from src.apps.subscriptions.models.subscription import Subscription


class SubscriptionActivity(Base):
    """
    Append-only event log for a Subscription.

    activity_type should use dot-notation strings, e.g.:
        'subscription.created'
        'subscription.activated'
        'subscription.charge_succeeded'
        'subscription.charge_failed'
        'subscription.dunning_retry_scheduled'
        'subscription.dunning_exhausted'
        'subscription.paused'
        'subscription.resumed'
        'subscription.cancelled'
        'subscription.completed'
    """

    __tablename__ = "subscription_activities"

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

    activity_type: Mapped[str] = mapped_column(
        String(64),
        nullable=False,
        index=True,
        doc="Dot-notation event type, e.g. 'subscription.charge_failed'.",
    )
    description: Mapped[Optional[str]] = mapped_column(
        Text,
        nullable=True,
        doc="Human-readable summary of what happened.",
    )
    actor_type: Mapped[Optional[str]] = mapped_column(
        String(20),
        nullable=True,
        doc="Who triggered this event: 'merchant' | 'system' | 'customer'.",
    )
    actor_id: Mapped[Optional[int]] = mapped_column(
        Integer,
        nullable=True,
        doc="PK of the acting entity (user.id for merchant/customer, NULL for system).",
    )
    metadata_: Mapped[Optional[dict]] = mapped_column(
        "metadata",
        JSON,
        nullable=True,
        doc="Arbitrary JSON payload; use for amounts, error codes, retry info, etc.",
    )

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

    # ── Relationships ─────────────────────────────────────────────────────────

    subscription: Mapped["Subscription"] = relationship(
        "Subscription",
        back_populates="activities",
    )
