"""
Call Center Console UI views
"""
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, Avg
from django.http import JsonResponse
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.complaints.models import Complaint, Inquiry
from apps.px_sources.models import PXSource
from apps.core.services import AuditService
from apps.organizations.models import Department, Hospital, Patient, Staff

from .models import CallCenterInteraction


@login_required
def interaction_list(request):
    """Call center interactions list view"""
    queryset = CallCenterInteraction.objects.select_related(
        'patient', 'hospital', 'department', 'agent'
    )

    # 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
    call_type_filter = request.GET.get('call_type')
    if call_type_filter:
        queryset = queryset.filter(call_type=call_type_filter)

    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    is_low_rating = request.GET.get('is_low_rating')
    if is_low_rating == 'true':
        queryset = queryset.filter(is_low_rating=True)

    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(
            Q(subject__icontains=search_query) |
            Q(caller_name__icontains=search_query) |
            Q(patient__mrn__icontains=search_query)
        )

    # Date range
    date_from = request.GET.get('date_from')
    if date_from:
        queryset = queryset.filter(call_started_at__gte=date_from)

    date_to = request.GET.get('date_to')
    if date_to:
        queryset = queryset.filter(call_started_at__lte=date_to)

    # Ordering
    queryset = queryset.order_by('-call_started_at')

    # 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(),
        'low_rating': queryset.filter(is_low_rating=True).count(),
        'avg_satisfaction': queryset.filter(satisfaction_rating__isnull=False).aggregate(
            avg=Avg('satisfaction_rating')
        )['avg'] or 0,
    }

    context = {
        'page_obj': page_obj,
        'interactions': page_obj.object_list,
        'stats': stats,
        'hospitals': hospitals,
        'filters': request.GET,
    }

    return render(request, 'callcenter/interaction_list.html', context)


@login_required
def interaction_detail(request, pk):
    """Call center interaction detail view"""
    interaction = get_object_or_404(
        CallCenterInteraction.objects.select_related(
            'patient', 'hospital', 'department', 'agent'
        ),
        pk=pk
    )

    context = {
        'interaction': interaction,
    }

    return render(request, 'callcenter/interaction_detail.html', context)


# ============================================================================
# COMPLAINT CREATION FOR CALL CENTER
# ============================================================================

@login_required
@require_http_methods(["GET", "POST"])
def create_complaint(request):
    """
    Create complaint from call center interaction.

    Call center staff can create complaints on behalf of patients/callers.
    """
    if request.method == 'POST':
        try:
            # Get form data
            patient_id = request.POST.get('patient_id', None)
            hospital_id = request.POST.get('hospital_id')
            department_id = request.POST.get('department_id', None)
            staff_id = request.POST.get('staff_id', None)

            title = request.POST.get('title')
            description = request.POST.get('description')
            category = request.POST.get('category')
            subcategory = request.POST.get('subcategory', '')
            priority = request.POST.get('priority')
            severity = request.POST.get('severity')
            encounter_id = request.POST.get('encounter_id', '')

            # Call center specific fields
            caller_name = request.POST.get('caller_name', '')
            caller_phone = request.POST.get('caller_phone', '')
            caller_relationship = request.POST.get('caller_relationship', 'patient')

            # Validate required fields
            if not all([hospital_id, title, description, category, priority, severity]):
                messages.error(request, "Please fill in all required fields.")
                return redirect('callcenter:create_complaint')

            # If no patient selected, we need caller info
            if not patient_id and not caller_name:
                messages.error(request, "Please provide either patient or caller information.")
                return redirect('callcenter:create_complaint')
            
            # Get first active source for call center
            try:
                call_center_source = PXSource.objects.filter(is_active=True).first()
            except PXSource.DoesNotExist:
                messages.error(request, "No active PX sources available.")
                return redirect('callcenter:create_complaint')
            
            # Create complaint
            complaint = Complaint.objects.create(
                patient_id=patient_id if patient_id else None,
                hospital_id=hospital_id,
                department_id=department_id if department_id else None,
                staff_id=staff_id if staff_id else None,
                title=title,
                description=description,
                category=category,
                subcategory=subcategory,
                priority=priority,
                severity=severity,
                source=call_center_source,
                encounter_id=encounter_id,
            )

            # Create call center interaction record
            CallCenterInteraction.objects.create(
                patient_id=patient_id if patient_id else None,
                caller_name=caller_name,
                caller_phone=caller_phone,
                caller_relationship=caller_relationship,
                hospital_id=hospital_id,
                department_id=department_id if department_id else None,
                agent=request.user,
                call_type='complaint',
                subject=title,
                notes=description,
                metadata={
                    'complaint_id': str(complaint.id),
                    'category': category,
                    'severity': severity,
                }
            )

            # Log audit
            AuditService.log_event(
                event_type='complaint_created',
                description=f"Complaint created via call center: {complaint.title}",
                user=request.user,
                content_object=complaint,
                metadata={
                    'category': complaint.category,
                    'severity': complaint.severity,
                    'source': 'call_center',
                    'caller_name': caller_name,
                }
            )

            messages.success(request, f"Complaint #{complaint.id} created successfully.")
            return redirect('callcenter:complaint_success', pk=complaint.id)

        except Exception as e:
            messages.error(request, f"Error creating complaint: {str(e)}")
            return redirect('callcenter:create_complaint')

    # GET request - show form
    hospitals = Hospital.objects.filter(status='active')
    if not request.user.is_px_admin() and request.user.hospital:
        hospitals = hospitals.filter(id=request.user.hospital.id)

    context = {
        'hospitals': hospitals,
    }

    return render(request, 'callcenter/complaint_form.html', context)


