"""
Simulator Console UI views - Server-rendered templates for viewing simulator logs
"""
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.core.paginator import Paginator
from django.db.models import Q, Count, Avg
from django.shortcuts import get_object_or_404, render
from django.views.decorators.http import require_http_methods

from .models import HISRequestLog


@login_required
def simulator_logs_list(request):
    """
    Simulator logs list view with filters and statistics.
    
    Features:
    - Server-side pagination
    - Filters (channel, status, date range, hospital)
    - Search (request ID, patient MRN, recipient)
    - Statistics dashboard
    - Channel breakdown
    """
    # Base queryset with optimizations
    queryset = HISRequestLog.objects.all()
    
    # Apply filters
    channel_filter = request.GET.get('channel')
    if channel_filter:
        queryset = queryset.filter(channel=channel_filter)
    
    status_filter = request.GET.get('status')
    if status_filter:
        queryset = queryset.filter(status=status_filter)
    
    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(hospital_code=hospital_filter)
    
    visit_type_filter = request.GET.get('visit_type')
    if visit_type_filter:
        queryset = queryset.filter(visit_type=visit_type_filter)
    
    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(
            Q(request_id__icontains=search_query) |
            Q(patient_id__icontains=search_query) |
            Q(journey_id__icontains=search_query) |
            Q(survey_id__icontains=search_query) |
            Q(recipient__icontains=search_query) |
            Q(subject__icontains=search_query)
        )
    
    # Date range
    date_from = request.GET.get('date_from')
    if date_from:
        queryset = queryset.filter(timestamp__gte=date_from)
    
    date_to = request.GET.get('date_to')
    if date_to:
        queryset = queryset.filter(timestamp__lte=date_to)
    
    # Ordering
    order_by = request.GET.get('order_by', '-timestamp')
    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)
    
    # Get base queryset for statistics (without pagination)
    stats_queryset = HISRequestLog.objects.all()
    
    # Apply same filters to stats
    if channel_filter:
        stats_queryset = stats_queryset.filter(channel=channel_filter)
    if status_filter:
        stats_queryset = stats_queryset.filter(status=status_filter)
    if hospital_filter:
        stats_queryset = stats_queryset.filter(hospital_code=hospital_filter)
    if visit_type_filter:
        stats_queryset = stats_queryset.filter(visit_type=visit_type_filter)
    if search_query:
        stats_queryset = stats_queryset.filter(
            Q(request_id__icontains=search_query) |
            Q(patient_id__icontains=search_query) |
            Q(journey_id__icontains=search_query) |
            Q(survey_id__icontains=search_query) |
            Q(recipient__icontains=search_query) |
            Q(subject__icontains=search_query)
        )
    if date_from:
        stats_queryset = stats_queryset.filter(timestamp__gte=date_from)
    if date_to:
        stats_queryset = stats_queryset.filter(timestamp__lte=date_to)
    
    # Statistics
    total_count = stats_queryset.count()
    success_count = stats_queryset.filter(status__in=['success', 'sent']).count()
    failed_count = stats_queryset.filter(status='failed').count()
    partial_count = stats_queryset.filter(status='partial').count()
    
    # Channel breakdown
    channel_stats = stats_queryset.values('channel').annotate(
        count=Count('request_id')
    ).order_by('-count')
    
    # Status breakdown
    status_stats = stats_queryset.values('status').annotate(
        count=Count('request_id')
    ).order_by('-count')
    
    # Hospital breakdown (for HIS events)
    hospital_stats = stats_queryset.values('hospital_code').annotate(
        count=Count('request_id')
    ).exclude(hospital_code__isnull=True).order_by('-count')
    
    # Visit type breakdown (for HIS events)
    visit_type_stats = stats_queryset.values('visit_type').annotate(
        count=Count('request_id')
    ).exclude(visit_type__isnull=True).order_by('-count')
    
    # Average processing time
    processing_stats = stats_queryset.filter(
        processing_time_ms__isnull=False
    ).aggregate(
        avg_time=Avg('processing_time_ms')
    )
    avg_processing_time = processing_stats['avg_time'] or 0
    
    # Survey invitations sent
    survey_sent_count = stats_queryset.filter(
        channel='his_event',
        status='success'
    ).count()
    
    # Detailed channel counts
    email_count = stats_queryset.filter(channel='email').count()
    sms_count = stats_queryset.filter(channel='sms').count()
    his_event_count = stats_queryset.filter(channel='his_event').count()
    
    stats = {
        'total': total_count,
        'success': success_count,
        'failed': failed_count,
        'partial': partial_count,
        'success_rate': round((success_count / total_count * 100) if total_count > 0 else 0, 1),
        'avg_processing_time': round(avg_processing_time, 2),
        'survey_sent': survey_sent_count,
        'channels': {
            'email': email_count,
            'sms': sms_count,
            'his_event': his_event_count,
        }
    }
    
    context = {
        'page_obj': page_obj,
        'logs': page_obj.object_list,
        'stats': stats,
        'channel_stats': list(channel_stats),
        'status_stats': list(status_stats),
        'hospital_stats': list(hospital_stats),
        'visit_type_stats': list(visit_type_stats),
        'filters': request.GET,
    }
    
    return render(request, 'simulator/log_list.html', context)


