"""
Django management команда для бенчмарка API endpoints.
Измеряет время ответа и количество SQL запросов для указанных endpoints.
"""
import time
import json
from django.core.management.base import BaseCommand
from django.db import connection, reset_queries
from django.test import Client
from django.contrib.auth import get_user_model
from rest_framework_simplejwt.tokens import RefreshToken

User = get_user_model()


class Command(BaseCommand):
    help = 'Бенчмарк API endpoints - измеряет время и SQL запросы'
    
    def add_arguments(self, parser):
        parser.add_argument(
            '--endpoint',
            type=str,
            help='URL endpoint для тестирования (например: /api/homework/homeworks/)',
        )
        parser.add_argument(
            '--email',
            type=str,
            default='mentor@test.com',
            help='Email пользователя для аутентификации (по умолчанию: mentor@test.com)',
        )
        parser.add_argument(
            '--iterations',
            type=int,
            default=5,
            help='Количество итераций теста (по умолчанию: 5)',
        )
    
    def handle(self, *args, **options):
        endpoint = options.get('endpoint')
        email = options['email']
        iterations = options['iterations']
        
        self.stdout.write(self.style.SUCCESS('=' * 70))
        self.stdout.write(self.style.SUCCESS('⚡ Бенчмарк API Endpoints'))
        self.stdout.write(self.style.SUCCESS('=' * 70))
        self.stdout.write('')
        
        # Получаем пользователя или создаем тестового
        try:
            user = User.objects.get(email=email)
        except User.DoesNotExist:
            self.stdout.write(self.style.WARNING(
                f'Пользователь {email} не найден. Создаю тестового пользователя...'
            ))
            user = User.objects.create_user(
                email=email,
                password='TestPass123!',
                first_name='Тест',
                last_name='Пользователь',
                role='mentor',
                is_email_verified=True,
                is_active=True
            )
        
        # Создаем клиент и аутентифицируем
        client = Client()
        refresh = RefreshToken.for_user(user)
        client.defaults['HTTP_AUTHORIZATION'] = f'Bearer {refresh.access_token}'
        
        # Список endpoints для тестирования, если не указан конкретный
        endpoints_to_test = [
            endpoint,
        ] if endpoint else [
            '/api/homework/homeworks/',
            '/api/homework/homeworks/created_by_me/',
            '/api/chat/chats/',
        ]
        
        results = []
        
        for endpoint_url in endpoints_to_test:
            if not endpoint_url:
                continue
                
            self.stdout.write(f'📊 Тестирую: {endpoint_url}')
            self.stdout.write('-' * 70)
            
            times = []
            query_counts = []
            status_codes = []
            
            for i in range(iterations):
                reset_queries()
                start_time = time.time()
                
                response = client.get(endpoint_url)
                
                end_time = time.time()
                elapsed = end_time - start_time
                query_count = len(connection.queries)
                
                times.append(elapsed)
                query_counts.append(query_count)
                status_codes.append(response.status_code)
            
            avg_time = sum(times) / len(times)
            avg_queries = sum(query_counts) / len(query_counts)
            min_time = min(times)
            max_time = max(times)
            min_queries = min(query_counts)
            max_queries = max(query_counts)
            
            results.append({
                'endpoint': endpoint_url,
                'iterations': iterations,
                'avg_time': avg_time,
                'min_time': min_time,
                'max_time': max_time,
                'avg_queries': avg_queries,
                'min_queries': min_queries,
                'max_queries': max_queries,
                'status_code': status_codes[0],
            })
            
            self.stdout.write(f'   ✅ Статус: {status_codes[0]}')
            self.stdout.write(f'   ⏱️  Среднее время: {avg_time:.3f}с')
            self.stdout.write(f'   ⏱️  Минимальное время: {min_time:.3f}с')
            self.stdout.write(f'   ⏱️  Максимальное время: {max_time:.3f}с')
            self.stdout.write(f'   📊 Среднее SQL запросов: {avg_queries:.1f}')
            self.stdout.write(f'   📊 Минимум SQL запросов: {min_queries}')
            self.stdout.write(f'   📊 Максимум SQL запросов: {max_queries}')
            
            # Оценка производительности
            if avg_time > 0.5:
                self.stdout.write(self.style.ERROR('   ⚠️  МЕДЛЕННО: Время ответа > 0.5с'))
            elif avg_time > 0.3:
                self.stdout.write(self.style.WARNING('   ⚠️  Приемлемо: Время ответа 0.3-0.5с'))
            else:
                self.stdout.write(self.style.SUCCESS('   ✅ Быстро: Время ответа < 0.3с'))
            
            if avg_queries > 20:
                self.stdout.write(self.style.ERROR('   ⚠️  МНОГО SQL: Возможны N+1 проблемы'))
            elif avg_queries > 10:
                self.stdout.write(self.style.WARNING('   ⚠️  Много SQL запросов'))
            else:
                self.stdout.write(self.style.SUCCESS('   ✅ Оптимально: SQL запросов < 10'))
            
            self.stdout.write('')
            
            # Показываем самые медленные запросы
            if connection.queries:
                self.stdout.write('   🐌 Самые медленные SQL запросы:')
                query_times = []
                for query in connection.queries:
                    query_time = float(query.get('time', 0))
                    if query_time > min_time:
                        query_times.append((query_time, query['sql'][:100]))
                
                query_times.sort(reverse=True)
                for query_time, sql in query_times[:5]:
                    self.stdout.write(f'      {query_time:.3f}с: {sql}...')
                self.stdout.write('')
        
        # Итоговая таблица
        self.stdout.write(self.style.SUCCESS('=' * 70))
        self.stdout.write(self.style.SUCCESS('📋 Итоговая таблица результатов'))
        self.stdout.write(self.style.SUCCESS('=' * 70))
        self.stdout.write(f'{"Endpoint":<40} {"Время (с)":<12} {"SQL":<8} {"Статус":<8}')
        self.stdout.write('-' * 70)
        for result in results:
            status_icon = '✅' if result['status_code'] == 200 else '❌'
            self.stdout.write(
                f"{result['endpoint']:<40} "
                f"{result['avg_time']:.3f} (<{result['min_time']:.3f}-{result['max_time']:.3f})  "
                f"{result['avg_queries']:.1f} (<{result['min_queries']}-{result['max_queries']})  "
                f"{status_icon} {result['status_code']}"
            )
        
        self.stdout.write('')

