"""
Custom admin views for AI reporting and conversation views
"""
from django.contrib.admin.views.decorators import staff_member_required
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponse, JsonResponse
from django.template.response import TemplateResponse
from django.db.models import Q, Count
from django.utils import timezone
from django.views.generic import ListView, DetailView
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import get_object_or_404, redirect
from datetime import timedelta
import json

from bazi.models import Person
from liuyao.models import liuyao
from ai.models import Conversation, Message
from ai.utils.conversation import create_conversation, send_conversation_message


@staff_member_required
def ai_reports_dashboard(request):
    """
    Custom dashboard view for AI reports across all analysis types
    """
    # Get reports from all three analysis types
    bazi_reports = Person.objects.filter(bazi_analysis_reported=True).select_related('created_by', 'bazi_report_resolved_by')
    number_reports = Person.objects.filter(number_analysis_reported=True).select_related('created_by', 'number_report_resolved_by') 
    liuyao_reports = liuyao.objects.filter(analysis_reported=True).select_related('user', 'report_resolved_by')
    
    # Calculate statistics
    total_reports = bazi_reports.count() + number_reports.count() + liuyao_reports.count()
    
    pending_bazi = bazi_reports.filter(bazi_report_status='pending').count()
    pending_number = number_reports.filter(number_report_status='pending').count()
    pending_liuyao = liuyao_reports.filter(report_status='pending').count()
    total_pending = pending_bazi + pending_number + pending_liuyao
    
    # Recent reports (last 7 days)
    week_ago = timezone.now() - timedelta(days=7)
    recent_bazi = bazi_reports.filter(bazi_report_timestamp__gte=week_ago).count()
    recent_number = number_reports.filter(number_report_timestamp__gte=week_ago).count()
    recent_liuyao = liuyao_reports.filter(report_timestamp__gte=week_ago).count()
    total_recent = recent_bazi + recent_number + recent_liuyao
    
    # Get latest reports for display
    latest_reports = []
    
    # Add latest BaZi reports
    for person in bazi_reports.order_by('-bazi_report_timestamp')[:5]:
        latest_reports.append({
            'type': 'BaZi',
            'icon': '🔮',
            'name': person.name,
            'user': person.created_by,
            'category': person.bazi_report_category,
            'status': person.bazi_report_status,
            'timestamp': person.bazi_report_timestamp,
            'admin_url': f'/admin/bazi/person/{person.id}/change/',
            'message': person.bazi_report_message[:100] + '...' if person.bazi_report_message and len(person.bazi_report_message) > 100 else person.bazi_report_message
        })
    
    # Add latest Number reports
    for person in number_reports.order_by('-number_report_timestamp')[:5]:
        latest_reports.append({
            'type': 'Number',
            'icon': '🔢',
            'name': person.name,
            'user': person.created_by,
            'category': person.number_report_category,
            'status': person.number_report_status,
            'timestamp': person.number_report_timestamp,
            'admin_url': f'/admin/bazi/person/{person.id}/change/',
            'message': person.number_report_message[:100] + '...' if person.number_report_message and len(person.number_report_message) > 100 else person.number_report_message
        })
    
    # Add latest LiuYao reports
    for entry in liuyao_reports.order_by('-report_timestamp')[:5]:
        latest_reports.append({
            'type': 'LiuYao',
            'icon': '☯️',
            'name': entry.question[:50] + ('...' if len(entry.question) > 50 else ''),
            'user': entry.user,
            'category': entry.report_category,
            'status': entry.report_status,
            'timestamp': entry.report_timestamp,
            'admin_url': f'/admin/liuyao/liuyao/{entry.id}/change/',
            'message': entry.report_message[:100] + '...' if entry.report_message and len(entry.report_message) > 100 else entry.report_message
        })
    
    # Sort by timestamp
    latest_reports.sort(key=lambda x: x['timestamp'] or timezone.datetime.min.replace(tzinfo=timezone.utc), reverse=True)
    latest_reports = latest_reports[:10]  # Show top 10 most recent
    
    # Category statistics
    category_stats = {}
    all_categories = ['inappropriate_content', 'inaccurate_analysis', 'offensive_language', 'technical_error', 'other']
    
    for category in all_categories:
        count = (
            bazi_reports.filter(bazi_report_category=category).count() +
            number_reports.filter(number_report_category=category).count() + 
            liuyao_reports.filter(report_category=category).count()
        )
        if count > 0:
            category_stats[category] = count
    
    context = {
        'title': 'AI Analysis Reports Dashboard',
        'total_reports': total_reports,
        'total_pending': total_pending,
        'total_recent': total_recent,
        'bazi_reports': bazi_reports.count(),
        'number_reports': number_reports.count(),
        'liuyao_reports': liuyao_reports.count(),
        'pending_bazi': pending_bazi,
        'pending_number': pending_number,
        'pending_liuyao': pending_liuyao,
        'recent_bazi': recent_bazi,
        'recent_number': recent_number,
        'recent_liuyao': recent_liuyao,
        'latest_reports': latest_reports,
        'category_stats': category_stats,
        'quick_links': [
            {
                'name': 'All BaZi Reports',
                'url': '/admin/bazi/person/?bazi_analysis_reported__exact=1',
                'count': bazi_reports.count()
            },
            {
                'name': 'All Number Reports', 
                'url': '/admin/bazi/person/?number_analysis_reported__exact=1',
                'count': number_reports.count()
            },
            {
                'name': 'All LiuYao Reports',
                'url': '/admin/liuyao/liuyao/?analysis_reported__exact=1',
                'count': liuyao_reports.count()
            },
            {
                'name': 'Pending BaZi Reports',
                'url': '/admin/bazi/person/?bazi_report_status__exact=pending',
                'count': pending_bazi
            },
            {
                'name': 'Pending Number Reports',
                'url': '/admin/bazi/person/?number_report_status__exact=pending', 
                'count': pending_number
            },
            {
                'name': 'Pending LiuYao Reports',
                'url': '/admin/liuyao/liuyao/?report_status__exact=pending',
                'count': pending_liuyao
            }
        ]
    }
    
    return TemplateResponse(request, 'admin/ai/reports_dashboard.html', context)


