"""
Profile History — история изменений профиля пользователя
Только для администраторов
"""
import logging
from datetime import datetime
from aiogram import Router, F
from aiogram.types import Message
from aiogram.filters import Command
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, desc
from database.db import AsyncSessionLocal
from database.models import User, ProfileHistory
from utils.decorators import admin_only

logger = logging.getLogger(__name__)

router = Router()


# =============================================================================
# ИСТОРИЯ ПОЛЬЗОВАТЕЛЯ
# =============================================================================

@router.message(Command('history'))
@router.message(Command('история'))
@admin_only
async def cmd_history(message: Message):
    """
    Показать историю изменений профиля пользователя
    Использование: /history <user_id> [лимит]
    """
    args = message.text.split()
    if len(args) < 2:
        await message.answer(
            '❌ <b>Использование:</b>\n'
            '<code>/history &lt;user_id&gt; [лимит]</code>\n\n'
            'Пример: /history 123456789 20',
            parse_mode='HTML'
        )
        return

    try:
        user_id = int(args[1])
    except ValueError:
        await message.answer('❌ Неверный ID пользователя')
        return

    limit = int(args[2]) if len(args) > 2 and args[2].isdigit() else 20

    async with AsyncSessionLocal() as session:
        # Получаем пользователя
        user = await session.get(User, user_id)
        if not user:
            await message.answer(f'❌ Пользователь {user_id} не найден')
            return

        # Получаем историю
        stmt = (
            select(ProfileHistory)
            .where(ProfileHistory.user_id == user_id)
            .order_by(desc(ProfileHistory.changed_at))
            .limit(limit)
        )
        result = await session.execute(stmt)
        history = list(result.scalars().all())

    name = user.full_name or user.username or f'user{user_id}'
    apt = user.apartment or '?'

    if not history:
        await message.answer(f'ℹ️ У пользователя {name} нет истории изменений')
        return

    text = f'📋 <b>История профиля: {name}</b> (кв. {apt})\n\n'
    text += f'Показано последних: {len(history)} из {limit}\n\n'

    field_names = {
        'username': 'Никнейм',
        'first_name': 'Имя',
        'last_name': 'Фамилия',
        'apartment': 'Квартира',
        'phone': 'Телефон',
    }

    for i, record in enumerate(history, 1):
        field_name = field_names.get(record.field_name, record.field_name)
        old_val = record.old_value or 'пусто'
        new_val = record.new_value or 'пусто'
        changed_at = record.changed_at.strftime('%d.%m.%Y %H:%M')

        text += f'{i}. <b>{field_name}</b> ({changed_at})\n'
        text += f'   ├─ Было: {old_val}\n'
        text += f'   └─ Стало: {new_val}\n\n'

    await message.answer(text, parse_mode='HTML')


# =============================================================================
# ВСЕ ИЗМЕНЕНИЯ ЗА ПЕРИОД
# =============================================================================

@router.message(Command('all_history'))
@router.message(Command('вся_история'))
@admin_only
async def cmd_all_history(message: Message):
    """
    Показать все изменения профилей за период
    Использование: /all_history [дни] [лимит]
    """
    args = message.text.split()
    days = int(args[1]) if len(args) > 1 and args[1].isdigit() else 7
    limit = int(args[2]) if len(args) > 2 and args[2].isdigit() else 50

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

    async with AsyncSessionLocal() as session:
        stmt = (
            select(ProfileHistory)
            .where(ProfileHistory.changed_at >= time_window)
            .order_by(desc(ProfileHistory.changed_at))
            .limit(limit)
        )
        result = await session.execute(stmt)
        history = list(result.scalars().all())

    if not history:
        await message.answer(f'ℹ️ Нет изменений за последние {days} дней')
        return

    text = f'📋 <b>Все изменения за {days} дн.</b>\n\n'
    text += f'Показано: {len(history)} из {limit}\n\n'

    field_names = {
        'username': 'Никнейм',
        'first_name': 'Имя',
        'last_name': 'Фамилия',
        'apartment': 'Квартира',
        'phone': 'Телефон',
    }

    # Группируем по пользователям
    user_changes = {}
    for record in history:
        if record.user_id not in user_changes:
            user_changes[record.user_id] = []
        user_changes[record.user_id].append(record)

    for user_id, changes in user_changes.items():
        user = await session.get(User, user_id)
        name = user.full_name or user.username or f'user{user_id}'
        apt = user.apartment or '?'

        text += f'👤 <b>{name}</b> (кв. {apt}) — {len(changes)} изм.\n'

        for record in changes[:5]:  # Показываем первые 5
            field_name = field_names.get(record.field_name, record.field_name)
            old_val = record.old_value or 'пусто'
            new_val = record.new_value or 'пусто'

            text += f'   └─ {field_name}: {old_val} → {new_val}\n'

        if len(changes) > 5:
            text += f'   └─ ... и ещё {len(changes) - 5}\n'

        text += '\n'

    await message.answer(text, parse_mode='HTML')


