"""Сервис пользователей.""" from __future__ import annotations from aiogram.types import ChatMemberUpdated, Message, User from bot.services.economy import ACTION_USER_DELETED from common.analytics import EventType, record from common.models import NickEntry, UserInfo from common.repositories import economy_repo, users_repo def _user_fields(user: User) -> tuple[int, str, str, str]: return ( int(user.id), user.username or "", user.first_name or "", user.last_name or "", ) async def register_from_message(message: Message) -> None: """Зарегистрировать/обновить автора сообщения.""" user = message.from_user if user is None or user.is_bot: return await users_repo.add_user(*_user_fields(user)) async def register_from_event(event: ChatMemberUpdated) -> None: """Зарегистрировать/обновить участника, вошедшего в чат.""" user = event.new_chat_member.user if user.is_bot: return await users_repo.add_user(*_user_fields(user)) record( EventType.JOIN, user_id=user.id, username=user.username, chat_id=event.chat.id, payload={"chat_title": event.chat.title or ""}, ) async def set_nick(id_user: int, nick: str) -> None: await users_repo.set_nick_with_history(id_user, nick, editor_id=id_user, source="user") record(EventType.NICK_SET, user_id=id_user, payload={"nick": nick}) async def delete_user(id_user: int) -> None: """Удалить пользователя и зафиксировать обнуление баланса. Баланс читается **до** удаления: ``bot.del_user_by_id`` обнуляет его записью в журнал ``money``. """ balance = await economy_repo.get_money(id_user) await users_repo.del_user_by_id(id_user) if balance: record( EventType.MONEY_SPEND, user_id=id_user, payload={"amount": abs(balance), "reason": "user_deleted", "action_id": ACTION_USER_DELETED}, ) async def list_nicks() -> list[NickEntry]: rows = await users_repo.get_nick_list() return [NickEntry(username=row.get("username"), nick=row.get("nick")) for row in rows] async def list_subscribers() -> list[dict]: return await users_repo.get_nick_list_subscribe() async def get_user_info(id_user: int) -> UserInfo | None: row = await users_repo.get_info_by_id(id_user) if not row: return None return UserInfo( username=row.get("username"), nick=row.get("nick"), title=row.get("title"), lvl=int(row.get("lvl") or 0), exp=int(row.get("expr") or 0), money=int(row.get("mny") or 0), dt=row.get("dt") or "", msg_count=int(row.get("msg_count") or 0), eggs=int(row.get("eggs_count") or 0), )