"""
Хендлеры безопасности: бан, отзыв верификации, логирование
"""
import logging
import json
from datetime import datetime, timedelta
from aiogram import Router, F
from aiogram.types import Message, CallbackQuery, FSInputFile
from aiogram.filters import Command
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, update
from database.db import AsyncSessionLocal
from database.models import User, VerificationRequest, SpyLog
from utils.decorators import admin_only
from utils.formatters import format_user_info
import config
import os

logger = logging.getLogger(__name__)

router = Router()


# =============================================================================
# ОТЗЫВ ВЕРИФИКАЦИИ (UNVERIFY)
# =============================================================================

@router.message(Command('unverify'))
@admin_only
async def cmd_unverify(message: Message):
    """
    Отзыв верификации у пользователя
    Использование: /unverify <user_id> [причина]
    """
    args = message.text.split(maxsplit=2)
    
    if len(args) < 2:
        await message.answer(
            'Использование: <code>/unverify &lt;user_id&gt; [причина]</code>\n\n'
            'Пример: <code>/unverify 123456789 Подозрение на шпиона</code>',
            parse_mode='HTML'
        )
        return
    
    try:
        user_id = int(args[1])
    except ValueError:
        await message.answer('❌ Неверный ID пользователя')
        return
    
    reason = args[2] if len(args) > 2 else 'Без указания причины'
    
    async with AsyncSessionLocal() as session:
        # Находим пользователя
        stmt = select(User).where(User.user_id == user_id)
        result = await session.execute(stmt)
        user = result.scalar_one_or_none()
        
        if not user:
            await message.answer('❌ Пользователь не найден')
            return
        
        # Проверяем, не админ ли это
        if user.is_admin:
            await message.answer('❌ Нельзя отозвать верификацию у администратора!')
            return
        
        # Если уже не верифицирован
        if not user.verified:
            await message.answer(f'ℹ️ Пользователь {user.full_name} уже не верифицирован')
            return
        
        # Отзываем верификацию
        user.verified = False
        
        # Создаём запись в логе
        verification_log = VerificationRequest(
            user_id=user_id,
            apartment=user.apartment,
            status='revoked',
            comment=f'Отзыв верификации: {reason}',
            reviewed_at=datetime.utcnow(),
            reviewed_by=message.from_user.id,
        )
        session.add(verification_log)
        
        await session.commit()
        
        logger.info(f'Верификация отозвана у user_id={user_id}, причина: {reason}')
        
        # Уведомляем пользователя (в личку)
        try:
            await message.bot.send_message(
                user_id,
                f'⚠️ <b>Верификация отозвана</b>\n\n'
                f'Причина: {reason}\n\n'
                f'❗ <b>Что дальше:</b>\n'
                f'У вас есть <b>7 дней</b> на повторную верификацию.\n'
                f'Если не пройдёте верификацию — будете удалены из чата.\n\n'
                f'Для верификации напишите боту номер квартиры в личку.',
                parse_mode='HTML'
            )
        except Exception as e:
            logger.error(f'Не удалось уведомить пользователя: {e}')
        
        # Отвечаем админу
        await message.answer(
            f'✅ <b>Верификация отозвана</b>\n\n'
            f'Пользователь: {user.full_name}\n'
            f'Квартира: {user.apartment}\n'
            f'Причина: {reason}\n\n'
            f'⏳ У пользователя есть 7 дней на повторную верификацию',
            parse_mode='HTML'
        )


# =============================================================================
# БАН / РАЗБАН
# =============================================================================

