"""
Thanks Service — система благодарностей пользователей
"""
import logging
from datetime import datetime
from typing import Dict, List, Optional
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)


class ThanksService:
    """Сервис благодарностей"""

    def __init__(self, session: AsyncSession):
        self.session = session

    async def give_thank(self, from_user_id: int, to_user_id: int, message: str = None) -> bool:
        """
        Отправить благодарность
        Returns: True если успешно
        """
        from database.models import Thank

        # Нельзя поблагодарить самого себя
        if from_user_id == to_user_id:
            return False

        # Создаём благодарность
        thank = Thank(
            from_user_id=from_user_id,
            to_user_id=to_user_id,
            message=message
        )
        self.session.add(thank)
        await self.session.commit()

        logger.info(f"Благодарность от {from_user_id} к {to_user_id}")
        return True

    async def get_user_thanks(self, user_id: int) -> Dict:
        """
        Получить статистику благодарностей пользователя
        Returns: dict со статистикой
        """
        from database.models import Thank

        # Полученные благодарности
        stmt_received = (
            select(func.count(Thank.id))
            .where(Thank.to_user_id == user_id)
        )
        result = await self.session.execute(stmt_received)
        received_count = result.scalar() or 0

        # Отправленные благодарности
        stmt_given = (
            select(func.count(Thank.id))
            .where(Thank.from_user_id == user_id)
        )
        result = await self.session.execute(stmt_given)
        given_count = result.scalar() or 0

        # Последние полученные
        stmt_last = (
            select(Thank)
            .where(Thank.to_user_id == user_id)
            .order_by(Thank.created_at.desc())
            .limit(5)
        )
        result = await self.session.execute(stmt_last)
        last_received = list(result.scalars().all())

        return {
            'received': received_count,
            'given': given_count,
            'last_received': [
                {
                    'from': t.from_user_id,
                    'message': t.message,
                    'created_at': t.created_at.isoformat()
                }
                for t in last_received
            ]
        }

    async def get_leaderboard(self, limit: int = 10) -> List[Dict]:
        """
        Получить топ пользователей по благодарностям
        Returns: список пользователей с количеством благодарностей
        """
        from database.models import Thank, User

        stmt = (
            select(
                User.user_id,
                User.full_name,
                User.apartment,
                func.count(Thank.id).label('thanks_count')
            )
            .join(Thank, User.user_id == Thank.to_user_id, isouter=True)
            .group_by(User.user_id)
            .order_by(func.count(Thank.id).desc())
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        rows = list(result.all())

        return [
            {
                'user_id': row.user_id,
                'name': row.full_name or f'user{row.user_id}',
                'apartment': row.apartment or '?',
                'thanks': row.thanks_count
            }
            for row in rows
        ]

    async def get_thanks_history(self, user_id: int, limit: int = 20) -> List[Dict]:
        """
        Получить историю благодарностей пользователя
        Returns: список благодарностей
        """
        from database.models import Thank

        stmt = (
            select(Thank)
            .where((Thank.from_user_id == user_id) | (Thank.to_user_id == user_id))
            .order_by(Thank.created_at.desc())
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        thanks = list(result.scalars().all())

        return [
            {
                'from': t.from_user_id,
                'to': t.to_user_id,
                'message': t.message,
                'created_at': t.created_at.isoformat(),
                'is_received': t.to_user_id == user_id
            }
            for t in thanks
        ]

    async def has_thanked_today(self, from_user_id: int, to_user_id: int) -> bool:
        """
        Проверить, благодарил ли уже пользователь сегодня
        Returns: True если уже благодарил
        """
        from database.models import Thank
        from datetime import timedelta

        today = datetime.utcnow().replace(hour=0, minute=0, second=0, microsecond=0)

        stmt = (
            select(func.count(Thank.id))
            .where(Thank.from_user_id == from_user_id)
            .where(Thank.to_user_id == to_user_id)
            .where(Thank.created_at >= today)
        )
        result = await self.session.execute(stmt)
        count = result.scalar() or 0

        return count > 0
