"""
Survey Console UI views - Server-rendered templates for survey management
"""
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, Prefetch
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 apps.core.services import AuditService
from apps.organizations.models import Department, Hospital

from .models import SurveyInstance, SurveyTemplate
from .tasks import send_satisfaction_feedback


@login_required
def survey_instance_list(request):
    """
    Survey instances list view with filters.
    
    Features:
    - Server-side pagination
    - Filters (status, journey type, hospital, date range)
    - Search by patient MRN
    - Score display
    """
    # Base queryset with optimizations
    queryset = SurveyInstance.objects.select_related(
        'survey_template',
        'patient',
        'journey_instance__journey_template',
        'journey_stage_instance__stage_template'
    ).prefetch_related(
        'responses__question'
    )
    
    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass  # See all
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(survey_template__hospital=user.hospital)
    elif user.hospital:
        queryset = queryset.filter(survey_template__hospital=user.hospital)
    else:
        queryset = queryset.none()
    
    # Apply filters
    status_filter = request.GET.get('status')
    if status_filter:
        queryset = queryset.filter(status=status_filter)
    
    survey_type = request.GET.get('survey_type')
    if survey_type:
        queryset = queryset.filter(survey_template__survey_type=survey_type)
    
    is_negative = request.GET.get('is_negative')
    if is_negative == 'true':
        queryset = queryset.filter(is_negative=True)
    
    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(survey_template__hospital_id=hospital_filter)
    
    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(
            Q(patient__mrn__icontains=search_query) |
            Q(patient__first_name__icontains=search_query) |
            Q(patient__last_name__icontains=search_query) |
            Q(encounter_id__icontains=search_query)
        )
    
    # Date range
    date_from = request.GET.get('date_from')
    if date_from:
        queryset = queryset.filter(sent_at__gte=date_from)
    
    date_to = request.GET.get('date_to')
    if date_to:
        queryset = queryset.filter(sent_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)
    
    # Get filter options
    hospitals = Hospital.objects.filter(status='active')
    if not user.is_px_admin() and user.hospital:
        hospitals = hospitals.filter(id=user.hospital.id)
    
    # Statistics
    stats = {
        'total': queryset.count(),
        'sent': queryset.filter(status='sent').count(),
        'completed': queryset.filter(status='completed').count(),
        'negative': queryset.filter(is_negative=True).count(),
    }
    
    context = {
        'page_obj': page_obj,
        'surveys': page_obj.object_list,
        'stats': stats,
        'hospitals': hospitals,
        'filters': request.GET,
    }
    
    return render(request, 'surveys/instance_list.html', context)


@login_required
def survey_instance_detail(request, pk):
    """
    Survey instance detail view with responses.
    
    Features:
    - Full survey details
    - All responses
    - Score breakdown
    - Related journey/stage info
    """
    survey = get_object_or_404(
        SurveyInstance.objects.select_related(
            'survey_template',
            'patient',
            'journey_instance__journey_template',
            'journey_stage_instance__stage_template'
        ).prefetch_related(
            'responses__question'
        ),
        pk=pk
    )
    
    # Get responses
    responses = survey.responses.all().order_by('question__order')
    
    context = {
        'survey': survey,
        'responses': responses,
    }
    
    return render(request, 'surveys/instance_detail.html', context)


@login_required
def survey_template_list(request):
    """Survey templates list view"""
    queryset = SurveyTemplate.objects.select_related('hospital').prefetch_related('questions')
    
    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()
    
    # Apply filters
    survey_type = request.GET.get('survey_type')
    if survey_type:
        queryset = queryset.filter(survey_type=survey_type)
    
    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)
    
    is_active = request.GET.get('is_active')
    if is_active == 'true':
        queryset = queryset.filter(is_active=True)
    elif is_active == 'false':
        queryset = queryset.filter(is_active=False)
    
    # Ordering
    queryset = queryset.order_by('hospital', 'survey_type', 'name')
    
    # 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 filter options
    hospitals = Hospital.objects.filter(status='active')
    if not user.is_px_admin() and user.hospital:
        hospitals = hospitals.filter(id=user.hospital.id)
    
    context = {
        'page_obj': page_obj,
        'templates': page_obj.object_list,
        'hospitals': hospitals,
        'filters': request.GET,
    }
    
    return render(request, 'surveys/template_list.html', context)