# =============================================================================
# ИЗМЕНЕНИЯ КОНКРЕТНОГО ПОЛЯ
# =============================================================================

@router.message(Command('field_history'))
@router.message(Command('история_поля'))
@admin_only
async def cmd_field_history(message: Message):
    """
    Показать изменения конкретного поля
    Использование: /field_history <поле> [дни]
    Поля: username, first_name, last_name, apartment, phone
    """
    args = message.text.split()
    if len(args) < 2:
        await message.answer(
            '❌ <b>Использование:</b>\n'
            '<code>/field_history &lt;поле&gt; [дни]</code>\n\n'
            'Поля: username, first_name, last_name, apartment, phone\n'
            'Пример: /field_history apartment 7',
            parse_mode='HTML'
        )
        return

    field = args[1].lower()
    days = int(args[2]) if len(args) > 2 and args[2].isdigit() else 7

    valid_fields = ['username', 'first_name', 'last_name', 'apartment', 'phone']
    if field not in valid_fields:
        await message.answer(f'❌ Неверное поле. Доступные: {", ".join(valid_fields)}')
        return

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

    async with AsyncSessionLocal() as session:
        stmt = (
            select(ProfileHistory)
            .where(ProfileHistory.field_name == field)
            .where(ProfileHistory.changed_at >= time_window)
            .order_by(desc(ProfileHistory.changed_at))
            .limit(20)
        )
        result = await session.execute(stmt)
        history = list(result.scalars().all())

    if not history:
        await message.answer(f'ℹ️ Нет изменений поля "{field}" за {days} дней')
        return

    field_names = {
        'username': 'Никнейм',
        'first_name': 'Имя',
        'last_name': 'Фамилия',
        'apartment': 'Квартира',
        'phone': 'Телефон',
    }

    text = f'📋 <b>История поля: {field_names.get(field, field)}</b>\n\n'
    text += f'За {days} дн. ({len(history)} изм.)\n\n'

    for i, record in enumerate(history, 1):
        user = await session.get(User, record.user_id)
        name = user.full_name or user.username or f'user{record.user_id}'
        apt = user.apartment or '?'

        old_val = record.old_value or 'пусто'
        new_val = record.new_value or 'пусто'
        changed_at = record.changed_at.strftime('%d.%m.%Y %H:%M')

        text += f'{i}. {name} (кв. {apt}) — {changed_at}\n'
        text += f'   └─ {old_val} → {new_val}\n\n'

    await message.answer(text, parse_mode='HTML')


# =============================================================================
# СТАТИСТИКА ИЗМЕНЕНИЙ
# =============================================================================

@router.message(Command('history_stats'))
@router.message(Command('статистика_истории'))
@admin_only
async def cmd_history_stats(message: Message):
    """Статистика изменений профилей"""
    from sqlalchemy import func

    async with AsyncSessionLocal() as session:
        # Общее количество записей
        stmt = select(func.count(ProfileHistory.id))
        result = await session.execute(stmt)
        total = result.scalar()

        # По полям
        stmt = (
            select(ProfileHistory.field_name, func.count(ProfileHistory.id))
            .group_by(ProfileHistory.field_name)
        )
        result = await session.execute(stmt)
        by_field = list(result.all())

        # За последние 7 дней
        from datetime import timedelta
        time_window = datetime.utcnow() - timedelta(days=7)
        stmt = select(func.count(ProfileHistory.id)).where(
            ProfileHistory.changed_at >= time_window
        )
        result = await session.execute(stmt)
        last_7_days = result.scalar()

    text = '📊 <b>Статистика истории профиля</b>\n\n'
    text += f'Всего записей: {total}\n'
    text += f'За последние 7 дней: {last_7_days}\n\n'

    if by_field:
        text += '📁 <b>По полям:</b>\n\n'
        field_names = {
            'username': 'Никнейм',
            'first_name': 'Имя',
            'last_name': 'Фамилия',
            'apartment': 'Квартира',
            'phone': 'Телефон',
        }
        for field, count in sorted(by_field, key=lambda x: x[1], reverse=True):
            text += f'• {field_names.get(field, field)}: {count}\n'

    await message.answer(text, parse_mode='HTML')