@router.message(Command('ban'))
@admin_only
async def cmd_ban(message: Message):
    """
    Бан пользователя (помечает в БД)
    Использование: /ban <user_id> [причина]
    """
    args = message.text.split(maxsplit=2)
    
    if len(args) < 2:
        await message.answer('Использование: <code>/ban &lt;user_id&gt; [причина]</code>', parse_mode='HTML')
        return
    
    try:
        user_id = int(args[1])
    except ValueError:
        await message.answer('❌ Неверный ID пользователя')
        return
    
    reason = args[2] if len(args) > 2 else 'Нарушение правил чата'
    
    async with AsyncSessionLocal() as session:
        # Находим пользователя
        stmt = select(User).where(User.user_id == user_id)
        result = await session.execute(stmt)
        user = result.scalar_one_or_none()
        
        if not user:
            await message.answer('❌ Пользователь не найден')
            return
        
        # Помечаем как забаненный
        user.is_banned = True
        
        # Создаём лог
        spy_log = SpyLog(
            user_id=user_id,
            spy_score=100,
            flags=json.dumps(['banned_by_admin', reason]),
            action_taken='banned',
        )
        session.add(spy_log)
        
        await session.commit()
        
        logger.info(f'Пользователь забанен: user_id={user_id}, причина: {reason}')
        
        # Пытаемся удалить из чата
        try:
            await message.chat.ban(user_id)
            await message.answer(
                f'🚫 <b>Пользователь забанен и удалён из чата</b>\n\n'
                f'Пользователь: {user.full_name}\n'
                f'Причина: {reason}',
                parse_mode='HTML'
            )
        except Exception as e:
            logger.error(f'Не удалось удалить из чата: {e}')
            await message.answer(
                f'⚠️ <b>Пользователь забанен (в БД)</b>\n\n'
                f'Пользователь: {user.full_name}\n'
                f'Причина: {reason}\n\n'
                f'❌ Не удалось удалить из чата автоматически.\n'
                f'Удалите вручную или дайте боту права администратора.',
                parse_mode='HTML'
            )


@router.message(Command('unban'))
@admin_only
async def cmd_unban(message: Message):
    """Разбан пользователя"""
    args = message.text.split(maxsplit=2)
    
    if len(args) < 2:
        await message.answer('Использование: <code>/unban &lt;user_id&gt;</code>', parse_mode='HTML')
        return
    
    try:
        user_id = int(args[1])
    except ValueError:
        await message.answer('❌ Неверный ID пользователя')
        return
    
    async with AsyncSessionLocal() as session:
        stmt = select(User).where(User.user_id == user_id)
        result = await session.execute(stmt)
        user = result.scalar_one_or_none()
        
        if not user:
            await message.answer('❌ Пользователь не найден')
            return
        
        user.is_banned = False
        await session.commit()
        
        logger.info(f'Пользователь разбанен: user_id={user_id}')
        
        await message.answer(f'✅ <b>Пользователь {user.full_name} разбанен</b>', parse_mode='HTML')


# =============================================================================
# ЛОГИРОВАНИЕ ПОДОЗРИТЕЛЬНЫХ
# =============================================================================

@router.message(Command('log_spy'))
@admin_only
async def cmd_log_spy(message: Message):
    """
    Создать лог подозрительной активности
    Использование: /log_spy <user_id> [комментарий]
    """
    args = message.text.split(maxsplit=2)
    
    if len(args) < 2:
        await message.answer('Использование: <code>/log_spy &lt;user_id&gt; [комментарий]</code>', parse_mode='HTML')
        return
    
    try:
        user_id = int(args[1])
    except ValueError:
        await message.answer('❌ Неверный ID пользователя')
        return
    
    comment = args[2] if len(args) > 2 else 'Подозрительная активность'
    
    async with AsyncSessionLocal() as session:
        # Находим пользователя
        stmt = select(User).where(User.user_id == user_id)
        result = await session.execute(stmt)
        user = result.scalar_one_or_none()
        
        if not user:
            await message.answer('❌ Пользователь не найден')
            return
        
        # Создаём лог
        spy_log = SpyLog(
            user_id=user_id,
            spy_score=user.spy_score + 20,  # Увеличиваем score
            flags=json.dumps(['manual_log_by_admin', comment]),
            action_taken='logged',
        )
        session.add(spy_log)
        
        # Обновляем score пользователя
        user.spy_score = min(user.spy_score + 20, 100)
        
        await session.commit()
        
        # Сохраняем лог в файл
        await save_spy_log_to_file(user, comment)
        
        logger.info(f'Создан лог подозрительности: user_id={user_id}')
        
        await message.answer(
            f'📝 <b>Лог создан</b>\n\n'
            f'Пользователь: {user.full_name}\n'
            f'Квартира: {user.apartment}\n'
            f'Комментарий: {comment}\n'
            f'Spy Score: {user.spy_score}/100',
            parse_mode='HTML'
        )