@login_required
def simulator_log_detail(request, pk):
    """
    Simulator log detail view.
    
    Features:
    - Full request payload
    - Full response data
    - Processing details
    - Related object links
    - Error details if applicable
    """
    log_entry = get_object_or_404(HISRequestLog, pk=pk)
    
    # Parse JSON for better display
    import json
    
    # Format payload
    payload_formatted = json.dumps(log_entry.payload, indent=2)
    
    # Format response data
    response_formatted = None
    if log_entry.response_data:
        response_formatted = json.dumps(log_entry.response_data, indent=2)
    
    # Get related objects if available
    related_objects = {}
    
    if log_entry.patient_id:
        from apps.organizations.models import Patient
        try:
            patient = Patient.objects.filter(mrn=log_entry.patient_id).first()
            if patient:
                related_objects['patient'] = {
                    'id': str(patient.id),
                    'mrn': patient.mrn,
                    'name': patient.get_full_name(),
                    'phone': patient.phone,
                    'email': patient.email,
                }
        except Exception:
            pass
    
    if log_entry.journey_id:
        from apps.journeys.models import PatientJourneyInstance
        try:
            journey = PatientJourneyInstance.objects.filter(
                encounter_id=log_entry.journey_id
            ).select_related('journey_template', 'patient').first()
            if journey:
                related_objects['journey'] = {
                    'id': str(journey.id),
                    'encounter_id': journey.encounter_id,
                    'patient_name': journey.patient.get_full_name() if journey.patient else None,
                    'journey_type': journey.journey_template.journey_type if journey.journey_template else None,
                    'status': journey.status,
                }
        except Exception:
            pass
    
    if log_entry.survey_id:
        from apps.surveys.models import SurveyInstance
        try:
            survey = SurveyInstance.objects.filter(
                id=log_entry.survey_id
            ).select_related('survey_template', 'patient').first()
            if survey:
                related_objects['survey'] = {
                    'id': str(survey.id),
                    'status': survey.status,
                    'patient_name': survey.patient.get_full_name() if survey.patient else None,
                    'survey_type': survey.survey_template.survey_type if survey.survey_template else None,
                    'total_score': float(survey.total_score) if survey.total_score else None,
                }
        except Exception:
            pass
    
    context = {
        'log': log_entry,
        'payload_formatted': payload_formatted,
        'response_formatted': response_formatted,
        'related_objects': related_objects,
    }
    
    return render(request, 'simulator/log_detail.html', context)


@login_required
@require_http_methods(["POST"])
def simulator_clear_logs(request):
    """
    Clear all simulator logs (admin only).
    
    This is a destructive operation that removes all logged simulator requests.
    """
    # Check if user is admin
    if not (request.user.is_superuser or request.user.is_px_admin()):
        messages.error(request, "You don't have permission to clear simulator logs.")
        return redirect('simulator:logs_list')
    
    try:
        count = HISRequestLog.objects.count()
        HISRequestLog.objects.all().delete()
        
        messages.success(
            request,
            f"Successfully cleared {count} simulator log entries."
        )
        
    except Exception as e:
        messages.error(request, f"Error clearing logs: {str(e)}")
    
    return redirect('simulator:logs_list')
