"""
Topics Analyzer — анализ тем чата, облако тегов
Классификация сообщений по темам и категориям
"""
import logging
import re
from datetime import datetime, timedelta
from typing import Dict, List, Tuple, Optional
from collections import defaultdict, Counter
from sqlalchemy import select, func
from sqlalchemy.ext.asyncio import AsyncSession

logger = logging.getLogger(__name__)


class TopicsAnalyzer:
    """Анализатор тем чата"""

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

    def _load_topics(self) -> Dict:
        """Загрузить темы и ключевые слова"""
        return {
            'лифты': {
                'keywords': ['лифт', 'лифты', 'лифтовая', 'кабина', 'шахта лифта', 'лифт застрял', 'лифт не работает'],
                'emoji': '🛗'
            },
            'парковка': {
                'keywords': ['парковк', 'машина', 'автомобиль', 'место парковк', 'припаркован', 'шлагбаум'],
                'emoji': '🚗'
            },
            'уборка': {
                'keywords': ['уборк', 'грязн', 'мусор', 'подъезд', 'лестниц', 'пол', 'пыль'],
                'emoji': '🧹'
            },
            'соседи': {
                'keywords': ['сосед', 'соседи', 'шум', 'громко', 'музыка', 'ремонт', 'сверлит'],
                'emoji': '👥'
            },
            'вода': {
                'keywords': ['вод', 'кран', 'труб', 'протечк', 'засор', 'канализаци', 'стояк'],
                'emoji': '💧'
            },
            'электричество': {
                'keywords': ['свет', 'электричеств', 'розетк', 'проводк', 'автомат', 'лампочк', 'мигает'],
                'emoji': '⚡'
            },
            'отопление': {
                'keywords': ['отоплен', 'батаре', 'радиатор', 'тепло', 'холод', 'температур'],
                'emoji': '🔥'
            },
            'домофон': {
                'keywords': ['домофон', 'ключ', 'карта', 'доступ', 'вход', 'дверь'],
                'emoji': '🔑'
            },
            'мусор': {
                'keywords': ['мусор', 'контейнер', 'баки', 'вывоз', 'раздельный', 'переработк'],
                'emoji': '🗑️'
            },
            'дети': {
                'keywords': ['ребенок', 'дети', 'детск', 'коляск', 'площадк', 'песочниц'],
                'emoji': '👶'
            },
            'животные': {
                'keywords': ['собак', 'кошк', 'животн', 'питомец', 'лают', 'мяукают'],
                'emoji': '🐕'
            },
            'объявления': {
                'keywords': ['объявлен', 'продам', 'куплю', 'отдам', 'ищу', 'предлагаю'],
                'emoji': '📢'
            },
            'жалобы': {
                'keywords': ['жалоб', 'жалуюсь', 'недовольн', 'возмущен', 'требую', 'безобраз'],
                'emoji': '😠'
            },
            'благодарности': {
                'keywords': ['спасиб', 'благодар', 'благодарю', 'молодец', 'хорошо', 'отличн'],
                'emoji': '🙏'
            },
            'вопросы': {
                'keywords': ['вопрос', 'подскажит', 'помогит', 'кто знает', 'как сделать'],
                'emoji': '❓'
            },
            'предложения': {
                'keywords': ['предлагаю', 'предложен', 'давайте', 'может быть', 'идея'],
                'emoji': '💡'
            },
            'собрание': {
                'keywords': ['собран', 'встреч', 'совещан', 'голосован', 'опрос', 'обсужден'],
                'emoji': '📅'
            },
            'ук': {
                'keywords': ['ук', 'управляющ', 'компан', 'жкх', 'паспортист', 'диспетчер'],
                'emoji': '🏢'
            },
        }

    async def analyze_message(self, text: str) -> Optional[str]:
        """
        Классифицировать сообщение по теме
        Returns: название темы или None
        """
        if not text:
            return None

        text_lower = text.lower()
        topic_scores = defaultdict(int)

        for topic_name, topic_data in self.topics.items():
            for keyword in topic_data['keywords']:
                if keyword in text_lower:
                    topic_scores[topic_name] += 1

        if not topic_scores:
            return None

        # Возвращаем тему с наибольшим score
        best_topic = max(topic_scores, key=topic_scores.get)
        return best_topic

    async def get_topics_stats(self, days: int = 7) -> Dict:
        """
        Получить статистику тем за период
        Returns: dict с темами и количеством сообщений
        """
        from database.models import Message

        time_window = datetime.utcnow() - timedelta(days=days)

        stmt = (
            select(Message.text)
            .where(Message.timestamp >= time_window)
            .where(Message.text.isnot(None))
        )
        result = await self.session.execute(stmt)
        messages = [row[0] for row in result.all()]

        topic_counts = defaultdict(int)

        for text in messages:
            topic = await self.analyze_message(text)
            if topic:
                topic_counts[topic] += 1

        # Считаем общее количество классифицированных сообщений
        total = sum(topic_counts.values())
        unclassified = len(messages) - total

        # Формируем результат
        result = {
            'total_messages': len(messages),
            'classified': total,
            'unclassified': unclassified,
            'topics': {}
        }

        for topic_name, count in sorted(topic_counts.items(), key=lambda x: x[1], reverse=True):
            percent = (count / total * 100) if total > 0 else 0
            emoji = self.topics[topic_name]['emoji']
            result['topics'][topic_name] = {
                'count': count,
                'percent': round(percent, 1),
                'emoji': emoji
            }

        return result

    async def get_topics_cloud(self, days: int = 7) -> str:
        """
        Получить облако тегов в текстовом виде
        Returns: форматированный текст
        """
        stats = await self.get_topics_stats(days)

        if not stats['topics']:
            return 'ℹ️ Нет данных за указанный период'

        text = f'☁️ <b>Облако тем чата</b> (за {days} дн.)\n\n'
        text += f'Всего сообщений: {stats["total_messages"]}\n'
        text += f'Распознано: {stats["classified"]} ({stats["classified"]/stats["total_messages"]*100:.0f}%)\n\n'

        # Формируем облако
        sorted_topics = sorted(
            stats['topics'].items(),
            key=lambda x: x[1]['percent'],
            reverse=True
        )

        for topic_name, data in sorted_topics:
            bar_length = int(data['percent'] / 5)  # 1 символ = 5%
            bar = '█' * bar_length + '░' * (20 - bar_length)
            
            text += f'{data["emoji"]} <b>{topic_name.capitalize()}</b>: {bar} {data["percent"]}% ({data["count"]})\n'

        return text

    async def get_top_topics(self, days: int = 7, limit: int = 5) -> List[Tuple[str, Dict]]:
        """
        Получить топ тем за период
        Returns: список (название_темы, данные)
        """
        stats = await self.get_topics_stats(days)
        
        sorted_topics = sorted(
            stats['topics'].items(),
            key=lambda x: x[1]['percent'],
            reverse=True
        )
        
        return sorted_topics[:limit]

    async def get_topic_trend(self, topic: str, days: int = 14) -> Dict:
        """
        Получить тренд темы по дням
        Returns: dict с датами и количеством сообщений
        """
        from database.models import Message

        time_window = datetime.utcnow() - timedelta(days=days)

        stmt = (
            select(Message.text, func.date(Message.timestamp).label('msg_date'))
            .where(Message.timestamp >= time_window)
            .where(Message.text.isnot(None))
        )
        result = await self.session.execute(stmt)
        messages = [(row[0], row[1]) for row in result.all()]

        daily_counts = defaultdict(int)

        for text, date in messages:
            topic = await self.analyze_message(text)
            if topic == topic:
                daily_counts[date] += 1

        return {
            'topic': topic,
            'days': days,
            'daily_counts': dict(sorted(daily_counts.items())),
            'total': sum(daily_counts.values())
        }

    async def get_weekly_report(self) -> str:
        """
        Сформировать еженедельный отчёт по темам
        Returns: форматированный текст отчёта
        """
        stats = await self.get_topics_stats(7)
        prev_stats = await self.get_topics_stats(14)

        text = '📊 <b>Еженедельный отчёт по темам чата</b>\n\n'
        text += f'Период: последние 7 дней\n\n'

        # Топ тем
        text += '🔥 <b>Топ тем недели:</b>\n\n'
        top_topics = await self.get_top_topics(7, 5)

        for i, (topic_name, data) in enumerate(top_topics, 1):
            text += f'{i}. {data["emoji"]} {topic_name.capitalize()}: {data["percent"]}% ({data["count"]} сообщ.)\n'

        # Сравнение с прошлой неделей
        text += '\n📈 <b>Динамика:</b>\n\n'

        if prev_stats['topics']:
            for topic_name, data in stats['topics'].items():
                prev_data = prev_stats['topics'].get(topic_name, {'count': 0})
                diff = data['count'] - prev_data['count']

                if diff > 0:
                    text += f'↗️ {topic_name.capitalize()}: +{diff} ({data["emoji"]})\n'
                elif diff < 0:
                    text += f'↘️ {topic_name.capitalize()}: {diff} ({data["emoji"]})\n'

        text += '\n💡 Используйте /topics для детальной статистики'

        return text
