"""Domain model for the Follow entity.

A ``Follow`` record represents a user's subscription to a "target" —
any domain object that can be followed (events, stories, people, sources,
or custom entities).  The target is identified polymorphically by a
``(target_type, target_id)`` pair, avoiding separate join tables per kind.
"""
from __future__ import annotations

from datetime import datetime
from enum import Enum

from repo_core.base.models import DomainModel


class FollowTargetType(str, Enum):
    """Enum of all followable target kinds.

    Using ``str, Enum`` keeps values as plain strings at the DB level
    while providing IDE autocompletion and type safety in Python.
    """

    EVENT = "event"
    STORY = "story"
    PERSON = "person"
    SOURCE = "source"
    ENTITY = "entity"


class Follow(DomainModel):
    """Links a user to a polymorphic target via ``(target_type, target_id)``.

    A single ``follows`` table replaces separate join/pivot tables per
    target kind (e.g. ``event_follows``, ``story_follows``, ...).

    The ``(user_id, target_type, target_id)`` triplet is unique — enforced
    at the DB level (see migration) and by ``FollowRepository.follow()``.
    """

    id: int
    user_id: int
    target_type: FollowTargetType
    target_id: str
    created_at: datetime | None = None
    updated_at: datetime | None = None