@login_required
def complaint_success(request, pk):
    """Success page after creating complaint"""
    complaint = get_object_or_404(Complaint, pk=pk)

    context = {
        'complaint': complaint,
    }

    return render(request, 'callcenter/complaint_success.html', context)


@login_required
def complaint_list(request):
    """List complaints created by call center"""
    queryset = Complaint.objects.filter(
        source=ComplaintSource.CALL_CENTER
    ).select_related(
        'patient', 'hospital', 'department', 'staff', 'assigned_to'
    )

    # 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
    status_filter = request.GET.get('status')
    if status_filter:
        queryset = queryset.filter(status=status_filter)

    severity_filter = request.GET.get('severity')
    if severity_filter:
        queryset = queryset.filter(severity=severity_filter)

    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(
            Q(title__icontains=search_query) |
            Q(description__icontains=search_query) |
            Q(patient__mrn__icontains=search_query)
        )

    # Ordering
    queryset = queryset.order_by('-created_at')

    # 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(),
        'open': queryset.filter(status='open').count(),
        'in_progress': queryset.filter(status='in_progress').count(),
        'resolved': queryset.filter(status='resolved').count(),
    }

    context = {
        'page_obj': page_obj,
        'complaints': page_obj.object_list,
        'stats': stats,
        'hospitals': hospitals,
        'filters': request.GET,
    }

    return render(request, 'callcenter/complaint_list.html', context)


# ============================================================================
# INQUIRY CREATION FOR CALL CENTER
# ============================================================================

@login_required
@require_http_methods(["GET", "POST"])
def create_inquiry(request):
    """
    Create inquiry from call center interaction.

    Call center staff can create inquiries for general questions/requests.
    """
    if request.method == 'POST':
        try:
            # Get form data
            patient_id = request.POST.get('patient_id', None)
            hospital_id = request.POST.get('hospital_id')
            department_id = request.POST.get('department_id', None)

            subject = request.POST.get('subject')
            message = request.POST.get('message')
            category = request.POST.get('category')

            # Contact info (if no patient)
            contact_name = request.POST.get('contact_name', '')
            contact_phone = request.POST.get('contact_phone', '')
            contact_email = request.POST.get('contact_email', '')

            # Call center specific
            caller_relationship = request.POST.get('caller_relationship', 'patient')

            # Validate required fields
            if not all([hospital_id, subject, message, category]):
                messages.error(request, "Please fill in all required fields.")
                return redirect('callcenter:create_inquiry')

            # If no patient, need contact info
            if not patient_id and not contact_name:
                messages.error(request, "Please provide either patient or contact information.")
                return redirect('callcenter:create_inquiry')

            # Create inquiry
            inquiry = Inquiry.objects.create(
                patient_id=patient_id if patient_id else None,
                hospital_id=hospital_id,
                department_id=department_id if department_id else None,
                subject=subject,
                message=message,
                category=category,
                contact_name=contact_name,
                contact_phone=contact_phone,
                contact_email=contact_email,
            )

            # Create call center interaction record
            CallCenterInteraction.objects.create(
                patient_id=patient_id if patient_id else None,
                caller_name=contact_name,
                caller_phone=contact_phone,
                caller_relationship=caller_relationship,
                hospital_id=hospital_id,
                department_id=department_id if department_id else None,
                agent=request.user,
                call_type='inquiry',
                subject=subject,
                notes=message,
                metadata={
                    'inquiry_id': str(inquiry.id),
                    'category': category,
                }
            )

            # Log audit
            AuditService.log_event(
                event_type='inquiry_created',
                description=f"Inquiry created via call center: {inquiry.subject}",
                user=request.user,
                content_object=inquiry,
                metadata={
                    'category': inquiry.category,
                    'source': 'call_center',
                    'contact_name': contact_name,
                }
            )

            messages.success(request, f"Inquiry #{inquiry.id} created successfully.")
            return redirect('callcenter:inquiry_success', pk=inquiry.id)

        except Exception as e:
            messages.error(request, f"Error creating inquiry: {str(e)}")
            return redirect('callcenter:create_inquiry')

    # GET request - show form
    hospitals = Hospital.objects.filter(status='active')
    if not request.user.is_px_admin() and request.user.hospital:
        hospitals = hospitals.filter(id=request.user.hospital.id)

    context = {
        'hospitals': hospitals,
    }

    return render(request, 'callcenter/inquiry_form.html', context)


