# bot/services.py
import logging
from dataclasses import dataclass
from typing import Optional, Protocol, Tuple, Coroutine, Any, Awaitable
from django.utils import timezone
from asgiref.sync import sync_to_async
from .models import TelegramBot, TelegramChat

logger = logging.getLogger(__name__)

# Протокол (интерфейс) репозитория — удобно мокать в тестах
from typing import Coroutine

class IChatRepository(Protocol):
    async def upsert_chat(
        self, *, bot: TelegramBot, chat_id: int, chat_type: str,
        title: str = "", username: str = "", is_member: bool = True,
        touch_last_message: bool = False,
    ) -> Coroutine[Any, Any, Tuple[TelegramChat, bool]]: ...

# Реализация на Django ORM
class DjangoChatRepository:
    @sync_to_async
    def upsert_chat(
        self, *, bot: TelegramBot, chat_id: int, chat_type: str,
        title: str = "", username: str = "", is_member: bool = True,
        touch_last_message: bool = False,
    ):
        defaults = {
            "type": chat_type,
            "title": title or "",
            "username": username or "",
            "is_member": is_member,
            "joined_at": timezone.now() if is_member else None,
            "left_at": None if is_member else timezone.now(),
        }
        if touch_last_message:
            defaults["last_message_at"] = timezone.now()

        obj, created = TelegramChat.objects.update_or_create(
            bot=bot, chat_id=chat_id, defaults=defaults
        )
        return obj, created

@dataclass
class BotServices:
    """Контейнер зависимостей для конкретного бота."""
    bot: TelegramBot
    chats: IChatRepository

def build_services(bot: TelegramBot) -> BotServices:
    return BotServices(bot=bot, chats=DjangoChatRepository())
