"""
Events Service — календарь событий дома
"""
import logging
from datetime import datetime, timedelta
from typing import Dict, List, Optional
from sqlalchemy import select, func, delete
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)


class EventsService:
    """Сервис событий"""

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

    async def create_event(
        self,
        title: str,
        event_date: datetime,
        description: str = None,
        event_type: str = 'general',
        location: str = None,
        created_by: int = None
    ) -> int:
        """
        Создать событие
        Returns: ID события
        """
        from database.models import Event

        event = Event(
            title=title,
            description=description,
            event_type=event_type,
            event_date=event_date,
            location=location,
            created_by=created_by
        )
        self.session.add(event)
        await self.session.commit()
        await self.session.refresh(event)

        logger.info(f"Событие {title} создано (ID: {event.id})")
        return event.id

    async def join_event(self, event_id: int, user_id: int) -> bool:
        """
        Присоединиться к событию
        Returns: True если успешно
        """
        from database.models import EventParticipant

        # Проверяем не участвует ли уже
        stmt = select(EventParticipant).where(
            EventParticipant.event_id == event_id,
            EventParticipant.user_id == user_id
        )
        result = await self.session.execute(stmt)
        if result.scalar_one_or_none():
            return False

        participant = EventParticipant(
            event_id=event_id,
            user_id=user_id
        )
        self.session.add(participant)
        await self.session.commit()

        logger.info(f"Пользователь {user_id} присоединился к событию {event_id}")
        return True

    async def leave_event(self, event_id: int, user_id: int) -> bool:
        """
        Отписаться от события
        Returns: True если успешно
        """
        from database.models import EventParticipant

        stmt = delete(EventParticipant).where(
            EventParticipant.event_id == event_id,
            EventParticipant.user_id == user_id
        )
        await self.session.execute(stmt)
        await self.session.commit()

        logger.info(f"Пользователь {user_id} отписался от события {event_id}")
        return True

    async def get_event(self, event_id: int) -> Optional[Dict]:
        """Получить информацию о событии"""
        from database.models import Event

        event = await self.session.get(Event, event_id)
        if not event:
            return None

        # Считаем участников
        stmt = select(func.count()).select_from(EventParticipant).where(
            EventParticipant.event_id == event_id
        )
        result = await self.session.execute(stmt)
        participants_count = result.scalar() or 0

        return {
            'id': event.id,
            'title': event.title,
            'description': event.description,
            'event_type': event.event_type,
            'event_date': event.event_date,
            'location': event.location,
            'created_by': event.created_by,
            'participants_count': participants_count,
            'is_active': event.is_active
        }

    async def get_upcoming_events(self, limit: int = 10) -> List[Dict]:
        """Получить предстоящие события"""
        from database.models import Event

        stmt = (
            select(Event)
            .where(Event.is_active == True)
            .where(Event.event_date >= datetime.utcnow())
            .order_by(Event.event_date)
            .limit(limit)
        )
        result = await self.session.execute(stmt)
        events = list(result.scalars().all())

        return [
            {
                'id': e.id,
                'title': e.title,
                'event_date': e.event_date,
                'location': e.location,
                'event_type': e.event_type
            }
            for e in events
        ]

    async def get_user_events(self, user_id: int) -> List[Dict]:
        """Получить события пользователя"""
        from database.models import Event, EventParticipant

        stmt = (
            select(Event)
            .join(EventParticipant, Event.id == EventParticipant.event_id)
            .where(EventParticipant.user_id == user_id)
            .where(Event.is_active == True)
            .order_by(Event.event_date)
        )
        result = await self.session.execute(stmt)
        events = list(result.scalars().all())

        return [
            {
                'id': e.id,
                'title': e.title,
                'event_date': e.event_date,
                'location': e.location,
                'event_type': e.event_type
            }
            for e in events
        ]

    async def cancel_event(self, event_id: int) -> bool:
        """Отменить событие"""
        from database.models import Event

        event = await self.session.get(Event, event_id)
        if not event:
            return False

        event.is_active = False
        await self.session.commit()

        logger.info(f"Событие {event_id} отменено")
        return True

    async def get_participants(self, event_id: int) -> List[Dict]:
        """Получить участников события"""
        from database.models import EventParticipant, User

        stmt = (
            select(User)
            .join(EventParticipant, User.user_id == EventParticipant.user_id)
            .where(EventParticipant.event_id == event_id)
        )
        result = await self.session.execute(stmt)
        users = list(result.scalars().all())

        return [
            {
                'user_id': u.user_id,
                'name': u.full_name or u.username or f'user{u.user_id}',
                'apartment': u.apartment
            }
            for u in users
        ]

    async def get_events_for_reminder(self, hours_ahead: int = 24) -> List[Dict]:
        """Получить события для напоминания"""
        from database.models import Event

        now = datetime.utcnow()
        future = now + timedelta(hours=hours_ahead)

        stmt = (
            select(Event)
            .where(Event.is_active == True)
            .where(Event.reminder_sent == False)
            .where(Event.event_date > now)
            .where(Event.event_date <= future)
        )
        result = await self.session.execute(stmt)
        events = list(result.scalars().all())

        return [
            {
                'id': e.id,
                'title': e.title,
                'event_date': e.event_date,
                'location': e.location,
                'description': e.description
            }
            for e in events
        ]

    async def mark_reminder_sent(self, event_id: int):
        """Отметить что напоминание отправлено"""
        from database.models import Event

        event = await self.session.get(Event, event_id)
        if event:
            event.reminder_sent = True
            await self.session.commit()

    def get_event_type_emoji(self, event_type: str) -> str:
        """Получить emoji типа события"""
        emojis = {
            'meeting': '📋',
            'subbotnik': '🧹',
            'holiday': '🎉',
            'sport': '⚽',
            'kids': '🎈',
            'general': '📅'
        }
        return emojis.get(event_type, '📅')
