"""Domain models for parsed Telegram messages in the Doris warehouse.

These models correspond to the denormalised, analytics-optimised tables
defined in ``telegram-parsed-message-schema.md``.  They are persisted primarily
to Doris (warehouse) via ``_warehouse_include``.
"""

from __future__ import annotations

import uuid
from datetime import date, datetime

from repo_core.base.models import DomainModel


class TelegramParsedMessage(DomainModel):
    """Denormalised, analytics-ready Telegram message.

    Corresponds to the ``telegram_parsed_messages`` Doris UNIQUE KEY table.
    Keyed by ``(peer_id, message_id)``.
    """

    # DB (PostgreSQL) primary key
    id: uuid.UUID | None = None

    peer_id: int
    message_id: int
    message_sent_at: datetime | None = None

    from_id: int | None = None
    from_type: int | None = None
    message_text: str | None = None
    message_lang: str | None = None

    views: int = 0
    forwards_count: int = 0
    reply_count: int = 0

    has_media: bool = False
    media_type: str | None = None

    is_forward: bool = False
    fwd_from_peer_id: int | None = None
    fwd_from_msg_id: int | None = None
    fwd_from_date: datetime | None = None

    reply_to_msg_id: int | None = None
    edit_date: datetime | None = None

    translated_text: str | None = None

    crawled_at: datetime | None = None
    created_at: datetime | None = None
    updated_at: datetime | None = None

    # ------------------------------------------------------------------
    # DB-only fields (PostgreSQL JSONB / extra columns)
    # ------------------------------------------------------------------
    entities: dict | None = None
    media: dict | None = None
    reactions: dict | None = None
    replies: dict | None = None
    reply_to: dict | None = None
    fwd_from: dict | None = None

    forwards: int | None = None
    is_post: bool = False
    is_pinned: bool = False

    # ------------------------------------------------------------------
    # Auto-managed timestamps (UTC datetime).
    # crawled_at is injected by the caller (persistence handler).
    # ------------------------------------------------------------------
    _timestamps: set[str] = {"created_at", "updated_at"}

    # Fields written to PostgreSQL
    _db_include: set[str] = {
        "id",
        "message_id",
        "peer_id",
        "from_id",
        "message_sent_at",
        "message_text",
        "message_lang",
        "edit_date",
        "details",
        "media",
        "reactions",
        "replies",
        "reply_to",
        "fwd_from",
        "views",
        "forwards",
        "is_post",
        "is_pinned",
        "crawled_at",
        "translated_text",
        "created_at",
        "updated_at",
    }

    # All fields are warehouse-relevant
    _warehouse_include: set[str] = {
        "peer_id",
        "message_id",
        "message_sent_at",
        "from_id",
        "from_type",
        "message_text",
        "message_lang",
        "translated_text",
        "views",
        "forwards_count",
        "reply_count",
        "has_media",
        "media_type",
        "is_forward",
        "fwd_from_peer_id",
        "fwd_from_msg_id",
        "fwd_from_date",
        "reply_to_msg_id",
        "edit_date",
        "crawled_at",
        "created_at",
        "updated_at",
    }


class MessageReaction(DomainModel):
    """Per-message, per-emoji reaction counts.

    Corresponds to the ``message_reactions`` Doris UNIQUE KEY table.
    Keyed by ``(peer_id, message_id, emoticon)``.
    """

    peer_id: int
    message_id: int
    emoticon: str
    reaction_count: int = 0
    is_custom: bool = False
    updated_at: datetime

    # ------------------------------------------------------------------
    # Auto-managed timestamps
    # ------------------------------------------------------------------
    _timestamps: set[str] = {"updated_at"}

    _warehouse_include: set[str] = {
        "peer_id",
        "message_id",
        "emoticon",
        "reaction_count",
        "is_custom",
        "updated_at",
    }


class MessageDetail(DomainModel):
    """Formatted-text detail rows extracted from Telegram messages.

    Corresponds to the ``telegram_message_details`` Doris DUPLICATE KEY table.
    Append-only for maximum write throughput; keyed by
    ``(peer_id, message_id)``.
    """

    peer_id: int
    message_id: int
    detail_type: str
    detail_value: str | None = None
    offset: int
    length: int

    # Optional entity-specific fields extracted from Telegram message entities.
    url: str | None = None
    language: str | None = None
    user_id: int | None = None
    document_id: int | None = None

    # ------------------------------------------------------------------
    # No auto-managed timestamps — this is an append-only table.
    # ------------------------------------------------------------------
    _timestamps: set[str] = set()

    _warehouse_include: set[str] = {
        "peer_id",
        "message_id",
        "detail_type",
        "detail_value",
        "offset",
        "length",
        "url",
        "language",
        "user_id",
        "document_id",
    }
