"""Telegram parsed message repositories — Doris warehouse CRUD via BaseRepository."""

from __future__ import annotations

from datetime import datetime, timezone
from typing import Any

from repo_core import BaseRepository
from repo_core.domains.telegram.telegram_parsed_message.model import (
    TelegramParsedMessage,
    MessageDetail,
    MessageReaction,
)


class TelegramParsedMessageRepository(BaseRepository[TelegramParsedMessage]):
    """Repository for the ``telegram_parsed_messages`` Doris UNIQUE KEY table."""

    TABLE = "telegram_parsed_messages"
    _backends = {"doris"}

    # ------------------------------------------------------------------
    # Timestamp injection  (UTC datetime for Doris warehouse)
    # ------------------------------------------------------------------

    def _inject_model_timestamps(self, data: dict[str, Any]) -> dict[str, Any]:
        """Inject ``created_at`` and ``updated_at`` as UTC datetimes."""
        if self.model is None:
            return data
        now = datetime.now(timezone.utc)
        for field in ("created_at", "updated_at"):
            if field in self.model.model_fields and field not in data:
                data[field] = now
        return data

    def _inject_model_updated_at(self, values: dict[str, Any]) -> dict[str, Any]:
        """Inject ``updated_at`` as a UTC datetime on update operations."""
        if self.model is None:
            return values
        if "updated_at" in self.model.model_fields and "updated_at" not in values:
            values["updated_at"] = datetime.now(timezone.utc)
        return values

    async def update_by_key(
        self, peer_id: int, message_id: int, values: dict[str, Any]
    ) -> None:
        """Update an existing ``telegram_parsed_messages`` warehouse row.

        Keyed by ``(peer_id, message_id)``.  ``None`` values are
        stripped — only explicitly set fields are written.  Silently
        ignores when no matching row exists (the parse pipeline may
        not have run yet).
        """
        values = {k: v for k, v in values.items() if v is not None}
        if not values:
            return
        await self.warehouse_update(
            self.TABLE,
            {"peer_id": peer_id, "message_id": message_id},
            values,
            limit=1,
        )


class TelegramParsedMessageDBRepository(BaseRepository[TelegramParsedMessage]):
    """Repository for the ``telegram_parsed_messages`` PostgreSQL table."""

    TABLE = "telegram_parsed_messages"
    _backends = {"db"}

    def _inject_model_timestamps(self, data: dict[str, Any]) -> dict[str, Any]:
        """Inject ``created_at`` and ``updated_at`` as UTC datetimes."""
        if self.model is None:
            return data
        now = datetime.now(timezone.utc)
        for field in ("created_at", "updated_at"):
            if field in self.model.model_fields and field not in data:
                data[field] = now
        return data

    def _inject_model_updated_at(self, values: dict[str, Any]) -> dict[str, Any]:
        """Inject ``updated_at`` as a UTC datetime on update operations."""
        if self.model is None:
            return values
        if "updated_at" in self.model.model_fields and "updated_at" not in values:
            values["updated_at"] = datetime.now(timezone.utc)
        return values

    async def update_by_key(
        self, peer_id: int, message_id: int, values: dict[str, Any]
    ) -> None:
        """Update an existing ``telegram_parsed_messages`` PostgreSQL row.

        Keyed by ``(peer_id, message_id)``.  ``None`` values are
        stripped — only explicitly set fields are written.  Silently
        ignores when no matching row exists (the parse pipeline may
        not have run yet).
        """
        values = {k: v for k, v in values.items() if v is not None}
        if not values:
            return
        await self.db_update(
            self.TABLE,
            {"peer_id": peer_id, "message_id": message_id},
            values,
            limit=1,
        )


class MessageReactionRepository(BaseRepository[MessageReaction]):
    """Repository for the ``message_reactions`` Doris UNIQUE KEY table."""

    TABLE = "message_reactions"
    _backends = {"doris"}


class MessageDetailRepository(BaseRepository[MessageDetail]):
    """Repository for the ``telegram_message_details`` Doris DUPLICATE KEY table."""

    TABLE = "telegram_message_details"
    _backends = {"doris"}
