#!/usr/bin/env python3
"""
Автоматические тесты для Домовой Бот
Проверка критических функций без запуска бота
"""
import sys
import asyncio
from pathlib import Path

# Добавляем путь к проекту
BASE_DIR = Path(__file__).resolve().parent
sys.path.insert(0, str(BASE_DIR))

# Тесты
TESTS_PASSED = 0
TESTS_FAILED = 0


def test_result(name: str, passed: bool, details: str = ""):
    """Вывод результата теста"""
    global TESTS_PASSED, TESTS_FAILED
    if passed:
        print(f"✅ {name}")
        TESTS_PASSED += 1
    else:
        print(f"❌ {name}: {details}")
        TESTS_FAILED += 1


def test_syntax():
    """Тест 1: Синтаксис Python файлов"""
    print("\n=== ТЕСТ 1: СИНТАКСИС ===")
    import py_compile
    import glob
    
    py_files = glob.glob("**/*.py", recursive=True)
    py_files = [f for f in py_files if 'venv' not in f]
    
    for file in py_files:
        try:
            py_compile.compile(file, doraise=True)
            test_result(f"✅ {file}", True)
        except py_compile.PyCompileError as e:
            test_result(f"❌ {file}", False, str(e))


def test_imports():
    """Тест 2: Импорты модулей"""
    print("\n=== ТЕСТ 2: ИМПОРТЫ ===")
    
    modules = [
        'handlers.admin',
        'handlers.users',
        'handlers.verification',
        'handlers.chat_monitor',
        'handlers.security',
        'handlers.apartments',
        'handlers.antimat',
        'handlers.phones',
        'handlers.polls',
        'handlers.antispam',
        'handlers.ratelimit',
        'handlers.schedule',
        'handlers.ads',
        'handlers.payments',
        'handlers.multicount',
        'handlers.topics',
        'handlers.toxicity',
        'handlers.profile_history',
        'handlers.achievements',
        'handlers.thanks',
        'handlers.events',
        'handlers.initiative_group',
        'keyboards.admin_menu',
        'keyboards.inline',
        'keyboards.reply',
        'database.models',
        'database.db',
        'config',
    ]
    
    for module in modules:
        try:
            __import__(module)
            test_result(f"✅ {module}", True)
        except ImportError as e:
            test_result(f"❌ {module}", False, str(e))


def test_callback_data_unique():
    """Тест 3: Уникальность callback_data"""
    print("\n=== ТЕСТ 3: УНИКАЛЬНОСТЬ CALLBACK_DATA ===")
    import re
    import glob
    
    callbacks = []
    files = glob.glob("handlers/*.py") + glob.glob("keyboards/*.py")
    
    for file in files:
        if 'venv' not in file:
            with open(file, 'r', encoding='utf-8') as f:
                content = f.read()
                found = re.findall(r"callback_data=['\"]([^'\"]+)['\"]", content)
                callbacks.extend(found)
    
    # Исключения (шаблоны с переменными)
    callbacks = [c for c in callbacks if '_' not in c.split('_')[-1] or not c.split('_')[-1].isdigit()]
    
    duplicates = [c for c in callbacks if callbacks.count(c) > 1]
    unique_duplicates = list(set(duplicates))
    
    if unique_duplicates:
        test_result("Уникальность callback_data", False, f"Дубликаты: {unique_duplicates[:10]}")
    else:
        test_result("Уникальность callback_data", True)


def test_commands_unique():
    """Тест 4: Уникальность Command"""
    print("\n=== ТЕСТ 4: УНИКАЛЬНОСТЬ COMMAND ===")
    import re
    import glob
    
    commands = []
    files = glob.glob("handlers/*.py")
    
    for file in files:
        if 'venv' not in file:
            with open(file, 'r', encoding='utf-8') as f:
                content = f.read()
                found = re.findall(r"@router\.message\(Command\(['\"]([^'\"]+)['\"]", content)
                commands.extend(found)
    
    # Считаем дубликаты (разрешены алиасы)
    from collections import Counter
    cmd_counts = Counter(commands)
    
    # Находим реальные дубликаты (не алиасы)
    duplicates = [cmd for cmd, count in cmd_counts.items() if count > 2]
    
    if duplicates:
        test_result("Уникальность Command", False, f"Дубликаты: {duplicates}")
    else:
        test_result("Уникальность Command", True)