@login_required
@require_http_methods(["POST"])
def survey_log_patient_contact(request, pk):
    """
    Log patient contact for negative survey.
    
    This records that the user contacted the patient to discuss
    the negative survey feedback.
    """
    survey = get_object_or_404(SurveyInstance, pk=pk)
    
    # Check permission
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and survey.survey_template.hospital != user.hospital:
            messages.error(request, "You don't have permission to modify this survey.")
            return redirect('surveys:instance_detail', pk=pk)
    
    # Check if survey is negative
    if not survey.is_negative:
        messages.warning(request, "This survey is not marked as negative.")
        return redirect('surveys:instance_detail', pk=pk)
    
    # Get form data
    contact_notes = request.POST.get('contact_notes', '')
    issue_resolved = request.POST.get('issue_resolved') == 'on'
    
    if not contact_notes:
        messages.error(request, "Please provide contact notes.")
        return redirect('surveys:instance_detail', pk=pk)
    
    try:
        # Update survey
        survey.patient_contacted = True
        survey.patient_contacted_at = timezone.now()
        survey.patient_contacted_by = user
        survey.contact_notes = contact_notes
        survey.issue_resolved = issue_resolved
        survey.save(update_fields=[
            'patient_contacted', 'patient_contacted_at', 
            'patient_contacted_by', 'contact_notes', 'issue_resolved'
        ])
        
        # Log audit
        AuditService.log_event(
            event_type='survey_patient_contacted',
            description=f"Patient contacted for negative survey by {user.get_full_name()}",
            user=user,
            content_object=survey,
            metadata={
                'contact_notes': contact_notes,
                'issue_resolved': issue_resolved,
                'survey_score': float(survey.total_score) if survey.total_score else None
            }
        )
        
        status = "resolved" if issue_resolved else "discussed"
        messages.success(request, f"Patient contact logged successfully. Issue marked as {status}.")
        
    except Exception as e:
        messages.error(request, f"Error logging patient contact: {str(e)}")
    
    return redirect('surveys:instance_detail', pk=pk)


@login_required
@require_http_methods(["POST"])
def survey_send_satisfaction_feedback(request, pk):
    """
    Send satisfaction feedback form to patient.
    
    This creates and sends a feedback form to assess patient satisfaction
    with how their negative survey concerns were addressed.
    """
    survey = get_object_or_404(SurveyInstance, pk=pk)
    
    # Check permission
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        if user.hospital and survey.survey_template.hospital != user.hospital:
            messages.error(request, "You don't have permission to modify this survey.")
            return redirect('surveys:instance_detail', pk=pk)
    
    # Check if survey is negative
    if not survey.is_negative:
        messages.warning(request, "This survey is not marked as negative.")
        return redirect('surveys:instance_detail', pk=pk)
    
    # Check if patient was contacted
    if not survey.patient_contacted:
        messages.error(request, "Please log patient contact before sending satisfaction feedback.")
        return redirect('surveys:instance_detail', pk=pk)
    
    # Check if already sent
    if survey.satisfaction_feedback_sent:
        messages.warning(request, "Satisfaction feedback has already been sent for this survey.")
        return redirect('surveys:instance_detail', pk=pk)
    
    try:
        # Trigger async task to send satisfaction feedback
        send_satisfaction_feedback.delay(str(survey.id), str(user.id))
        
        messages.success(
            request, 
            "Satisfaction feedback form is being sent to the patient. "
            "They will receive a link to provide their feedback."
        )
        
    except Exception as e:
        messages.error(request, f"Error sending satisfaction feedback: {str(e)}")
    
    return redirect('surveys:instance_detail', pk=pk)