class ConversationListView(LoginRequiredMixin, ListView):
    """List all conversations for the current user."""
    model = Conversation
    template_name = 'ai/conversation_list.html'
    context_object_name = 'conversations'
    paginate_by = 20
    
    def get_queryset(self):
        """Get conversations for the current user."""
        return Conversation.objects.filter(user=self.request.user).select_related('person').prefetch_related('messages')


class ConversationDetailView(LoginRequiredMixin, DetailView):
    """View a single conversation and its messages."""
    model = Conversation
    template_name = 'ai/conversation_detail.html'
    context_object_name = 'conversation'
    
    def get_queryset(self):
        """Only allow users to view their own conversations."""
        return Conversation.objects.filter(user=self.request.user).select_related('person', 'user')
    
    def get_context_data(self, **kwargs):
        """Add messages to context."""
        context = super().get_context_data(**kwargs)
        context['messages'] = self.object.messages.all().order_by('created_at')
        context['person'] = self.object.person
        return context


@require_http_methods(["POST"])
def create_conversation_view(request, person_id):
    """Create a new conversation for a person's BaZi chart."""
    if not request.user.is_authenticated:
        return JsonResponse({'error': 'Authentication required'}, status=401)
    
    person = get_object_or_404(Person, pk=person_id, created_by=request.user)
    
    data = json.loads(request.body)
    title = data.get('title', f"Conversation about {person.name}")
    
    try:
        conversation = create_conversation(
            user=request.user,
            person=person,
            title=title
        )
        return JsonResponse({
            'success': True,
            'conversation_id': conversation.id,
            'redirect_url': f'/ai/conversations/{conversation.id}/'
        })
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)


@require_http_methods(["POST"])
def send_message_view(request, conversation_id):
    """Send a message in a conversation and get AI response."""
    if not request.user.is_authenticated:
        return JsonResponse({'error': 'Authentication required'}, status=401)
    
    conversation = get_object_or_404(
        Conversation,
        pk=conversation_id,
        user=request.user
    )
    
    data = json.loads(request.body)
    user_message = data.get('message', '').strip()
    language = data.get('language', 'zh-hans')
    
    if not user_message:
        return JsonResponse({'error': 'Message cannot be empty'}, status=400)
    
    try:
        assistant_message = send_conversation_message(
            conversation=conversation,
            user_message=user_message,
            language=language
        )
        
        return JsonResponse({
            'success': True,
            'message': {
                'id': assistant_message.id,
                'role': assistant_message.role,
                'content': assistant_message.content,
                'created_at': assistant_message.created_at.isoformat(),
                'provider': assistant_message.provider,
                'model': assistant_message.model
            }
        })
    except Exception as e:
        return JsonResponse({'error': str(e)}, status=500)