def test_database_structure():
    """Тест 5: Структура БД"""
    print("\n=== ТЕСТ 5: СТРУКТУРА БД ===")
    import sqlite3
    
    db_path = "database/domovoy.db"
    
    try:
        conn = sqlite3.connect(db_path)
        cursor = conn.cursor()
        
        # Проверяем таблицы
        cursor.execute("SELECT name FROM sqlite_master WHERE type='table'")
        tables = [row[0] for row in cursor.fetchall()]
        
        expected_tables = ['user', 'verification_request', 'service', 'announcement']
        for table in expected_tables:
            test_result(f"Таблица '{table}'", table in tables)
        
        # Проверяем количество пользователей
        cursor.execute("SELECT COUNT(*) FROM user")
        count = cursor.fetchone()[0]
        test_result(f"Пользователей в БД: {count}", count >= 0)
        
        conn.close()
    except Exception as e:
        test_result("Проверка БД", False, str(e))


def test_keyboard_functions():
    """Тест 6: Функции клавиатур"""
    print("\n=== ТЕСТ 6: ФУНКЦИИ КЛАВИАТУР ===")
    
    from keyboards.admin_menu import (
        get_admin_main_menu,
        get_admin_reply_menu,
        get_admin_toxicity_menu,
        get_admin_search_menu,
        get_admin_antispam_menu,
        get_user_pagination_keyboard,
        get_user_action_menu,
        get_bad_words_list_keyboard,
        get_yes_no_keyboard,
        get_back_keyboard,
    )
    
    from keyboards.inline import (
        get_main_menu,
        get_thank_user_keyboard,
        get_thank_confirm_keyboard,
    )
    
    functions = [
        ('get_admin_main_menu', get_admin_main_menu),
        ('get_admin_toxicity_menu', get_admin_toxicity_menu),
        ('get_admin_search_menu', get_admin_search_menu),
        ('get_admin_antispam_menu', get_admin_antispam_menu),
        ('get_user_action_menu', lambda: get_user_action_menu(123, 'Test')),
        ('get_bad_words_list_keyboard', lambda: get_bad_words_list_keyboard(['test'])),
        ('get_yes_no_keyboard', lambda: get_yes_no_keyboard('test')),
        ('get_back_keyboard', get_back_keyboard),
        ('get_main_menu', get_main_menu),
        ('get_thank_user_keyboard', lambda: get_thank_user_keyboard([])),
        ('get_thank_confirm_keyboard', lambda: get_thank_confirm_keyboard(123)),
    ]
    
    for name, func in functions:
        try:
            result = func()
            test_result(f"✅ {name}", result is not None)
        except Exception as e:
            test_result(f"❌ {name}", False, str(e))


def test_fsm_states():
    """Тест 7: FSM состояния"""
    print("\n=== ТЕСТ 7: FSM СОСТОЯНИЯ ===")
    
    from handlers.admin import SearchState, AddWordState, AddDomainState, AddPatternState
    
    states = [
        ('SearchState.waiting_for_apt_search', SearchState.waiting_for_apt_search),
        ('SearchState.waiting_for_user_search', SearchState.waiting_for_user_search),
        ('AddWordState.waiting_for_word', AddWordState.waiting_for_word),
        ('AddDomainState.waiting_for_domain', AddDomainState.waiting_for_domain),
        ('AddPatternState.waiting_for_pattern', AddPatternState.waiting_for_pattern),
    ]
    
    for name, state in states:
        test_result(f"✅ {name}", state is not None)


def test_config():
    """Тест 8: Конфигурация"""
    print("\n=== ТЕСТ 8: КОНФИГУРАЦИЯ ===")
    
    from config import BOT_TOKEN, ADMIN_CHAT_ID, ADMIN_USER_ID
    
    test_result("BOT_TOKEN настроен", len(BOT_TOKEN) > 10)
    test_result("ADMIN_CHAT_ID настроен", ADMIN_CHAT_ID != 0)
    test_result("ADMIN_USER_ID настроен", ADMIN_USER_ID != 0)


def run_all_tests():
    """Запуск всех тестов"""
    print("=" * 60)
    print("🧪 АВТОМАТИЧЕСКИЕ ТЕСТЫ ДОМОВОЙ БОТ")
    print("=" * 60)
    
    test_syntax()
    test_imports()
    test_callback_data_unique()
    test_commands_unique()
    test_database_structure()
    test_keyboard_functions()
    test_fsm_states()
    test_config()
    
    print("\n" + "=" * 60)
    print(f"✅ ПРОЙДЕНО: {TESTS_PASSED}")
    print(f"❌ ПРОВАЛЕНО: {TESTS_FAILED}")
    print("=" * 60)
    
    return TESTS_FAILED == 0


if __name__ == '__main__':
    success = run_all_tests()
    sys.exit(0 if success else 1)