@login_required
def inquiry_success(request, pk):
    """Success page after creating inquiry"""
    inquiry = get_object_or_404(Inquiry, pk=pk)

    context = {
        'inquiry': inquiry,
    }

    return render(request, 'callcenter/inquiry_success.html', context)


@login_required
def inquiry_list(request):
    """List inquiries created by call center"""
    queryset = Inquiry.objects.select_related(
        'patient', 'hospital', 'department', 'assigned_to', 'responded_by'
    )

    # 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
    status_filter = request.GET.get('status')
    if status_filter:
        queryset = queryset.filter(status=status_filter)

    category_filter = request.GET.get('category')
    if category_filter:
        queryset = queryset.filter(category=category_filter)

    hospital_filter = request.GET.get('hospital')
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    # Search
    search_query = request.GET.get('search')
    if search_query:
        queryset = queryset.filter(
            Q(subject__icontains=search_query) |
            Q(message__icontains=search_query) |
            Q(contact_name__icontains=search_query)
        )

    # Ordering
    queryset = queryset.order_by('-created_at')

    # 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(),
        'open': queryset.filter(status='open').count(),
        'in_progress': queryset.filter(status='in_progress').count(),
        'resolved': queryset.filter(status='resolved').count(),
    }

    context = {
        'page_obj': page_obj,
        'inquiries': page_obj.object_list,
        'stats': stats,
        'hospitals': hospitals,
        'filters': request.GET,
    }

    return render(request, 'callcenter/inquiry_list.html', context)


# ============================================================================
# AJAX/API HELPERS
# ============================================================================

@login_required
def get_departments_by_hospital(request):
    """Get departments for a hospital (AJAX)"""
    hospital_id = request.GET.get('hospital_id')
    if not hospital_id:
        return JsonResponse({'departments': []})

    departments = Department.objects.filter(
        hospital_id=hospital_id,
        status='active'
    ).values('id', 'name', 'name_ar')

    return JsonResponse({'departments': list(departments)})


@login_required
def get_staff_by_hospital(request):
    """Get staff for a hospital (AJAX)"""
    hospital_id = request.GET.get('hospital_id')
    if not hospital_id:
        return JsonResponse({'staff': []})

    staff_members = Staff.objects.filter(
        hospital_id=hospital_id,
        status='active'
    ).values('id', 'first_name', 'last_name', 'staff_type', 'specialization')

    # Format staff names
    staff_list = [
        {
            'id': str(s['id']),
            'name': f"Dr. {s['first_name']} {s['last_name']}" if s['staff_type'] == 'physician' else f"{s['first_name']} {s['last_name']}",
            'staff_type': s['staff_type'],
            'specialization': s['specialization']
        }
        for s in staff_members
    ]

    return JsonResponse({'staff': staff_list})


@login_required
def search_patients(request):
    """Search patients by MRN or name (AJAX)"""
    query = request.GET.get('q', '')
    hospital_id = request.GET.get('hospital_id', None)

    if len(query) < 2:
        return JsonResponse({'patients': []})

    patients = Patient.objects.filter(
        Q(mrn__icontains=query) |
        Q(first_name__icontains=query) |
        Q(last_name__icontains=query) |
        Q(national_id__icontains=query) |
        Q(phone__icontains=query)
    )

    if hospital_id:
        patients = patients.filter(hospital_id=hospital_id)

    patients = patients[:20]

    results = [
        {
            'id': str(p.id),
            'mrn': p.mrn,
            'name': p.get_full_name(),
            'phone': p.phone,
            'email': p.email,
            'national_id': p.national_id,
        }
        for p in patients
    ]

    return JsonResponse({'patients': results})
    
