"""
AI Engine UI views - Server-rendered templates
"""
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Count, Q
from django.shortcuts import get_object_or_404, redirect, render
from django.utils import timezone
from django.views.decorators.http import require_http_methods

from .forms import AnalyzeTextForm, SentimentFilterForm
from .models import SentimentResult
from .services import AIEngineService


@login_required
def sentiment_list(request):
    """
    Sentiment results list view with filters and pagination.
    
    Features:
    - Server-side pagination
    - Advanced filters (sentiment, language, confidence, etc.)
    - Search by text
    - Statistics dashboard
    """
    # Base queryset
    queryset = SentimentResult.objects.select_related('content_type').all()
    
    # Apply filters from request
    sentiment_filter = request.GET.get('sentiment')
    if sentiment_filter:
        queryset = queryset.filter(sentiment=sentiment_filter)
    
    language_filter = request.GET.get('language')
    if language_filter:
        queryset = queryset.filter(language=language_filter)
    
    ai_service_filter = request.GET.get('ai_service')
    if ai_service_filter:
        queryset = queryset.filter(ai_service=ai_service_filter)
    
    min_confidence = request.GET.get('min_confidence')
    if min_confidence:
        try:
            queryset = queryset.filter(confidence__gte=float(min_confidence))
        except ValueError:
            pass
    
    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(text__icontains=search_query)
    
    # Date range filters
    date_from = request.GET.get('date_from')
    if date_from:
        queryset = queryset.filter(created_at__gte=date_from)
    
    date_to = request.GET.get('date_to')
    if date_to:
        queryset = queryset.filter(created_at__lte=date_to)
    
    # Ordering
    order_by = request.GET.get('order_by', '-created_at')
    queryset = queryset.order_by(order_by)
    
    # Pagination
    page_size = int(request.GET.get('page_size', 25))
    paginator = Paginator(queryset, page_size)
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    
    # Statistics
    stats = AIEngineService.get_sentiment_stats(queryset)
    
    # Filter form
    filter_form = SentimentFilterForm(request.GET)
    
    context = {
        'page_obj': page_obj,
        'results': page_obj.object_list,
        'stats': stats,
        'filter_form': filter_form,
        'filters': request.GET,
    }
    
    return render(request, 'ai_engine/sentiment_list.html', context)


@login_required
def sentiment_detail(request, pk):
    """
    Sentiment result detail view.
    
    Features:
    - Full sentiment analysis details
    - Keywords, entities, emotions
    - Link to related object
    """
    result = get_object_or_404(
        SentimentResult.objects.select_related('content_type'),
        pk=pk
    )
    
    # Get related object if it exists
    related_object = None
    try:
        related_object = result.content_object
    except Exception:
        pass
    
    context = {
        'result': result,
        'related_object': related_object,
    }
    
    return render(request, 'ai_engine/sentiment_detail.html', context)


@login_required
@require_http_methods(["GET", "POST"])
def analyze_text_view(request):
    """
    Manual text analysis view.
    
    Allows users to manually analyze text for sentiment.
    """
    result = None
    
    if request.method == 'POST':
        form = AnalyzeTextForm(request.POST)
        if form.is_valid():
            try:
                # Perform analysis
                analysis = AIEngineService.sentiment.analyze_text(
                    text=form.cleaned_data['text'],
                    language=form.cleaned_data.get('language') or None,
                    extract_keywords=form.cleaned_data.get('extract_keywords', True),
                    extract_entities=form.cleaned_data.get('extract_entities', True),
                    detect_emotions=form.cleaned_data.get('detect_emotions', True),
                )
                
                result = analysis
                messages.success(request, "Text analyzed successfully!")
                
            except Exception as e:
                messages.error(request, f"Error analyzing text: {str(e)}")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = AnalyzeTextForm()
    
    context = {
        'form': form,
        'result': result,
    }
    
    return render(request, 'ai_engine/analyze_text.html', context)


@login_required
def sentiment_dashboard(request):
    """
    Sentiment analytics dashboard.
    
    Features:
    - Overall sentiment statistics
    - Sentiment trends over time
    - Top keywords
    - Language distribution
    - Service performance
    """
    # Get date range from request (default: last 30 days)
    from datetime import timedelta
    
    date_from = request.GET.get('date_from')
    date_to = request.GET.get('date_to')
    
    if not date_from:
        date_from = timezone.now() - timedelta(days=30)
    if not date_to:
        date_to = timezone.now()
    
    # Base queryset
    queryset = SentimentResult.objects.filter(
        created_at__gte=date_from,
        created_at__lte=date_to
    )
    
    # Overall statistics
    overall_stats = AIEngineService.get_sentiment_stats(queryset)
    
    # Language distribution
    language_stats = queryset.values('language').annotate(
        count=Count('id')
    ).order_by('-count')
    
    # Sentiment by language
    sentiment_by_language = {}
    for lang in ['en', 'ar']:
        lang_queryset = queryset.filter(language=lang)
        sentiment_by_language[lang] = AIEngineService.get_sentiment_stats(lang_queryset)
    
    # AI service distribution
    service_stats = queryset.values('ai_service').annotate(
        count=Count('id')
    ).order_by('-count')
    
    # Recent results
    recent_results = queryset.select_related('content_type').order_by('-created_at')[:10]
    
    # Top keywords (aggregate from all results)
    all_keywords = []
    for result in queryset:
        all_keywords.extend(result.keywords)
    
    # Count keyword frequency
    from collections import Counter
    keyword_counts = Counter(all_keywords)
    top_keywords = keyword_counts.most_common(20)
    
    # Sentiment trend (by day)
    from django.db.models.functions import TruncDate
    sentiment_trend = queryset.annotate(
        date=TruncDate('created_at')
    ).values('date', 'sentiment').annotate(
        count=Count('id')
    ).order_by('date')
    
    # Organize trend data
    trend_data = {}
    for item in sentiment_trend:
        date_str = item['date'].strftime('%Y-%m-%d')
        if date_str not in trend_data:
            trend_data[date_str] = {'positive': 0, 'neutral': 0, 'negative': 0}
        trend_data[date_str][item['sentiment']] = item['count']
    
    context = {
        'overall_stats': overall_stats,
        'language_stats': language_stats,
        'sentiment_by_language': sentiment_by_language,
        'service_stats': service_stats,
        'recent_results': recent_results,
        'top_keywords': top_keywords,
        'trend_data': trend_data,
        'date_from': date_from,
        'date_to': date_to,
    }
    
    return render(request, 'ai_engine/sentiment_dashboard.html', context)


@login_required
@require_http_methods(["POST"])
def reanalyze_sentiment(request, pk):
    """
    Re-analyze sentiment for a specific result.
    
    This can be useful when the AI model is updated.
    """
    result = get_object_or_404(SentimentResult, pk=pk)
    
    try:
        # Get the related object
        related_object = result.content_object
        
        if related_object:
            # Re-analyze
            new_result = AIEngineService.sentiment.analyze_and_save(
                text=result.text,
                content_object=related_object,
                language=result.language
            )
            
            messages.success(request, "Sentiment re-analyzed successfully!")
            return redirect('ai_engine:sentiment_detail', pk=new_result.id)
        else:
            messages.error(request, "Related object not found.")
            
    except Exception as e:
        messages.error(request, f"Error re-analyzing sentiment: {str(e)}")
    
    return redirect('ai_engine:sentiment_detail', pk=pk)
