"""Activity feed model.

An :class:`ActivityEvent` is one entry in a user's personal history ("here's
everything that's been happening with your account"). It is deliberately
**generic** — a free-text ``event_type`` plus a shared ``(related_entity_type,
related_entity_id)`` pointer — so future features publish events without any
schema migration. All rows are created through the single
:func:`app.activity.services.publish_activity` entry point; nothing writes here
directly.

This is separate from, and never replaces, :class:`Notification` (which answers
"something needs your attention"). Some actions publish both.
"""

from __future__ import annotations

from app.extensions import db
from app.models.base import BaseModel, BigIntegerType, utcnow
from app.models.enums import RelatedEntityType


def _enum_values(enum_cls):
    return [member.value for member in enum_cls]


class ActivityEvent(BaseModel):
    """A single activity-feed entry belonging to one user."""

    __tablename__ = "activity_events"
    __table_args__ = (
        # Feed ordering is always "this user, newest first".
        db.Index("ix_activity_events_user_created", "user_id", "created_at"),
        db.Index("ix_activity_events_user_unread", "user_id", "is_read"),
        db.Index("ix_activity_events_event_type", "event_type"),
    )

    user_id = db.Column(BigIntegerType, db.ForeignKey("users.id"), nullable=False)
    event_type = db.Column(db.String(50), nullable=False)
    title = db.Column(db.String(150), nullable=False)
    message = db.Column(db.String(500), nullable=True)
    related_entity_type = db.Column(
        db.Enum(RelatedEntityType, values_callable=_enum_values, name="activity_related_entity_type"),
        nullable=True,
    )
    related_entity_id = db.Column(BigIntegerType, nullable=True)
    icon = db.Column(db.String(60), nullable=True)  # a Bootstrap-Icons class
    is_read = db.Column(db.Boolean, nullable=False, default=False, server_default="0")
    created_at = db.Column(db.DateTime, nullable=False, default=utcnow)

    user = db.relationship("User", foreign_keys=[user_id])

    def __repr__(self) -> str:
        return f"<ActivityEvent id={self.id} user_id={self.user_id} type={self.event_type!r}>"