async def save_spy_log_to_file(user: User, comment: str):
    """Сохранение лога в файл"""
    try:
        log_dir = 'logs/spy_logs'
        os.makedirs(log_dir, exist_ok=True)
        
        # Имя файла: user_id_username_date.log
        username = user.username or f'user{user.user_id}'
        timestamp = datetime.utcnow().strftime('%Y%m%d_%H%M%S')
        filename = f'{log_dir}/{user.user_id}_{username}_{timestamp}.log'
        
        log_text = f'''=== ЛОГ ПОДОЗРИТЕЛЬНОЙ АКТИВНОСТИ ===
Дата: {datetime.utcnow().strftime('%d.%m.%Y %H:%M')}
Пользователь: {user.full_name}
ID: {user.user_id}
Username: @{user.username or 'нет'}
Квартира: {user.apartment or 'не указана'}
Spy Score: {user.spy_score}/100

Комментарий админа:
{comment}

=== История сообщений (последние 50) ===
(см. в основном экспорте)

=== Статус ===
Верифицирован: {"Да" if user.verified else "Нет"}
Забанен: {"Да" if user.is_banned else "Нет"}
'''
        
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(log_text)
        
        logger.info(f'Лог сохранён: {filename}')
        
    except Exception as e:
        logger.error(f'Не удалось сохранить лог: {e}')


# =============================================================================
# СПИСОК ЗАБАНЕННЫХ / ОТОЗВАННЫХ
# =============================================================================

@router.message(Command('banned'))
@admin_only
async def cmd_banned_list(message: Message):
    """Список забаненных пользователей"""
    async with AsyncSessionLocal() as session:
        stmt = select(User).where(User.is_banned == True)
        result = await session.execute(stmt)
        users = list(result.scalars().all())
    
    if not users:
        await message.answer('✅ Забаненных пользователей нет')
        return
    
    text = f'🚫 <b>Забаненные пользователи</b> ({len(users)}):\n\n'
    for user in users:
        text += f'• {user.full_name} (кв. {user.apartment}) — ID: {user.user_id}\n'
    
    await message.answer(text, parse_mode='HTML')


@router.message(Command('unverified_list'))
@admin_only
async def cmd_unverified_list(message: Message):
    """Список пользователей с отозванной верификацией"""
    async with AsyncSessionLocal() as session:
        stmt = (
            select(User)
            .where(User.verified == False)
            .where(User.is_banned == False)
            .order_by(User.verification_date.desc())
        )
        result = await session.execute(stmt)
        users = list(result.scalars().all())
    
    # Фильтруем тех у кого вообще не было верификации
    users_with_revoked = [u for u in users if u.verification_date is not None]
    
    if not users_with_revoked:
        await message.answer('✅ Нет пользователей с отозванной верификацией')
        return
    
    text = f'⏳ <b>С отозванной верификацией</b> ({len(users_with_revoked)}):\n\n'
    for user in users_with_revoked[:20]:  # Показываем первые 20
        days_since = (datetime.utcnow() - user.verification_date).days if user.verification_date else '?'
        text += f'• {user.full_name} (кв. {user.apartment}) — отозвано {days_since} дн. назад\n'
    
    if len(users_with_revoked) > 20:
        text += f'\n... и ещё {len(users_with_revoked) - 20}'
    
    await message.answer(text, parse_mode='HTML')


# =============================================================================
# АВТО-УДАЛЕНИЕ НЕВЕРИФИЦИРОВАННЫХ
# =============================================================================

@router.message(Command('check_unverified'))
@admin_only
async def cmd_check_unverified(message: Message):
    """
    Проверка пользователей с просроченной верификацией
    Показывает кто не прошёл верификацию за 7 дней
    """
    async with AsyncSessionLocal() as session:
        # Находим пользователей которые не верифицированы более 7 дней
        week_ago = datetime.utcnow() - timedelta(days=7)
        
        stmt = (
            select(User)
            .where(User.verified == False)
            .where(User.join_date <= week_ago)
            .where(User.is_banned == False)
        )
        result = await session.execute(stmt)
        users = list(result.scalars().all())
    
    if not users:
        await message.answer('✅ Все пользователи верифицированы вовремя')
        return
    
    text = f'⚠️ <b>Не верифицированы более 7 дней</b> ({len(users)}):\n\n'
    for user in users[:20]:
        days = (datetime.utcnow() - user.join_date).days
        text += f'• {user.full_name} (кв. {user.apartment}) — {days} дн. в чате\n'
    
    if len(users) > 20:
        text += f'\n... и ещё {len(users) - 20}'
    
    text += '\n\n💡 Используйте <code>/unverify &lt;user_id&gt;</code> для отзыва'
    
    await message.answer(text, parse_mode='HTML')
