"""
Complaints UI views - Server-rendered templates for complaints console
"""

import logging

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, Prefetch
from django.http import HttpResponseForbidden, JsonResponse
from django.shortcuts import get_object_or_404, redirect, render
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.views.decorators.http import require_http_methods

from apps.accounts.models import User
from apps.accounts.services import StaffActivityService
from apps.core.services import AuditService
from apps.core.decorators import hospital_admin_required, block_source_user, px_admin_required
from apps.organizations.models import Department, Hospital, Staff
from apps.observations.models import Observation
from apps.px_sources.models import SourceUser, PXSource

from .models import (
    Complaint,
    ComplaintAttachment,
    ComplaintCategory,
    ComplaintExplanation,
    ComplaintSourceType,
    ComplaintStatus,
    ComplaintType,
    ComplaintUpdate,
    Inquiry,
    InquiryAttachment,
    InquiryUpdate,
    ComplaintAdverseAction,
    ComplaintAdverseActionAttachment,
    GovernmentTicket,
)
from .services.complaint_service import ComplaintService, ComplaintServiceError
from .forms import (
    ComplaintForm,
    ComplaintInvolvedDepartmentForm,
    ComplaintInvolvedStaffForm,
    DepartmentResponseForm,
    StaffExplanationForm,
    GovernmentTicketForm,
)

# Set up logger
logger = logging.getLogger(__name__)


def _format_duration(start, end):
    """Format duration between two datetimes as a human-readable string."""
    if not start or not end:
        return None
    duration = end - start
    total_seconds = int(duration.total_seconds())
    if total_seconds < 60:
        return "1m"
    days = total_seconds // 86400
    hours = (total_seconds % 86400) // 3600
    minutes = (total_seconds % 3600) // 60
    parts = []
    if days > 0:
        parts.append(f"{days}d")
    if hours > 0:
        parts.append(f"{hours}h")
    if minutes > 0 and days == 0:
        parts.append(f"{minutes}m")
    return " ".join(parts) if parts else "1m"


def _build_complaint_stage_timeline(complaint):
    """Build stage timeline with timestamps and durations for a complaint."""
    from .models import ComplaintExplanation, ComplaintInvolvedDepartment, ComplaintUpdate

    stages = []

    status_updates = list(
        ComplaintUpdate.objects.filter(
            complaint=complaint,
            update_type__in=["status_change", "escalation", "assignment"],
        ).select_related("created_by").order_by("created_at")
    )

    def _find_update(new_status=None, msg_contains=None, update_type=None):
        for u in status_updates:
            if update_type and u.update_type != update_type:
                continue
            if new_status and u.new_status != new_status:
                continue
            if msg_contains and msg_contains not in (u.message or ""):
                continue
            return u
        return None

    def _user_name(user):
        return user.get_full_name() if user else None

    if complaint.created_at:
        performed_by = _user_name(complaint.created_by) if complaint.created_by else str(_("Patient"))
        stages.append({"label": _("Created"), "timestamp": complaint.created_at, "color": "bg-slate-400", "icon": "plus-circle", "performed_by": performed_by})

    if complaint.activated_at:
        activate_update = _find_update(msg_contains="activated", update_type="assignment")
        if not activate_update:
            activate_update = _find_update(new_status="in_progress")
        performed_by = _user_name(activate_update.created_by) if activate_update else None
        stages.append({"label": _("Activated"), "timestamp": complaint.activated_at, "color": "bg-blue-500", "icon": "play-circle", "performed_by": performed_by})

    forwarded_ts = complaint.forwarded_to_dept_at
    if not forwarded_ts:
        earliest_dept = ComplaintInvolvedDepartment.objects.filter(
            complaint=complaint,
            forwarded_at__isnull=False,
        ).select_related("department").order_by("forwarded_at").first()
        if earliest_dept:
            forwarded_ts = earliest_dept.forwarded_at
    if forwarded_ts:
        fwd_update = _find_update(msg_contains="sent to")
        performed_by = _user_name(fwd_update.created_by) if fwd_update else None
        stages.append({"label": _("Forwarded to Department"), "timestamp": forwarded_ts, "color": "bg-purple-500", "icon": "send", "performed_by": performed_by})

    status_update = _find_update(msg_contains="contacted")
    if status_update:
        performed_by = _user_name(status_update.created_by)
        stages.append({"label": _("Contacted"), "timestamp": status_update.created_at, "color": "bg-indigo-500", "icon": "phone", "performed_by": performed_by})

    if complaint.escalated_at:
        esc_update = _find_update(update_type="escalation")
        performed_by = _user_name(esc_update.created_by) if esc_update else None
        stages.append({"label": _("Escalated"), "timestamp": complaint.escalated_at, "color": "bg-red-500", "icon": "alert-triangle", "performed_by": performed_by})

    if complaint.escalated_ovr_at:
        performed_by = _user_name(complaint.escalated_ovr_by)
        stages.append({"label": _("OVR Escalated"), "timestamp": complaint.escalated_ovr_at, "color": "bg-rose-600", "icon": "shield-alert", "performed_by": performed_by})

    earliest_response = complaint.response_date
    first_explanation = None
    if not earliest_response:
        first_explanation = ComplaintExplanation.objects.filter(
            complaint=complaint,
            responded_at__isnull=False,
        ).select_related("staff").order_by("responded_at").first()
        if first_explanation:
            earliest_response = first_explanation.responded_at
    if earliest_response:
        performed_by = _user_name(first_explanation.staff) if first_explanation else None
        stages.append({"label": _("Department Responded"), "timestamp": earliest_response, "color": "bg-amber-500", "icon": "message-square", "performed_by": performed_by})

    if complaint.resolved_at:
        performed_by = _user_name(complaint.resolved_by)
        if not performed_by:
            resolved_update = _find_update(new_status="resolved")
            performed_by = _user_name(resolved_update.created_by) if resolved_update else None
        stages.append({"label": _("Resolved"), "timestamp": complaint.resolved_at, "color": "bg-green-500", "icon": "check-circle", "performed_by": performed_by})

    if complaint.partially_resolved_at:
        performed_by = _user_name(complaint.partially_resolved_by)
        if not performed_by:
            pr_update = _find_update(new_status="partially_resolved")
            performed_by = _user_name(pr_update.created_by) if pr_update else None
        stages.append({"label": _("Partially Resolved"), "timestamp": complaint.partially_resolved_at, "color": "bg-yellow-500", "icon": "alert-circle", "performed_by": performed_by})

    if complaint.pending_external_set_at:
        pe_update = _find_update(new_status="pending_external")
        performed_by = _user_name(pe_update.created_by) if pe_update else None
        stages.append({"label": _("Pending External"), "timestamp": complaint.pending_external_set_at, "color": "bg-orange-500", "icon": "clock", "performed_by": performed_by})

    if complaint.closed_at:
        performed_by = _user_name(complaint.closed_by)
        if not performed_by:
            closed_update = _find_update(new_status="closed")
            performed_by = _user_name(closed_update.created_by) if closed_update else None
        stages.append({"label": _("Closed"), "timestamp": complaint.closed_at, "color": "bg-emerald-600", "icon": "circle-check", "performed_by": performed_by})

    if complaint.cancelled_at:
        performed_by = _user_name(complaint.cancelled_by)
        if not performed_by:
            cancelled_update = _find_update(new_status="cancelled")
            performed_by = _user_name(cancelled_update.created_by) if cancelled_update else None
        stages.append({"label": _("Cancelled"), "timestamp": complaint.cancelled_at, "color": "bg-rose-500", "icon": "x-circle", "performed_by": performed_by})

    stages.sort(key=lambda s: s["timestamp"])

    for i, stage in enumerate(stages):
        stage["duration_from_prev"] = _format_duration(stages[i - 1]["timestamp"], stage["timestamp"]) if i > 0 else None

    total_time = None
    if len(stages) >= 2:
        total_time = _format_duration(stages[0]["timestamp"], stages[-1]["timestamp"])

    return {"stages": stages, "total_time": total_time}


def _build_inquiry_stage_timeline(inquiry):
    """Build stage timeline with timestamps and durations for an inquiry."""
    from .models import InquiryUpdate

    stages = []

    status_updates = list(
        InquiryUpdate.objects.filter(
            inquiry=inquiry,
        ).select_related("created_by").order_by("created_at")
    )

    def _find_update(new_status=None, msg_contains=None, update_type=None):
        for u in status_updates:
            if update_type and u.update_type != update_type:
                continue
            if new_status and u.new_status != new_status:
                continue
            if msg_contains and msg_contains not in (u.message or ""):
                continue
            return u
        return None

    def _user_name(user):
        return user.get_full_name() if user else None

    if inquiry.created_at:
        performed_by = _user_name(inquiry.created_by) if inquiry.created_by else str(_("Patient"))
        stages.append({"label": _("Created"), "timestamp": inquiry.created_at, "color": "bg-slate-400", "icon": "plus-circle", "performed_by": performed_by})

    if inquiry.activated_at:
        activate_update = _find_update(msg_contains="activated", update_type="assignment")
        if not activate_update:
            activate_update = _find_update(new_status="in_progress")
        performed_by = _user_name(activate_update.created_by) if activate_update else None
        stages.append({"label": _("Activated"), "timestamp": inquiry.activated_at, "color": "bg-blue-500", "icon": "play-circle", "performed_by": performed_by})

    if inquiry.transferred_at:
        performed_by = _user_name(inquiry.transferred_by) if hasattr(inquiry, 'transferred_by') else None
        if not performed_by:
            fwd_update = _find_update(update_type="transferred_to_department")
            performed_by = _user_name(fwd_update.created_by) if fwd_update else None
        stages.append({"label": _("Transferred to Department"), "timestamp": inquiry.transferred_at, "color": "bg-purple-500", "icon": "send", "performed_by": performed_by})

    if inquiry.contacted_at:
        performed_by = _user_name(inquiry.contacted_by) if hasattr(inquiry, 'contacted_by') else None
        stages.append({"label": _("Contacted"), "timestamp": inquiry.contacted_at, "color": "bg-indigo-500", "icon": "phone", "performed_by": performed_by})

    if inquiry.contacted_nr_at:
        performed_by = _user_name(inquiry.contacted_nr_by) if hasattr(inquiry, 'contacted_nr_by') else None
        stages.append({"label": _("Contacted No Response"), "timestamp": inquiry.contacted_nr_at, "color": "bg-orange-500", "icon": "phone-off", "performed_by": performed_by})

    if getattr(inquiry, 'dept_response_escalated_at', None):
        esc_update = _find_update(msg_contains="escalat")
        performed_by = _user_name(esc_update.created_by) if esc_update else None
        stages.append({"label": _("Dept Response Escalated"), "timestamp": inquiry.dept_response_escalated_at, "color": "bg-red-500", "icon": "alert-triangle", "performed_by": performed_by})

    if inquiry.department_responded_at:
        performed_by = _user_name(inquiry.department_responded_by) if hasattr(inquiry, 'department_responded_by') else None
        stages.append({"label": _("Department Responded"), "timestamp": inquiry.department_responded_at, "color": "bg-amber-500", "icon": "message-square", "performed_by": performed_by})

    if inquiry.responded_at:
        performed_by = _user_name(inquiry.responded_by) if hasattr(inquiry, 'responded_by') else None
        stages.append({"label": _("Response Sent"), "timestamp": inquiry.responded_at, "color": "bg-cyan-500", "icon": "reply", "performed_by": performed_by})

    _resolved_at = getattr(inquiry, 'resolved_at', None)
    if _resolved_at:
        resolved_update = _find_update(new_status="resolved")
        performed_by = _user_name(resolved_update.created_by) if resolved_update else None
        stages.append({"label": _("Resolved"), "timestamp": _resolved_at, "color": "bg-green-500", "icon": "check-circle", "performed_by": performed_by})

    _closed_at = getattr(inquiry, 'closed_at', None)
    if _closed_at:
        closed_update = _find_update(new_status="closed")
        performed_by = _user_name(closed_update.created_by) if closed_update else None
        stages.append({"label": _("Closed"), "timestamp": _closed_at, "color": "bg-emerald-600", "icon": "circle-check", "performed_by": performed_by})

    stages.sort(key=lambda s: s["timestamp"])

    for i, stage in enumerate(stages):
        stage["duration_from_prev"] = _format_duration(stages[i - 1]["timestamp"], stage["timestamp"]) if i > 0 else None

    total_time = None
    if len(stages) >= 2:
        total_time = _format_duration(stages[0]["timestamp"], stages[-1]["timestamp"])

    return {"stages": stages, "total_time": total_time}


def can_manage_complaint(user, complaint):
    return ComplaintService.can_manage(user, complaint)


@login_required
def complaint_list(request):
    """
    Complaints list view with advanced filters and pagination.

    Features:
    - Server-side pagination
    - Advanced filters (status, severity, priority, hospital, department, etc.)
    - Search by title, description, patient MRN
    - Bulk actions support
    - Export capability
    """
    # Base queryset with optimizations
    queryset = Complaint.objects.select_related(
        "patient",
        "hospital",
        "department",
        "staff",
        "assigned_to",
        "resolved_by",
        "closed_by",
        "source",
        "created_by",
        "domain",
        "category",
        "resolution_survey",
    )

    # Apply RBAC filters
    user = request.user
    # Get selected hospital for PX Admins (from middleware)
    selected_hospital = getattr(request, "tenant_hospital", None)

    if user.is_px_admin():
        if selected_hospital:
            queryset = queryset.filter(hospital=selected_hospital)
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.is_department_manager() and user.department:
        queryset = queryset.filter(department=user.department)
    elif user.is_champion() and user.department:
        queryset = queryset.filter(department=user.department)
    elif user.is_source_user():
        queryset = queryset.filter(created_by=user)
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply filters from request
    status_filter = request.GET.get("status")
    if status_filter:
        values = [v.strip() for v in status_filter.split(",")]
        queryset = queryset.filter(status__in=values)

    # Complaint Type filter (complaint vs appreciation)
    complaint_type_filter = request.GET.get("complaint_type")
    if complaint_type_filter:
        queryset = queryset.filter(complaint_type=complaint_type_filter)

    # Source Type filter (internal vs external)
    source_type_filter = request.GET.get("complaint_source_type")
    if source_type_filter:
        queryset = queryset.filter(complaint_source_type=source_type_filter)

    # PX Source filter
    px_source_filter = request.GET.get("px_source")
    if px_source_filter:
        queryset = queryset.filter(source_id=px_source_filter)

    # Domain filter (taxonomy)
    domain_filter = request.GET.get("domain")
    if domain_filter:
        queryset = queryset.filter(domain_id=domain_filter)

    # Resolution survey filter
    has_survey_filter = request.GET.get("has_survey")
    if has_survey_filter == "yes":
        queryset = queryset.filter(resolution_survey__isnull=False)
    elif has_survey_filter == "no":
        queryset = queryset.filter(resolution_survey__isnull=True)

    severity_filter = request.GET.get("severity")
    if severity_filter:
        values = [v.strip() for v in severity_filter.split(",")]
        queryset = queryset.filter(severity__in=values)

    priority_filter = request.GET.get("priority")
    if priority_filter:
        queryset = queryset.filter(priority=priority_filter)

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

    source_filter = request.GET.get("source")
    if source_filter:
        queryset = queryset.filter(source=source_filter)

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

    department_filter = request.GET.get("department")
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)

    staff_filter = request.GET.get("staff")
    if staff_filter:
        queryset = queryset.filter(staff_id=staff_filter)

    assigned_to_filter = request.GET.get("assigned_to")
    if assigned_to_filter:
        queryset = queryset.filter(assigned_to_id=assigned_to_filter)

    overdue_filter = request.GET.get("is_overdue")
    if overdue_filter == "true":
        queryset = queryset.filter(is_overdue=True)

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

    # Date range filters (created date)
    date_from = request.GET.get("date_from")
    if not date_from and "date_from" not in request.GET:
        date_from = "2026-01-01"
    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 + " 23:59:59" if len(date_to) == 10 else date_to)

    # Incident date range filters
    incident_from = request.GET.get("incident_from")
    if incident_from:
        queryset = queryset.filter(incident_date__gte=incident_from)

    incident_to = request.GET.get("incident_to")
    if incident_to:
        queryset = queryset.filter(incident_date__lte=incident_to)

    # Ordering
    order_by = request.GET.get("order_by", "-created_at")
    queryset = queryset.order_by(order_by)

    # Annotate each complaint with can_edit flag
    for complaint in queryset:
        complaint.can_edit = ComplaintService.can_manage(user, complaint)

    # 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)

    departments = Department.objects.filter(status="active")
    if not user.is_px_admin() and user.hospital:
        departments = departments.filter(hospital=user.hospital)

    # Get assignable users
    from apps.core.utils import get_assignable_users
    assignable_users = get_assignable_users(user.hospital)

    # Statistics - more comprehensive
    total_count = queryset.count()
    resolved_count = queryset.filter(status=ComplaintStatus.RESOLVED).count()
    pending_count = queryset.filter(status__in=[ComplaintStatus.OPEN, ComplaintStatus.IN_PROGRESS]).count()

    base_stats = {
        "total": total_count,
        "open": queryset.filter(status=ComplaintStatus.OPEN).count(),
        "in_progress": queryset.filter(status=ComplaintStatus.IN_PROGRESS).count(),
        "resolved": resolved_count,
        "pending": pending_count,
        "resolved_percentage": (resolved_count / total_count * 100) if total_count > 0 else 0,
        "open_percentage": (queryset.filter(status=ComplaintStatus.OPEN).count() / total_count * 100) if total_count > 0 else 0,
        "in_progress_percentage": (queryset.filter(status=ComplaintStatus.IN_PROGRESS).count() / total_count * 100) if total_count > 0 else 0,
        "pending_percentage": (pending_count / total_count * 100) if total_count > 0 else 0,
        "overdue": queryset.filter(is_overdue=True).count(),
        "overdue_percentage": (queryset.filter(is_overdue=True).count() / total_count * 100) if total_count > 0 else 0,
        "complaints": queryset.filter(complaint_type=ComplaintType.COMPLAINT).count(),
        "appreciations": queryset.filter(complaint_type=ComplaintType.APPRECIATION).count(),
        "from_px_sources": queryset.filter(source__isnull=False).count(),
        "internal": queryset.filter(complaint_source_type=ComplaintSourceType.INTERNAL).count(),
        "reopened": queryset.filter(reopened_from__isnull=False).count(),
        "escalated_ovr": queryset.filter(is_escalated_ovr=True).count(),
    }

    # Get filter options
    from apps.px_sources.models import PXSource
    from apps.complaints.models import ComplaintCategory

    px_sources = PXSource.objects.filter(is_active=True)

    # Get domains for taxonomy filter
    domains = ComplaintCategory.objects.filter(level=ComplaintCategory.LevelChoices.DOMAIN, is_active=True)

    context = {
        "complaints": page_obj,
        "page_obj": page_obj,
        "stats": base_stats,
        "hospitals": hospitals,
        "departments": departments,
        "assignable_users": assignable_users,
        "px_sources": px_sources,
        "domains": domains,
        "status_choices": ComplaintStatus.choices,
        "complaint_type_choices": ComplaintType.choices,
        "source_type_choices": ComplaintSourceType.choices,
        "filters": request.GET,
        "status_filter": status_filter,
        "severity_filter": severity_filter,
        "priority_filter": priority_filter,
        "category_filter": category_filter,
        "source_filter": source_filter,
        "hospital_filter": hospital_filter,
        "department_filter": department_filter,
        "assigned_to_filter": assigned_to_filter,
        "overdue_filter": overdue_filter,
        "search_query": search_query,
        "date_from": date_from,
        "date_to": date_to or "",
    }

    return render(request, "complaints/complaint_list.html", context)


@login_required
def complaint_detail(request, pk):
    """
    Complaint detail view with timeline, attachments, and actions.

    Features:
    - Full complaint details
    - Timeline of all updates
    - Attachments management
    - Related surveys and journey
    - Linked PX actions
    - Workflow actions (assign, status change, add note)

    PERFORMANCE OPTIMIZATIONS:
    - Added missing select_related fields to main query
    - Annotated counts to avoid N+1 queries in template
    - Used prefetched data instead of re-querying
    - Optimized escalation targets query
    - Prefetched explanations with attachments
    """
    from apps.px_sources.models import SourceUser

    source_user = SourceUser.objects.filter(user=request.user).first()
    base_layout = "layouts/source_user_base.html" if source_user else "layouts/base.html"

    complaint_queryset = (
        Complaint.objects.select_related(
            "patient",
            "hospital",
            "department",
            "staff",
            "assigned_to",
            "resolved_by",
            "closed_by",
            "resolution_survey",
            "source",
            "created_by",
            "domain",
            "category",
            "subcategory_obj",
            "classification_obj",
        )
        .prefetch_related(
            "attachments",
            "updates__created_by",
            "involved_departments__department",
            "involved_departments__assigned_to",
            "involved_staff__staff__department",
            Prefetch(
                "explanations",
                queryset=ComplaintExplanation.objects.select_related("staff")
                .prefetch_related("attachments")
                .order_by("-created_at"),
            ),
            Prefetch(
                "adverse_actions",
                queryset=ComplaintAdverseAction.objects.select_related("reported_by").prefetch_related(
                    "involved_staff"
                ),
            ),
        )
        .annotate(
            updates_count=Count("updates", distinct=True),
            attachments_count=Count("attachments", distinct=True),
            involved_departments_count=Count("involved_departments", distinct=True),
            involved_staff_count=Count("involved_staff", distinct=True),
            explanations_count=Count("explanations", distinct=True),
            adverse_actions_count=Count("adverse_actions", distinct=True),
        )
    )

    complaint = get_object_or_404(complaint_queryset, pk=pk)

    user = request.user
    if not user.is_px_admin():
        if user.is_hospital_admin() and complaint.hospital != user.hospital:
            messages.error(request, "You don't have permission to view this complaint.")
            return redirect("complaints:complaint_list")
        elif user.is_department_manager() and complaint.department != user.department:
            messages.error(request, "You don't have permission to view this complaint.")
            return redirect("complaints:complaint_list")
        elif user.hospital and complaint.hospital != user.hospital:
            messages.error(request, "You don't have permission to view this complaint.")
            return redirect("complaints:complaint_list")

    timeline = sorted(complaint.updates.all(), key=lambda x: x.created_at, reverse=True)
    attachments = sorted(complaint.attachments.all(), key=lambda x: x.created_at, reverse=True)

    from django.contrib.contenttypes.models import ContentType
    from apps.px_action_center.models import PXAction

    complaint_ct = ContentType.objects.get_for_model(Complaint)
    px_actions = PXAction.objects.filter(content_type=complaint_ct, object_id=complaint.id).order_by("-created_at")

    assignable_users = User.objects.filter(is_active=True)
    if complaint.hospital:
        assignable_users = assignable_users.filter(hospital=complaint.hospital)

    hospital_departments = []
    if complaint.hospital:
        hospital_departments = Department.objects.filter(hospital=complaint.hospital, status="active").order_by("name")

    if complaint.is_active_status and not complaint.is_overdue:
        complaint.check_overdue()

    explanations = complaint.explanations.all()
    explanation = explanations.first() if explanations else None
    explanation_attachments = explanation.attachments.all() if explanation else []

    escalation_targets = []
    default_escalation_target = None

    if complaint.department:
        dept = Department.objects.filter(pk=complaint.department_id).first()
        if dept:
            for holder in dept.get_role_holders():
                staff = holder["staff"]
                has_user = staff.user and staff.user.is_active
                has_email = bool(staff.email)
                if has_user or has_email:
                    escalation_targets.append({
                        "staff": staff,
                        "has_user": has_user,
                        "user_id": str(staff.user.id) if has_user else "",
                        "is_manager": False,
                        "is_line_manager": False,
                        "role_label": holder["role_label"],
                        "group": "department_roles",
                    })
            if escalation_targets:
                default_escalation_target = str(escalation_targets[0]["staff"].id)

    adverse_actions = complaint.adverse_actions.all()

    from apps.rca.models import RootCauseAnalysis as RCA

    linked_rcas = RCA.objects.filter(
        content_type=complaint_ct, object_id=complaint.pk, is_deleted=False
    ).select_related("assigned_to", "created_by")

    stage_timeline = _build_complaint_stage_timeline(complaint)

    context = {
        "complaint": complaint,
        "timeline": timeline,
        "attachments": attachments,
        "px_actions": px_actions,
        "assignable_users": assignable_users,
        "status_choices": ComplaintStatus.choices,
        "base_layout": base_layout,
        "source_user": source_user,
        "can_edit": can_manage_complaint(user, complaint),
        "can_review_dept_response": user.is_px_admin() or user.is_hospital_admin(),
        "is_active_status": complaint.is_active_status,
        "ai_department_suggested": (
            bool(complaint.department)
            and not complaint.involved_departments.filter(department=complaint.department).exists()
        ),
        "hospital_departments": hospital_departments,
        "explanation": explanation,
        "explanations": explanations,
        "explanation_attachments": explanation_attachments,
        "escalation_targets": escalation_targets,
        "default_escalation_target": default_escalation_target,
        "escalation_email_subject": f"Complaint Escalated - {complaint.reference_number} - {complaint.title or 'N/A'}",
        "escalation_email_body": (
            f"Dear Manager,\n\n"
            f"This complaint has been escalated and requires your immediate attention.\n\n"
            f"Reference: {complaint.reference_number}\n"
            f"Title: {complaint.title or 'N/A'}\n"
            f"Severity: {complaint.get_severity_display()}\n"
            f"Priority: {complaint.get_priority_display()}\n"
            f"Status: {complaint.get_status_display()}\n\n"
            f"Please review and take appropriate action.\n\n"
            f"View: https://{request.get_host()}/organizations/departments/{complaint.department.pk}/"
        ),
        "current_user": user,
        "adverse_actions": adverse_actions,
        "linked_rcas": linked_rcas,
        "stage_timeline": stage_timeline,
        "show_delay_reason_closure": (
            complaint.delay_reason_closure
            or complaint.is_overdue
            or (timezone.now() - complaint.created_at).total_seconds() / 3600 > 72
            or complaint.status in ("closed", "resolved")
        ),
    }

    from django.contrib.contenttypes.models import ContentType
    complaint_ct = ContentType.objects.get_for_model(complaint)
    context["content_type_id"] = complaint_ct.pk
    context["object_id"] = complaint.pk
    context["notes"] = complaint.notes.select_related("created_by").all()
    context["notes_count"] = context["notes"].count()

    return render(request, "complaints/complaint_detail.html", context)


@login_required
@require_http_methods(["POST"])
def complaint_assign(request, pk):
    """Assign complaint to user - Admin or currently assigned user"""
    complaint = get_object_or_404(Complaint, pk=pk)

    user_id = request.POST.get("user_id")
    if not user_id:
        messages.error(request, "Please select a user to assign.")
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        assignee = User.objects.get(id=user_id)
        old_status = complaint.status
        ComplaintService.assign(complaint, assignee, request.user, request=request)
    except User.DoesNotExist:
        messages.error(request, "User not found.")
        return redirect("complaints:complaint_detail", pk=pk)
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        from apps.notifications.settings_service import NotificationServiceWithSettings
        NotificationServiceWithSettings.send_complaint_assigned(
            assignee.email if assignee.email else None,
            complaint,
        )
    except Exception:
        pass

    messages.success(request, f"Complaint assigned to {assignee.get_full_name()}.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["GET", "POST"])
def complaint_create(request):
    """Create new complaint with AI-powered classification"""
    # Determine base layout based on user type
    from apps.px_sources.models import SourceUser

    source_user = SourceUser.objects.filter(user=request.user).first()
    base_layout = "layouts/source_user_base.html" if source_user else "layouts/base.html"

    if request.method == "POST":
        # Handle form submission
        form = ComplaintForm(request.POST, request=request)

        if not form.is_valid():
            # Debug: print form errors
            print("Form validation errors:", form.errors)
            messages.error(request, f"Please correct the errors: {form.errors}")
            context = {
                "form": form,
                "base_layout": base_layout,
                "source_user": source_user,
            }
            return render(request, "complaints/complaint_form.html", context)

        try:
            # Create complaint with AI defaults
            complaint = form.save(commit=False)

            # Set AI-determined defaults
            complaint.title = "Complaint"  # AI will generate title
            # category can be None, AI will determine it
            complaint.subcategory = ""  # AI will determine

            # Set source from form if selected, otherwise from logged-in source user
            if form.cleaned_data.get("source"):
                # User explicitly selected a PX source
                complaint.source = form.cleaned_data["source"]
            elif source_user and source_user.source:
                # Source user is submitting (auto-assign their source)
                complaint.source = source_user.source
            else:
                # Fallback: get or create a 'staff' source
                from apps.px_sources.models import PXSource

                try:
                    source_obj = PXSource.objects.get(code="staff")
                except PXSource.DoesNotExist:
                    source_obj = PXSource.objects.create(
                        code="staff", name_en="Staff", description="Complaints submitted by staff members"
                    )
                complaint.source = source_obj

            complaint.priority = "medium"  # AI will update
            complaint.severity = "medium"  # AI will update
            complaint.created_by = request.user

            # Auto-set priority to high for MOH/CHI complaints
            if complaint.source and complaint.source.name_en:
                source_name = complaint.source.name_en.lower()
                if "moh" in source_name or "chi" in source_name or "council of health" in source_name or "ministry of health" in source_name:
                    complaint.priority = "high"

            # Link to patient if auto-lookup found a match
            patient_id = request.POST.get("patient_id")
            if patient_id:
                try:
                    from uuid import UUID

                    UUID(patient_id)
                    complaint.patient_id = patient_id
                except (ValueError, AttributeError):
                    pass

            # Reference number generated by Complaint.save() (unified CMP-YYYYMM-HOSP-NNNN)
            complaint.save()

            comm_req_id = request.POST.get("comm_req")
            if comm_req_id:
                try:
                    from apps.px_sources.models import CommunicationRequest
                    cr = CommunicationRequest.objects.get(pk=comm_req_id)
                    cr.link_to_record(complaint)
                except Exception:
                    pass

            ComplaintService.post_create_hooks(complaint, request.user, request=request)

            StaffActivityService.log_from_request(
                request,
                activity_type="create",
                description=f"Created complaint {complaint.reference_number}",
                content_object=complaint,
                module="complaints",
            )

            messages.success(
                request,
                f"Complaint #{complaint.id} created successfully. AI is analyzing and classifying the complaint.",
            )
            return redirect("complaints:complaint_detail", pk=complaint.id)

        except ComplaintCategory.DoesNotExist:
            messages.error(request, "Selected category not found.")
            return redirect("complaints:complaint_create")

    # GET request - show form
    # Check for hospital parameter from URL (for pre-selection)
    initial_data = {}
    hospital_id = request.GET.get("hospital")
    if hospital_id:
        initial_data["hospital"] = hospital_id

    communication_request = None
    comm_req_id = request.GET.get("comm_req")
    if comm_req_id:
        try:
            from apps.px_sources.models import CommunicationRequest
            cr_data = CommunicationRequest.get_initial_data(comm_req_id)
            communication_request = cr_data["communication_request"]
            for key in ("hospital", "patient_name", "description"):
                if key in cr_data["initial"] and cr_data["initial"][key]:
                    initial_data[key] = cr_data["initial"][key]
        except Exception:
            pass

    form = ComplaintForm(request=request, initial=initial_data)

    context = {
        "form": form,
        "base_layout": base_layout,
        "source_user": source_user,
        "communication_request": communication_request,
    }

    return render(request, "complaints/complaint_form.html", context)


@login_required
@require_http_methods(["POST"])
def complaint_send_to(request, pk):
    """
    Unified AJAX endpoint to send complaint to either a person or department.
    """
    from django.http import JsonResponse
    from .models import ComplaintInvolvedDepartment
    from apps.notifications.services import NotificationService, get_email_header_html

    complaint = get_object_or_404(Complaint, pk=pk)
    user = request.user

    # Check permission
    if not can_manage_complaint(user, complaint):
        return JsonResponse({
            "success": False,
            "error": str(_("You don't have permission to send this complaint.")),
        }, status=403)

    recipient_type = request.POST.get("recipient_type", "department")
    note = request.POST.get("note", "").strip()

    try:
        if recipient_type == "person":
            person_id = request.POST.get("person_id")
            if not person_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a person.")),
                }, status=400)

            try:
                person = User.objects.get(id=person_id)
            except User.DoesNotExist:
                return JsonResponse({
                    "success": False,
                    "error": str(_("User not found.")),
                }, status=400)

            # Assign complaint to person
            ComplaintService.assign(complaint, person, user, request=request)

            # Send notification
            if person.email:
                NotificationService.send_email(
                    email=person.email,
                    subject=f"Complaint Assigned - {complaint.reference_number}",
                    message=f"You have been assigned to complaint #{complaint.reference_number}.",
                    html_message=f"""
                    <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
                        {get_email_header_html()}
                        <div style="padding: 20px;">
                            <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Complaint Assigned</h2>
                            <p>You have been assigned to complaint <strong>#{complaint.reference_number}</strong>.</p>
                            <p><strong>Title:</strong> {complaint.title or 'N/A'}</p>
                            {f'<p><strong>Note:</strong> {note}</p>' if note else ''}
                            <p><a href="https://{request.get_host()}/complaints/{complaint.pk}/">View Complaint</a></p>
                        </div>
                    </div>
                    """,
                    related_object=complaint,
                )

            message = f"Complaint sent to {person.get_full_name()}."

        else:  # department
            department_id = request.POST.get("department_id")
            if not department_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a department.")),
                }, status=400)

            try:
                department = Department.objects.select_related("champion", "manager").get(id=department_id, status="active")
            except Department.DoesNotExist:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Department not found.")),
                }, status=400)

            if not department.champion and not department.manager:
                return JsonResponse({
                    "success": False,
                    "error": str(_(f"Cannot send to {department.get_localized_name()}. This department has no champion or manager assigned.")),
                }, status=400)

            contact_person_id = request.POST.get("contact_person_id")
            if not contact_person_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a contact person.")),
                }, status=400)

            contact_info = department.is_valid_contact_person(contact_person_id)
            if not contact_info:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Selected person is not a role holder in this department.")),
                }, status=400)

            contact_person = contact_info["staff"]

            now = timezone.now()

            if complaint.department_id == department.pk:
                complaint.sent_to_department = True
                complaint.sent_to_department_at = now
                if not complaint.forwarded_to_dept_at:
                    complaint.forwarded_to_dept_at = now
            else:
                involved_dept, created = ComplaintInvolvedDepartment.objects.get_or_create(
                    complaint=complaint,
                    department=department,
                    defaults={
                        "role": "secondary",
                        "added_by": user,
                        "forwarded_at": now,
                        "sent": True,
                        "sent_at": now,
                    }
                )

                if not created:
                    involved_dept.forwarded_at = now
                    involved_dept.sent = True
                    involved_dept.sent_at = now
                    involved_dept.save()

                complaint.sent_to_department = True
                complaint.sent_to_department_at = complaint.sent_to_department_at or now

            complaint.explanation_requested = True
            complaint.explanation_requested_at = complaint.explanation_requested_at or now

            contact_email = contact_person.email or (contact_person.user.email if contact_person.user else None)
            if complaint.department_id == department.pk and contact_email:
                NotificationService.send_email(
                    email=contact_email,
                    subject=f"Complaint Sent to Department - {complaint.reference_number}",
                    message=f"Complaint #{complaint.reference_number} has been sent to your department ({department.name}).",
                    html_message=f"""
                    <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
                        {get_email_header_html()}
                        <div style="padding: 20px;">
                            <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Complaint Sent to Department</h2>
                            <p>Complaint <strong>#{complaint.reference_number}</strong> has been sent to your department <strong>({department.name})</strong>.</p>
                            <p><strong>Title:</strong> {complaint.title or 'N/A'}</p>
                            {f'<p><strong>Note:</strong> {note}</p>' if note else ''}
                            <p><strong>Assigned to:</strong> {contact_person.get_full_name()} ({contact_info['role_label']})</p>
                            <p><a href="https://{request.get_host()}/organizations/departments/{department.pk}/">View Department Page</a></p>
                        </div>
                    </div>
                    """,
                    related_object=complaint,
                )

            message = f"Complaint sent to {department.name} — {contact_person.get_full_name()} ({contact_info['role_label']})."

        # Set forwarded timestamp and update tracking fields if active
        now = timezone.now()
        if complaint.is_active_status and complaint.status in ("open", "in_progress"):
            if not complaint.forwarded_to_dept_at:
                complaint.forwarded_to_dept_at = now
            complaint.save(update_fields=[
                "forwarded_to_dept_at",
                "sent_to_department", "sent_to_department_at",
                "explanation_requested", "explanation_requested_at",
            ])

            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="status_change",
                message=f"Complaint sent to {recipient_type}",
                created_by=user,
            )
        else:
            if not complaint.forwarded_to_dept_at:
                complaint.forwarded_to_dept_at = now
            complaint.save(update_fields=[
                "forwarded_to_dept_at",
                "sent_to_department", "sent_to_department_at",
                "explanation_requested", "explanation_requested_at",
            ])

        return JsonResponse({
            "success": True,
            "message": message,
        })

    except Exception as e:
        logger.error(f"Error in complaint_send_to: {str(e)}")
        return JsonResponse({
            "success": False,
            "error": str(_("An error occurred while sending the complaint.")),
        }, status=500)


@login_required
@require_http_methods(["POST"])
def complaint_change_status(request, pk):
    """Change complaint status"""
    complaint = get_object_or_404(Complaint, pk=pk)

    new_status = request.POST.get("status")
    note = request.POST.get("note", "")
    resolution = request.POST.get("resolution", "")
    resolution_outcome = request.POST.get("resolution_outcome", "")
    resolution_outcome_other = request.POST.get("resolution_outcome_other", "")

    try:
        ComplaintService.change_status(
            complaint,
            new_status,
            request.user,
            request=request,
            note=note,
            resolution=resolution,
            resolution_outcome=resolution_outcome,
            resolution_outcome_other=resolution_outcome_other,
        )
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        from apps.notifications.settings_service import NotificationServiceWithSettings
        NotificationServiceWithSettings.send_complaint_status_changed(
            complaint.assigned_to.email if complaint.assigned_to and complaint.assigned_to.email else None,
            complaint,
            complaint.status,
            new_status,
        )
    except Exception:
        pass

    messages.success(request, f"Complaint status changed to {new_status}.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def update_satisfaction(request, pk):
    """Update complaint satisfaction rating (resolved/closed complaints only)."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if complaint.status not in ("resolved", "closed"):
        messages.error(request, _("Satisfaction can only be set for resolved or closed complaints."))
        return redirect("complaints:complaint_detail", pk=pk)

    if not can_manage_complaint(request.user, complaint):
        messages.error(request, _("You don't have permission to update satisfaction."))
        return redirect("complaints:complaint_detail", pk=pk)

    satisfaction = request.POST.get("satisfaction", "")
    valid_choices = ["satisfied", "neutral", "dissatisfied", "no_response"]
    if satisfaction and satisfaction not in valid_choices:
        messages.error(request, _("Invalid satisfaction value."))
        return redirect("complaints:complaint_detail", pk=pk)

    from django.utils import timezone

    complaint.satisfaction = satisfaction
    if satisfaction:
        complaint.satisfaction_set_at = timezone.now()
    else:
        complaint.satisfaction_set_at = None
    complaint.save(update_fields=["satisfaction", "satisfaction_set_at", "updated_at"])

    if satisfaction:
        messages.success(request, _("Satisfaction updated to: {}").format(complaint.get_satisfaction_display()))
    else:
        messages.success(request, _("Satisfaction cleared."))

    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def update_patient_contact_status(request, pk):
    """Update patient contact status (contacted or contacted no response)."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if not can_manage_complaint(request.user, complaint):
        messages.error(request, _("You don't have permission to update patient contact status."))
        return redirect("complaints:complaint_detail", pk=pk)

    patient_contact_status = request.POST.get("patient_contact_status", "")
    valid_choices = ["not_contacted", "contacted", "contacted_no_response"]
    if patient_contact_status and patient_contact_status not in valid_choices:
        messages.error(request, _("Invalid patient contact status."))
        return redirect("complaints:complaint_detail", pk=pk)

    from django.utils import timezone

    old_status = complaint.patient_contact_status
    complaint.patient_contact_status = patient_contact_status
    if patient_contact_status and patient_contact_status != "not_contacted":
        complaint.patient_contact_status_at = timezone.now()
        complaint.patient_contact_status_by = request.user
    else:
        complaint.patient_contact_status_at = None
        complaint.patient_contact_status_by = None
    complaint.save(update_fields=["patient_contact_status", "patient_contact_status_at", "patient_contact_status_by", "updated_at"])

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="communication",
        message=f"Patient contact status changed from {old_status} to {patient_contact_status}",
        created_by=request.user,
    )

    messages.success(request, _("Patient contact status updated to: {}").format(complaint.get_patient_contact_status_display()))

    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def toggle_escalated_ovr(request, pk):
    """Request OVR escalation or cancel pending request."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if not can_manage_complaint(request.user, complaint):
        messages.error(request, _("You don't have permission to update this complaint."))
        return redirect("complaints:complaint_detail", pk=pk)

    if complaint.status == ComplaintStatus.OVR_PENDING:
        complaint.status = ComplaintStatus.IN_PROGRESS
        complaint.is_escalated_ovr = False
        complaint.escalated_ovr_by = None
        complaint.escalated_ovr_at = None
        complaint.metadata.pop("ovr_requested_by", None)
        complaint.metadata.pop("ovr_requested_at", None)
        messages.success(request, _("OVR escalation request cancelled."))
    else:
        complaint.status = ComplaintStatus.OVR_PENDING
        complaint.is_escalated_ovr = False
        complaint.metadata["ovr_requested_by"] = str(request.user.pk)
        complaint.metadata["ovr_requested_at"] = timezone.now().isoformat()
        messages.success(request, _("OVR escalation requested. Waiting for admin approval."))
        
        # Send email notification to PX admins and management
        _send_ovr_request_notification(complaint, request.user)
    
    complaint.save(update_fields=["status", "is_escalated_ovr", "escalated_ovr_by", "escalated_ovr_at", "metadata", "updated_at"])

    return redirect("complaints:complaint_detail", pk=pk)


def _send_ovr_request_notification(complaint, requested_by):
    """Send email notification to admins when OVR escalation is requested"""
    from django.conf import settings
    from apps.accounts.models import User
    from apps.notifications.services import NotificationService, get_email_header_html
    
    try:
        admin_users = User.objects.filter(
            is_active=True,
            groups__name__in=["PX Admin", "Hospital Admin", "PX Management"],
            hospital=complaint.hospital
        ).distinct()
        
        subject = f"OVR Escalation Request - Complaint #{complaint.reference_number}"
        
        for admin in admin_users:
            if admin.email:
                message = f"""A new OVR escalation request requires your approval.

Complaint: #{complaint.reference_number}
Title: {complaint.title}
Requested by: {requested_by.get_full_name()}
Hospital: {complaint.hospital.name}

Please review and approve/reject this request in the complaints system.

URL: {settings.SITE_URL.rstrip('/')}/complaints/{complaint.pk}/
"""
                NotificationService.send_email(
                    email=admin.email,
                    subject=subject,
                    message=message,
                    html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">OVR Escalation Request</h2>
        <p style="margin: 0 0 12px 0;">A new OVR escalation request requires your approval.</p>
        <table style="width: 100%; border-collapse: collapse; margin: 0 0 12px 0;">
            <tr><td style="padding: 4px 0; color: #6b7280; width: 140px;">Complaint:</td><td style="padding: 4px 0;"><strong>#{complaint.reference_number}</strong></td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Title:</td><td style="padding: 4px 0;">{complaint.title}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Requested by:</td><td style="padding: 4px 0;">{requested_by.get_full_name()}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Hospital:</td><td style="padding: 4px 0;">{complaint.hospital.name}</td></tr>
        </table>
        <div style="text-align: center; margin: 20px 0;">
            <a href="{settings.SITE_URL.rstrip('/')}/complaints/{complaint.pk}/" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">Review Request</a>
        </div>
    </div>
</div>
""",
                )
    except Exception as e:
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f"Failed to send OVR notification: {e}")


@login_required
@require_http_methods(["POST"])
def approve_ovr_escalation(request, pk):
    """Approve OVR escalation request."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if not request.user.is_px_admin() and not request.user.is_hospital_admin():
        messages.error(request, _("You don't have permission to approve OVR escalation."))
        return redirect("complaints:complaint_detail", pk=pk)

    if complaint.status != ComplaintStatus.OVR_PENDING:
        messages.error(request, _("This complaint does not have a pending OVR request."))
        return redirect("complaints:complaint_detail", pk=pk)

    complaint.status = ComplaintStatus.IN_PROGRESS
    complaint.is_escalated_ovr = True
    complaint.escalated_ovr_by = request.user
    complaint.escalated_ovr_at = timezone.now()
    requested_by = complaint.metadata.get("ovr_requested_by", "")
    complaint.metadata.pop("ovr_requested_by", None)
    complaint.metadata.pop("ovr_requested_at", None)
    complaint.metadata["ovr_approved_by"] = str(request.user.pk)
    complaint.metadata["ovr_approved_at"] = timezone.now().isoformat()
    complaint.save(update_fields=["status", "is_escalated_ovr", "escalated_ovr_by", "escalated_ovr_at", "metadata", "updated_at"])

    messages.success(request, _("OVR escalation approved."))
    _send_ovr_decision_notification(complaint, request.user, "approved")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def reject_ovr_escalation(request, pk):
    """Reject OVR escalation request."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if not request.user.is_px_admin() and not request.user.is_hospital_admin():
        messages.error(request, _("You don't have permission to reject OVR escalation."))
        return redirect("complaints:complaint_detail", pk=pk)

    if complaint.status != ComplaintStatus.OVR_PENDING:
        messages.error(request, _("This complaint does not have a pending OVR request."))
        return redirect("complaints:complaint_detail", pk=pk)

    complaint.status = ComplaintStatus.IN_PROGRESS
    complaint.metadata.pop("ovr_requested_by", None)
    complaint.metadata.pop("ovr_requested_at", None)
    complaint.metadata["ovr_rejected_by"] = str(request.user.pk)
    complaint.metadata["ovr_rejected_at"] = timezone.now().isoformat()
    complaint.save(update_fields=["status", "metadata", "updated_at"])

    messages.success(request, _("OVR escalation request rejected."))
    _send_ovr_decision_notification(complaint, request.user, "rejected")
    return redirect("complaints:complaint_detail", pk=pk)


def _send_ovr_decision_notification(complaint, decided_by, decision):
    """Send email notification to requester when OVR is approved or rejected"""
    from django.conf import settings
    from apps.accounts.models import User
    from apps.notifications.services import NotificationService, get_email_header_html
    
    try:
        requested_by_pk = complaint.metadata.get("ovr_requested_by")
        if not requested_by_pk:
            return
            
        requested_by_user = User.objects.filter(pk=requested_by_pk).first()
        if not requested_by_user or not requested_by_user.email:
            return
        
        decision_text = "approved" if decision == "approved" else "rejected"
        subject = f"OVR Escalation {decision_text.title()} - Complaint #{complaint.reference_number}"
        
        message = f"""Your OVR escalation request for complaint #{complaint.reference_number} has been {decision_text}.

Complaint: #{complaint.reference_number}
Title: {complaint.title}
Decision: {decision_text.title()} by {decided_by.get_full_name()}

{"The complaint is now escalated as OVR." if decision == "approved" else "Please contact the admin for more information."}

URL: {settings.SITE_URL.rstrip('/')}/complaints/{complaint.pk}/
"""
        NotificationService.send_email(
            email=requested_by_user.email,
            subject=subject,
            message=message,
            html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">OVR Escalation {decision_text.title()}</h2>
        <p style="margin: 0 0 12px 0;">Your OVR escalation request for complaint <strong>#{complaint.reference_number}</strong> has been <strong>{decision_text}</strong>.</p>
        <table style="width: 100%; border-collapse: collapse; margin: 0 0 12px 0;">
            <tr><td style="padding: 4px 0; color: #6b7280; width: 120px;">Title:</td><td style="padding: 4px 0;">{complaint.title}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Decision:</td><td style="padding: 4px 0;">{decision_text.title()} by {decided_by.get_full_name()}</td></tr>
        </table>
        <p style="margin: 0 0 12px 0;">{"The complaint is now escalated as OVR." if decision == "approved" else "Please contact the admin for more information."}</p>
        <div style="text-align: center; margin: 20px 0;">
            <a href="{settings.SITE_URL.rstrip('/')}/complaints/{complaint.pk}/" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">View Complaint</a>
        </div>
    </div>
</div>
""",
        )
    except Exception as e:
        import logging
        logger = logging.getLogger(__name__)
        logger.error(f"Failed to send OVR decision notification: {e}")


@login_required
@require_http_methods(["POST"])
def reject_ovr_escalation(request, pk):
    """Reject OVR escalation request."""
    complaint = get_object_or_404(Complaint, pk=pk)

    if not request.user.is_px_admin() and not request.user.is_hospital_admin():
        messages.error(request, _("You don't have permission to reject OVR escalation."))
        return redirect("complaints:complaint_detail", pk=pk)

    if complaint.status != ComplaintStatus.OVR_PENDING:
        messages.error(request, _("This complaint does not have a pending OVR request."))
        return redirect("complaints:complaint_detail", pk=pk)

    complaint.status = ComplaintStatus.IN_PROGRESS
    complaint.metadata.pop("ovr_requested_by", None)
    complaint.metadata.pop("ovr_requested_at", None)
    complaint.metadata["ovr_rejected_by"] = str(request.user.pk)
    complaint.metadata["ovr_rejected_at"] = timezone.now().isoformat()
    complaint.save(update_fields=["status", "metadata", "updated_at"])

    messages.success(request, _("OVR escalation request rejected."))
    _send_ovr_decision_notification(complaint, request.user, "rejected")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def complaint_reopen(request, pk):
    """Reopen a resolved or closed complaint"""
    complaint = get_object_or_404(Complaint, pk=pk)

    user = request.user
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or complaint.assigned_to == user
        or (user.is_department_manager() and user.department and user.department == complaint.department)
    ):
        messages.error(request, "You don't have permission to reopen this complaint.")
        return redirect("complaints:complaint_detail", pk=pk)

    note = request.POST.get("note", "")

    if complaint.status not in ("resolved", "closed"):
        messages.error(request, "Only resolved or closed complaints can be reopened.")
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        ComplaintService.reopen(complaint, request.user, request=request, note=note)
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        from apps.notifications.settings_service import NotificationServiceWithSettings
        NotificationServiceWithSettings.send_complaint_status_changed(
            complaint.assigned_to.email if complaint.assigned_to and complaint.assigned_to.email else None,
            complaint,
            complaint.status,
            "in_progress",
        )
    except Exception:
        pass

    messages.success(request, "Complaint reopened successfully.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def update_explanation_delay_reason(request, pk):
    complaint = get_object_or_404(Complaint, pk=pk)

    if not can_manage_complaint(request.user, complaint):
        messages.error(request, "You don't have permission to update this complaint.")
        return redirect("complaints:complaint_detail", pk=pk)

    reason = request.POST.get("explanation_delay_reason", "")
    old_reason = complaint.explanation_delay_reason
    complaint.explanation_delay_reason = reason
    complaint.save(update_fields=["explanation_delay_reason", "updated_at"])

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="note",
        message=f"Explanation delay reason updated: {reason}" if reason else "Explanation delay reason cleared",
        created_by=request.user,
    )

    AuditService.log_event(
        event_type="update",
        description="Explanation delay reason updated",
        user=request.user,
        content_object=complaint,
        metadata={"old_value": old_reason, "new_value": reason},
    )

    messages.success(request, "Explanation delay reason updated.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def update_delay_reason_closure(request, pk):
    complaint = get_object_or_404(Complaint, pk=pk)

    if not can_manage_complaint(request.user, complaint):
        messages.error(request, "You don't have permission to update this complaint.")
        return redirect("complaints:complaint_detail", pk=pk)

    if complaint.status in ("closed", "resolved"):
        messages.error(request, "Cannot update delay reason for closed/resolved complaints.")
        return redirect("complaints:complaint_detail", pk=pk)

    from django.utils import timezone

    hours_since_creation = (timezone.now() - complaint.created_at).total_seconds() / 3600
    if not complaint.is_overdue and hours_since_creation < 72:
        messages.error(request, "Delay reason can only be set when complaint is overdue or past 72 hours.")
        return redirect("complaints:complaint_detail", pk=pk)

    reason = request.POST.get("delay_reason_closure", "")
    from .models import DelayReasonChoices
    valid_reasons = [choice[0] for choice in DelayReasonChoices.choices]
    if reason and reason not in valid_reasons:
        messages.error(request, "Invalid delay reason.")
        return redirect("complaints:complaint_detail", pk=pk)
    old_reason = complaint.delay_reason_closure
    complaint.delay_reason_closure = reason
    complaint.save(update_fields=["delay_reason_closure", "updated_at"])

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="note",
        message=f"Closure delay reason updated: {reason}" if reason else "Closure delay reason cleared",
        created_by=request.user,
    )

    AuditService.log_event(
        event_type="update",
        description="Closure delay reason updated",
        user=request.user,
        content_object=complaint,
        metadata={"old_value": old_reason, "new_value": reason},
    )

    messages.success(request, "Closure delay reason updated.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def complaint_add_note(request, pk):
    """Add note to complaint"""
    complaint = get_object_or_404(Complaint, pk=pk)
    note = request.POST.get("note")

    try:
        ComplaintService.add_note(complaint, note, request.user, request=request)
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    messages.success(request, "Note added successfully.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def complaint_change_department(request, pk):
    """Change complaint department"""
    complaint = get_object_or_404(Complaint, pk=pk)

    department_id = request.POST.get("department_id")
    if not department_id:
        messages.error(request, "Please select a department.")
        return redirect("complaints:complaint_detail", pk=pk)

    try:
        department = Department.objects.get(id=department_id)
        ComplaintService.change_department(complaint, department, request.user, request=request)
    except Department.DoesNotExist:
        messages.error(request, "Department not found.")
        return redirect("complaints:complaint_detail", pk=pk)
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    messages.success(request, f"Department changed to {department.name}.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def complaint_escalate(request, pk):
    """Escalate complaint to selected staff (default is staff's manager) - Admin and Dept Manager only"""
    complaint = get_object_or_404(Complaint, pk=pk)

    # Check if complaint is in active status
    if not complaint.is_active_status:
        messages.error(
            request,
            f"Cannot escalate complaint with status '{complaint.get_status_display()}'. Complaint must be Open, In Progress, or Partially Resolved.",
        )
        return redirect("complaints:complaint_detail", pk=pk)

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to escalate complaints.")
        return redirect("complaints:complaint_detail", pk=pk)

    reason = request.POST.get("reason", "")
    escalate_to_id = request.POST.get("escalate_to", "")

    escalate_to_staff = None
    escalate_to_user = None
    escalate_to_email = None

    if escalate_to_id:
        try:
            escalate_to_staff = Staff.objects.get(id=escalate_to_id)
            if escalate_to_staff.user and escalate_to_staff.user.is_active:
                escalate_to_user = escalate_to_staff.user
                escalate_to_email = escalate_to_staff.user.email
            elif escalate_to_staff.email:
                escalate_to_email = escalate_to_staff.email
        except Staff.DoesNotExist:
            pass

    if not escalate_to_staff:
        messages.error(request, _("Please select a valid person to escalate to."))
        return redirect("complaints:complaint_detail", pk=pk)

    escalate_to_name = escalate_to_staff.get_full_name()

    # Mark as escalated and assign to selected user
    complaint.escalated_at = timezone.now()
    if escalate_to_user:
        complaint.assigned_to = escalate_to_user
    complaint.save(update_fields=["escalated_at", "assigned_to"])

    # Create update with escalation details
    escalation_message = f"Complaint escalated. Reason: {reason}"
    escalation_message += f" Escalated to: {escalate_to_name}"

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="escalation",
        message=escalation_message,
        created_by=request.user,
        metadata={
            "reason": reason,
            "escalated_to_staff_id": str(escalate_to_staff.id),
            "escalated_to_user_id": str(escalate_to_user.id) if escalate_to_user else None,
            "escalated_to_user_name": escalate_to_name,
        },
    )

    # Log audit
    AuditService.log_event(
        event_type="escalation",
        description=f"Complaint escalated to {escalate_to_name}",
        user=request.user,
        content_object=complaint,
        metadata={
            "reason": reason,
            "escalated_to_staff_id": str(escalate_to_staff.id),
            "escalated_to_user_id": str(escalate_to_user.id) if escalate_to_user else None,
            "escalated_to_user_name": escalate_to_name,
        },
    )

    # Send notification email
    if escalate_to_email:
        from apps.notifications.services import NotificationService, get_email_header_html

        email_subject = request.POST.get("email_subject", f"Complaint Escalated - {complaint.reference_number}")
        email_body = request.POST.get("email_body", "")

        department_url = f"https://{request.get_host()}/organizations/departments/{complaint.department.pk}/" if complaint.department else ""
        html_message = f"""
        <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
            {get_email_header_html()}
            <div style="padding: 20px;">
                <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Complaint Escalated</h2>
                <p>Dear Manager,</p>
                <p>This complaint has been escalated and requires your immediate attention.</p>
                <p><strong>Reference:</strong> {complaint.reference_number}<br>
                <strong>Title:</strong> {complaint.title or 'N/A'}<br>
                <strong>Severity:</strong> {complaint.get_severity_display()}<br>
                <strong>Priority:</strong> {complaint.get_priority_display()}<br>
                <strong>Status:</strong> {complaint.get_status_display()}</p>
                <p>Please review and take appropriate action.</p>
                <p style="margin-top: 16px;">
                    <a href="{department_url}" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">View Department</a>
                </p>
            </div>
        </div>
        """

        try:
            NotificationService.send_email(
                email=escalate_to_email,
                subject=email_subject,
                message=email_body,
                html_message=html_message,
                related_object=complaint,
                metadata={
                    "notification_type": "complaint_escalated",
                    "escalated_by": str(request.user.id),
                    "reason": reason,
                },
            )
        except Exception as e:
            logger.error(f"Failed to send escalation notification: {e}")

    messages.success(
        request,
        f"Complaint escalated successfully to {escalate_to_name}.",
    )
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def complaint_activate(request, pk):
    """Activate complaint and assign to current user."""
    complaint = get_object_or_404(Complaint, pk=pk)

    try:
        ComplaintService.activate(complaint, request.user, request=request)
    except ComplaintServiceError as e:
        messages.error(request, str(e))
        return redirect("complaints:complaint_detail", pk=pk)

    messages.success(request, "Complaint activated and assigned to you successfully.")
    return redirect("complaints:complaint_detail", pk=pk)


@login_required
def complaint_export_csv(request):
    """Export complaints to CSV"""
    from apps.complaints.utils import export_complaints_csv

    # Get filtered queryset (reuse list view logic)
    queryset = Complaint.objects.select_related(
        "patient", "hospital", "department", "staff", "assigned_to", "resolved_by", "closed_by"
    )

    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.is_department_manager() and user.department:
        queryset = queryset.filter(department=user.department)
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply filters from request
    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)

    priority_filter = request.GET.get("priority")
    if priority_filter:
        queryset = queryset.filter(priority=priority_filter)

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

    department_filter = request.GET.get("department")
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)

    overdue_filter = request.GET.get("is_overdue")
    if overdue_filter == "true":
        queryset = queryset.filter(is_overdue=True)

    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)
        )

    return export_complaints_csv(queryset, request.GET.dict())


@login_required
def complaint_export_excel(request):
    """Export complaints to Excel"""
    from apps.complaints.utils import export_complaints_excel

    # Get filtered queryset (same as CSV)
    queryset = Complaint.objects.select_related(
        "patient", "hospital", "department", "staff", "assigned_to", "resolved_by", "closed_by"
    )

    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.is_department_manager() and user.department:
        queryset = queryset.filter(department=user.department)
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply filters from request
    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)

    priority_filter = request.GET.get("priority")
    if priority_filter:
        queryset = queryset.filter(priority=priority_filter)

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

    department_filter = request.GET.get("department")
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)

    overdue_filter = request.GET.get("is_overdue")
    if overdue_filter == "true":
        queryset = queryset.filter(is_overdue=True)

    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)
        )

    return export_complaints_excel(queryset, request.GET.dict())


@login_required
def complaint_export_historical_excel(request):
    """Export complaints to historical Excel format with Arabic headers."""
    from apps.complaints.utils import export_historical_excel

    # Get filtered queryset
    queryset = Complaint.objects.select_related(
        "patient",
        "hospital",
        "department",
        "staff",
        "assigned_to",
        "resolved_by",
        "closed_by",
        "created_by",
        "source",
        "domain",
        "category",
        "subcategory_obj",
        "classification_obj",
    )

    # Apply RBAC filters
    user = request.user
    if user.is_px_admin():
        pass
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.is_department_manager() and user.department:
        queryset = queryset.filter(department=user.department)
    elif user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    else:
        queryset = queryset.none()

    # Apply date range filter
    date_start = request.GET.get("date_start")
    date_end = request.GET.get("date_end")

    if date_start:
        from datetime import datetime

        try:
            date_start_dt = datetime.strptime(date_start, "%Y-%m-%d")
            queryset = queryset.filter(created_at__date__gte=date_start_dt)
        except ValueError:
            pass

    if date_end:
        from datetime import datetime

        try:
            date_end_dt = datetime.strptime(date_end, "%Y-%m-%d")
            queryset = queryset.filter(created_at__date__lte=date_end_dt)
        except ValueError:
            pass

    # Apply other filters from request
    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_id=hospital_filter)

    department_filter = request.GET.get("department")
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)

    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)
        )

    return export_historical_excel(queryset, date_start, date_end)


@login_required
def complaint_export_monthly_calculations(request):
    """
    Step 1 — Export monthly calculations report to Excel.
    """
    from apps.complaints.utils import export_monthly_calculations
    from django.core.exceptions import PermissionDenied

    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        raise PermissionDenied("Only PX Admins and Hospital Admins can export.")

    year = request.GET.get("year")
    month = request.GET.get("month")
    if not year or not month:
        from django.contrib import messages

        messages.error(request, "Year and month are required for monthly calculations export.")
        return redirect("complaints:complaint_list")

    queryset = Complaint.objects.filter(
        created_at__year=int(year),
        created_at__month=int(month),
    )

    if request.user.is_hospital_admin() and request.user.hospital:
        queryset = queryset.filter(hospital=request.user.hospital)
    elif request.user.is_px_admin() and request.tenant_hospital:
        queryset = queryset.filter(hospital=request.tenant_hospital)

    queryset = queryset.select_related(
        "hospital",
        "department",
        "assigned_to",
        "resolved_by",
        "closed_by",
        "created_by",
        "source",
    ).prefetch_related("involved_departments__department")

    return export_monthly_calculations(queryset, int(year), int(month))


@login_required
def complaint_export_quarterly_calculations(request):
    """
    Step 2 — Export quarterly calculations report to Excel.
    """
    from apps.complaints.utils import export_quarterly_calculations
    from django.core.exceptions import PermissionDenied

    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        raise PermissionDenied("Only PX Admins and Hospital Admins can export.")

    year = request.GET.get("year")
    quarter = request.GET.get("quarter")
    if not year or not quarter:
        from django.contrib import messages

        messages.error(request, "Year and quarter are required.")
        return redirect("complaints:complaint_list")

    year, quarter = int(year), int(quarter)
    quarter_months = {1: (1, 3), 2: (4, 6), 3: (7, 9), 4: (10, 12)}
    start_month, end_month = quarter_months[quarter]

    queryset = Complaint.objects.filter(
        created_at__year=year,
        created_at__month__gte=start_month,
        created_at__month__lte=end_month,
    )

    if request.user.is_hospital_admin() and request.user.hospital:
        queryset = queryset.filter(hospital=request.user.hospital)
    elif request.user.is_px_admin() and request.tenant_hospital:
        queryset = queryset.filter(hospital=request.tenant_hospital)

    return export_quarterly_calculations(queryset, year, quarter)


@login_required
def complaint_export_yearly_calculations(request):
    """
    Export yearly calculations report to Excel.
    """
    from apps.complaints.utils import export_yearly_calculations
    from django.core.exceptions import PermissionDenied

    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        raise PermissionDenied("Only PX Admins and Hospital Admins can export.")

    year = request.GET.get("year")
    if not year:
        from django.contrib import messages

        messages.error(request, "Year is required.")
        return redirect("complaints:complaint_list")

    year = int(year)
    queryset = Complaint.objects.filter(created_at__year=year)

    if request.user.is_hospital_admin() and request.user.hospital:
        queryset = queryset.filter(hospital=request.user.hospital)
    elif request.user.is_px_admin() and request.tenant_hospital:
        queryset = queryset.filter(hospital=request.tenant_hospital)

    return export_yearly_calculations(queryset, year)


@hospital_admin_required
@require_http_methods(["POST"])
def complaint_bulk_assign(request):
    """Bulk assign complaints - Admin only"""
    from apps.complaints.utils import bulk_assign_complaints
    import json

    try:
        data = json.loads(request.body)
        complaint_ids = data.get("complaint_ids", [])
        user_id = data.get("user_id")

        if not complaint_ids or not user_id:
            return JsonResponse({"success": False, "error": "Missing required fields"}, status=400)

        result = bulk_assign_complaints(complaint_ids, user_id, request.user)

        if result["success"]:
            messages.success(request, f"Successfully assigned {result['success_count']} complaints.")

        return JsonResponse(result)

    except json.JSONDecodeError:
        return JsonResponse({"success": False, "error": "Invalid JSON"}, status=400)
    except Exception as e:
        return JsonResponse({"success": False, "error": str(e)}, status=500)


@hospital_admin_required
@require_http_methods(["POST"])
def complaint_bulk_status(request):
    """Bulk change complaint status - Admin only"""
    from apps.complaints.utils import bulk_change_status
    import json

    try:
        data = json.loads(request.body)
        complaint_ids = data.get("complaint_ids", [])
        new_status = data.get("status")
        note = data.get("note", "")

        if not complaint_ids or not new_status:
            return JsonResponse({"success": False, "error": "Missing required fields"}, status=400)

        result = bulk_change_status(complaint_ids, new_status, request.user, note)

        if result["success"]:
            messages.success(request, f"Successfully updated {result['success_count']} complaints.")

        return JsonResponse(result)

    except json.JSONDecodeError:
        return JsonResponse({"success": False, "error": "Invalid JSON"}, status=400)
    except Exception as e:
        return JsonResponse({"success": False, "error": str(e)}, status=500)


@hospital_admin_required
@require_http_methods(["POST"])
def complaint_bulk_escalate(request):
    """Bulk escalate complaints - Admin only"""
    from apps.complaints.utils import bulk_escalate_complaints
    import json

    try:
        data = json.loads(request.body)
        complaint_ids = data.get("complaint_ids", [])
        reason = data.get("reason", "")

        if not complaint_ids:
            return JsonResponse({"success": False, "error": "No complaints selected"}, status=400)

        result = bulk_escalate_complaints(complaint_ids, request.user, reason)

        if result["success"]:
            messages.success(request, f"Successfully escalated {result['success_count']} complaints.")

        return JsonResponse(result)

    except json.JSONDecodeError:
        return JsonResponse({"success": False, "error": "Invalid JSON"}, status=400)
    except Exception as e:
        return JsonResponse({"success": False, "error": str(e)}, status=500)


# ============================================================================
# INQUIRIES VIEWS
# ============================================================================


@login_required
def inquiry_list(request):
    """
    Inquiries list view with filters and pagination.
    """
    from .models import Inquiry

    # Base queryset with optimizations
    queryset = Inquiry.objects.select_related("patient", "hospital", "department", "assigned_to", "responded_by")

    # Apply RBAC filters
    user = request.user
    # Get selected hospital for PX Admins (from middleware)
    selected_hospital = getattr(request, "tenant_hospital", None)

    if user.is_px_admin():
        if selected_hospital:
            queryset = queryset.filter(hospital=selected_hospital)
    elif user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)
    elif user.is_department_manager() and user.department:
        queryset = queryset.filter(
            Q(department=user.department) | Q(outgoing_department=user.department)
        )
    elif user.is_champion() and user.department:
        queryset = queryset.filter(
            Q(department=user.department) | Q(outgoing_department=user.department)
        )
    elif user.is_source_user():
        queryset = queryset.filter(created_by=user)
    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)

    department_filter = request.GET.get("department")
    if department_filter:
        queryset = queryset.filter(department_id=department_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)
            | Q(contact_email__icontains=search_query)
        )

    # 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
    total_count = queryset.count()
    resolved_count = queryset.filter(status="resolved").count()

    stats = {
        "total": total_count,
        "open": queryset.filter(status="open").count(),
        "in_progress": queryset.filter(status="in_progress").count(),
        "resolved": resolved_count,
        "resolved_percentage": (resolved_count / total_count * 100) if total_count > 0 else 0,
        "overdue": queryset.filter(is_overdue=True).count(),
    }

    # Get departments for filter
    departments = Department.objects.filter(status="active")
    if not user.is_px_admin() and user.hospital:
        departments = departments.filter(hospital=user.hospital)

    context = {
        "page_obj": page_obj,
        "inquiries": page_obj,
        "stats": stats,
        "departments": departments,
        "filters": request.GET,
    }

    return render(request, "complaints/inquiry_list.html", context)


@login_required
def inquiry_detail(request, pk):
    """
    Inquiry detail view with timeline and attachments.

    Features:
    - Full inquiry details
    - Timeline of all updates
    - Attachments management
    - Workflow actions (assign, status change, add note, respond)
    """
    from apps.px_sources.models import SourceUser

    source_user = SourceUser.objects.filter(user=request.user).first()
    base_layout = "layouts/source_user_base.html" if source_user else "layouts/base.html"

    inquiry = get_object_or_404(
        Inquiry.objects.select_related(
            "patient", "hospital", "department",
            "assigned_to", "responded_by",
            "outgoing_department", "department_responded_by",
            "taxonomy_domain", "taxonomy_category", "taxonomy_subcategory", "taxonomy_classification",
        ).prefetch_related("attachments", "updates__created_by"),
        pk=pk,
    )

    # Check access
    user = request.user
    if not user.is_px_admin():
        if user.is_hospital_admin() and inquiry.hospital != user.hospital:
            messages.error(request, "You don't have permission to view this inquiry.")
            return redirect("inquiries:inquiry_list")
        elif (
            user.is_champion() or user.is_department_manager()
        ) and (
            (inquiry.department and inquiry.department == user.department)
            or (inquiry.outgoing_department and inquiry.outgoing_department == user.department)
        ):
            pass
        elif (
            user.is_champion() or user.is_department_manager()
        ):
            messages.error(request, "You don't have permission to view this inquiry.")
            return redirect("inquiries:inquiry_list")
        elif user.hospital and inquiry.hospital != user.hospital:
            messages.error(request, "You don't have permission to view this inquiry.")
            return redirect("inquiries:inquiry_list")

    # Get timeline (updates)
    timeline = inquiry.updates.all().order_by("-created_at")
    stage_timeline = _build_inquiry_stage_timeline(inquiry)

    # Get attachments
    attachments = inquiry.attachments.all().order_by("-created_at")

    # Get assignable users
    from apps.core.utils import get_assignable_users
    assignable_users = get_assignable_users(inquiry.hospital)

    # Get departments for the inquiry's hospital
    hospital_departments = []
    if inquiry.hospital:
        hospital_departments = Department.objects.filter(hospital=inquiry.hospital, status="active").order_by("name")

    # Status choices for the form
    status_choices = [
        ("open", "Open"),
        ("in_progress", "In Progress"),
        ("contacted", "Contacted"),
        ("contacted_no_response", "Contacted, No Response"),
        ("resolved", "Resolved"),
        ("closed", "Closed"),
    ]

    from apps.rca.models import RootCauseAnalysis as RCA
    from django.contrib.contenttypes.models import ContentType as CT

    inquiry_ct = CT.objects.get_for_model(Inquiry)
    linked_rcas = RCA.objects.filter(content_type=inquiry_ct, object_id=inquiry.pk, is_deleted=False).select_related(
        "assigned_to", "created_by"
    )

    escalation_targets = []

    if inquiry.hospital:
        from django.db.models import Q

        escalation_targets_qs = (
            Staff.objects.filter(
                hospital=inquiry.hospital, status="active", user__isnull=False, user__is_active=True
            )
            .filter(Q(user__groups__name__in=["Hospital Admin", "Department Manager"]) | Q(direct_reports__isnull=False))
            .select_related("user", "department", "report_to")
            .distinct()
            .order_by("first_name", "last_name")
        )

        for staff in escalation_targets_qs:
            escalation_targets.append(
                {
                    "staff": staff,
                    "has_user": True,
                    "user_id": str(staff.user.id),
                    "is_manager": staff.direct_reports.exists(),
                    "is_line_manager": False,
                    "group": "managers",
                }
            )

        escalation_targets.sort(key=lambda x: (not x["is_manager"], x["staff"].get_full_name()))

        if inquiry.department:
            dept = Department.objects.filter(pk=inquiry.department_id).first()
            if dept:
                dept_role_holders = []
                for holder in dept.get_role_holders():
                    if holder["staff"].user and holder["staff"].user.is_active:
                        dept_role_holders.append({
                            "staff": holder["staff"],
                            "has_user": True,
                            "user_id": str(holder["staff"].user.id),
                            "is_manager": False,
                            "is_line_manager": False,
                            "role_label": holder["role_label"],
                            "group": "department_roles",
                        })
                if dept_role_holders:
                    escalation_targets = dept_role_holders + escalation_targets

    context = {
        "inquiry": inquiry,
        "timeline": timeline,
        "stage_timeline": stage_timeline,
        "attachments": attachments,
        "assignable_users": assignable_users,
        "hospital_departments": hospital_departments,
        "status_choices": status_choices,
        "can_edit": user.is_px_admin() or user.is_hospital_admin(),
        "can_respond": (
            user.is_px_admin()
            or user.is_hospital_admin()
            or inquiry.assigned_to == user
            or (
                user.is_champion()
                and user.department
                and user.department in [inquiry.department, inquiry.outgoing_department]
            )
        ),
        "can_review_dept_response": user.is_px_admin() or user.is_hospital_admin(),
        "can_send_reminder": user.is_px_admin() or user.is_hospital_admin(),
        "base_layout": base_layout,
        "source_user": source_user,
        "linked_rcas": linked_rcas,
        "escalation_targets": escalation_targets,
        "escalation_email_subject": f"Inquiry Escalated - {inquiry.reference_number} - {inquiry.subject or 'N/A'}",
        "escalation_email_body": (
            f"Dear Manager,\n\n"
            f"This inquiry has been escalated and requires your immediate attention.\n\n"
            f"Reference: {inquiry.reference_number}\n"
            f"Subject: {inquiry.subject or 'N/A'}\n"
            f"Priority: {inquiry.get_priority_display()}\n"
            f"Status: {inquiry.get_status_display()}\n"
            f"Department: {inquiry.department.get_localized_name() if inquiry.department else 'N/A'}\n\n"
            f"Please review and take appropriate action.\n\n"
            f"View: https://{request.get_host()}/inquiries/{inquiry.pk}/"
        ),
    }

    from django.contrib.contenttypes.models import ContentType
    inquiry_ct = ContentType.objects.get_for_model(inquiry)
    context["content_type_id"] = inquiry_ct.pk
    context["object_id"] = inquiry.pk
    context["notes"] = inquiry.notes.select_related("created_by").all()
    context["notes_count"] = context["notes"].count()

    return render(request, "complaints/inquiry_detail.html", context)


@login_required
@require_http_methods(["POST"])
def inquiry_send_to_staff(request, pk):
    """Send inquiry explanation request to a specific staff member via token link."""
    from .models import InquiryExplanation
    from apps.organizations.models import Staff
    from apps.notifications.services import NotificationService
    from django.contrib.sites.shortcuts import get_current_site
    import secrets

    inquiry = get_object_or_404(Inquiry, pk=pk)

    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        messages.error(request, _("You don't have permission to perform this action."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    staff_id = request.POST.get("staff_id")
    request_message = request.POST.get("request_message", "").strip()

    if not staff_id:
        messages.error(request, _("Please select a staff member."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    staff = get_object_or_404(Staff, pk=staff_id)

    token = secrets.token_urlsafe(32)
    explanation = InquiryExplanation.objects.create(
        inquiry=inquiry,
        staff=staff,
        token=token,
        requested_by=request.user,
        request_message=request_message,
        email_sent_at=timezone.now(),
    )

    from apps.complaints.models import InquirySLAConfig
    sla_config = InquirySLAConfig.get_active_config()
    if sla_config and sla_config.dept_response_sla_hours:
        explanation.sla_due_at = timezone.now() + timezone.timedelta(hours=sla_config.dept_response_sla_hours)
        explanation.save(update_fields=["sla_due_at"])

    site = get_current_site(request)
    explanation_url = f"https://{site.domain}/inquiries/{inquiry.id}/explain/{token}/"

    if staff.email:
        from django.template.loader import render_to_string

        email_context = {
            "staff_name": f"{staff.first_name} {staff.last_name}",
            "inquiry_subject": inquiry.subject,
            "inquiry_reference": inquiry.reference_number or str(inquiry.id),
            "inquiry_message": inquiry.message[:500],
            "request_message": request_message,
            "explanation_url": explanation_url,
            "site_name": site.name,
        }
        html_message = render_to_string("emails/inquiry_explanation_request.html", email_context)
        message = (
            f"Dear {staff.first_name} {staff.last_name},\n\n"
            f"You have been requested to provide a response regarding inquiry #{inquiry.reference_number or inquiry.id}.\n\n"
            f"Subject: {inquiry.subject}\n\n"
            f"Please submit your response using the link below:\n{explanation_url}\n"
        )
        NotificationService.send_email(
            email=staff.email,
            subject=f"Inquiry Response Requested - #{inquiry.reference_number or inquiry.id}",
            message=message,
            html_message=html_message,
            related_object=explanation,
            metadata={"notification_type": "inquiry_explanation_request"},
        )

    messages.success(request, _(f"Response request sent to {staff.first_name} {staff.last_name}"))
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["GET", "POST"])
def inquiry_create(request):
    """Create new inquiry"""
    from .models import Inquiry
    from .forms import InquiryForm
    from apps.px_sources.models import SourceUser

    # Determine base layout based on user type
    source_user = SourceUser.objects.filter(user=request.user).first()
    base_layout = "layouts/source_user_base.html" if source_user else "layouts/base.html"
    communication_request = None

    if request.method == "POST":
        form = InquiryForm(request.POST, request=request)

        if form.is_valid():
            try:
                inquiry = form.save(commit=False)

                inquiry.category = request.POST.get("category")
                inquiry.created_by = request.user

                is_outgoing = request.POST.get("is_outgoing") in ("true", "True", "on", "1")
                inquiry.is_outgoing = is_outgoing

                if is_outgoing:
                    outgoing_dept_id = request.POST.get("outgoing_department")
                    if outgoing_dept_id:
                        from apps.organizations.models import Department
                        try:
                            inquiry.outgoing_department = Department.objects.get(id=outgoing_dept_id)
                        except Department.DoesNotExist:
                            pass

                # Link to patient if auto-lookup found a match
                patient_id = request.POST.get("patient_id")
                if patient_id:
                    try:
                        from uuid import UUID

                        UUID(patient_id)
                        inquiry.patient_id = patient_id
                    except (ValueError, AttributeError):
                        pass

                inquiry.save()

                comm_req_id = request.POST.get("comm_req")
                if comm_req_id:
                    try:
                        from apps.px_sources.models import CommunicationRequest as CR
                        cr = CR.objects.get(pk=comm_req_id)
                        cr.link_to_record(inquiry)
                    except Exception:
                        pass

                from apps.complaints.tasks import analyze_inquiry_with_ai, notify_staff_new_item

                analyze_inquiry_with_ai.delay(str(inquiry.id))
                notify_staff_new_item.delay("inquiry", str(inquiry.id))

                InquiryUpdate.objects.create(
                    inquiry=inquiry,
                    update_type="note",
                    message="Inquiry created.",
                    created_by=request.user,
                )

                AuditService.log_event(
                    event_type="inquiry_created",
                    description=f"Inquiry created: {inquiry.subject}",
                    user=request.user,
                    content_object=inquiry,
                    metadata={"category": inquiry.category},
                )

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

            except Exception as e:
                messages.error(request, f"Error creating inquiry: {str(e)}")
        else:
            messages.error(request, f"Please correct the errors: {form.errors}")
    else:
        # GET request - show form
        # Check for hospital parameter from URL (for pre-selection)
        initial_data = {}
        hospital_id = request.GET.get("hospital")
        if hospital_id:
            initial_data["hospital"] = hospital_id

        comm_req_id = request.GET.get("comm_req")
        if comm_req_id:
            try:
                from apps.px_sources.models import CommunicationRequest
                cr_data = CommunicationRequest.get_initial_data(comm_req_id)
                communication_request = cr_data["communication_request"]
                for key in ("hospital", "contact_name", "contact_phone", "message"):
                    if key in cr_data["initial"] and cr_data["initial"][key]:
                        initial_data[key] = cr_data["initial"][key]
            except Exception:
                pass

        form = InquiryForm(request=request, initial=initial_data)

    context = {
        "form": form,
        "base_layout": base_layout,
        "source_user": source_user,
        "communication_request": communication_request,
    }

    return render(request, "complaints/inquiry_form.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def inquiry_edit(request, pk):
    """Edit existing inquiry"""
    from .forms import InquiryForm

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, _("You don't have permission to edit this inquiry."))
        return redirect("inquiries:inquiry_detail", pk=inquiry.pk)

    if inquiry.status == "closed":
        messages.error(request, _("Closed inquiries cannot be edited."))
        return redirect("inquiries:inquiry_detail", pk=inquiry.pk)

    if request.method == "POST":
        form = InquiryForm(request.POST, request=request, instance=inquiry)

        if form.is_valid():
            try:
                inquiry = form.save(commit=False)

                inquiry.category = request.POST.get("category", inquiry.category)

                is_outgoing = request.POST.get("is_outgoing") in ("true", "True", "on", "1")
                inquiry.is_outgoing = is_outgoing

                if is_outgoing:
                    outgoing_dept_id = request.POST.get("outgoing_department")
                    if outgoing_dept_id:
                        try:
                            inquiry.outgoing_department = Department.objects.get(id=outgoing_dept_id)
                        except Department.DoesNotExist:
                            pass
                else:
                    inquiry.outgoing_department = None

                inquiry.save()

                InquiryUpdate.objects.create(
                    inquiry=inquiry,
                    update_type="note",
                    message="Inquiry updated.",
                    created_by=request.user,
                )

                AuditService.log_event(
                    event_type="inquiry_updated",
                    description=f"Inquiry updated: {inquiry.subject}",
                    user=request.user,
                    content_object=inquiry,
                )

                messages.success(request, _("Inquiry updated successfully."))
                return redirect("inquiries:inquiry_detail", pk=inquiry.pk)

            except Exception as e:
                messages.error(request, f"Error updating inquiry: {str(e)}")
        else:
            messages.error(request, f"Please correct the errors: {form.errors}")
    else:
        initial_data = {}
        form = InquiryForm(request=request, instance=inquiry, initial=initial_data)

    context = {
        "form": form,
        "inquiry": inquiry,
    }

    return render(request, "complaints/inquiry_form.html", context)


@login_required
@require_http_methods(["POST"])
def inquiry_activate(request, pk):
    """Activate inquiry by assigning it to current logged-in user"""
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to activate inquiries.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    # Check if already assigned to current user
    if inquiry.assigned_to == user:
        messages.info(request, "This inquiry is already assigned to you.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    old_assignee = inquiry.assigned_to
    old_status = inquiry.status

    # Update inquiry
    inquiry.assigned_to = user
    inquiry.assigned_at = timezone.now()

    # Only change status to in_progress if it's currently open
    if inquiry.status == "open":
        inquiry.status = "in_progress"
        inquiry.activated_at = timezone.now()
        inquiry.save(update_fields=["assigned_to", "assigned_at", "status", "activated_at"])
    else:
        inquiry.save(update_fields=["assigned_to", "assigned_at"])

    # Create update
    roles_display = ", ".join(user.get_role_names())
    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="assignment",
        message=f"Inquiry activated and assigned to {user.get_full_name()} ({roles_display})",
        created_by=request.user,
        metadata={
            "old_assignee_id": str(old_assignee.id) if old_assignee else None,
            "new_assignee_id": str(user.id),
            "assignee_roles": user.get_role_names(),
            "old_status": old_status,
            "new_status": inquiry.status,
            "activated_by_current_user": True,
        },
    )

    # Log audit
    AuditService.log_event(
        event_type="inquiry_activated",
        description=f"Inquiry activated by {user.get_full_name()}",
        user=request.user,
        content_object=inquiry,
        metadata={
            "old_assignee_id": str(old_assignee.id) if old_assignee else None,
            "new_assignee_id": str(user.id),
            "old_status": old_status,
            "new_status": inquiry.status,
        },
    )

    messages.success(request, f"Inquiry activated and assigned to you successfully.")

    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_assign(request, pk):
    """Assign inquiry to user"""
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    can_assign = (
        user.is_px_admin()
        or user.is_hospital_admin()
        or (user.is_department_manager() and user.department and user.department == inquiry.department)
    )
    if not can_assign:
        messages.error(request, "You don't have permission to assign inquiries.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    user_id = request.POST.get("user_id")
    if not user_id:
        messages.error(request, "Please select a user to assign.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    try:
        assignee = User.objects.get(id=user_id)
        old_assignee = inquiry.assigned_to
        old_status = inquiry.status

        inquiry.assigned_to = assignee
        inquiry.assigned_at = timezone.now()

        reopened = False
        if old_status in ("resolved", "closed"):
            inquiry.status = "in_progress"
            reopened = True

        inquiry.save()

        msg = f"{'Reopened and a' if reopened else 'A'}ssigned to {assignee.get_full_name()}"
        if old_assignee:
            msg += f" (reassigned from {old_assignee.get_full_name()})"

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="assignment",
            message=msg,
            created_by=request.user,
        )

        AuditService.log_event(
            event_type="assignment",
            description=f"Inquiry {'reopened and ' if reopened else ''}assigned to {assignee.get_full_name()}",
            user=request.user,
            content_object=inquiry,
            metadata={"old_status": old_status, "reopened": reopened},
        )

        if inquiry.department:
            try:
                from apps.notifications.settings_service import NotificationServiceWithSettings
                NotificationServiceWithSettings.send_inquiry_department_assigned(inquiry.department, inquiry)
            except Exception as e:
                logger.warning(f"Failed to send department assignment notification: {e}")

        try:
            from apps.notifications.settings_service import NotificationServiceWithSettings
            NotificationServiceWithSettings.send_inquiry_assigned(inquiry)
        except Exception as e:
            logger.warning(f"Failed to send inquiry assignment notification: {e}")

        messages.success(request, f"Inquiry {'reopened and ' if reopened else ''}assigned to {assignee.get_full_name()}.")

    except User.DoesNotExist:
        messages.error(request, "User not found.")

    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_change_status(request, pk):
    """Change inquiry status"""
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to change inquiry status.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    new_status = request.POST.get("status")
    note = request.POST.get("note", "")

    if not new_status:
        messages.error(request, "Please select a status.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    old_status = inquiry.status
    inquiry.status = new_status

    # Handle status-specific logic
    if new_status == "resolved" and not inquiry.response:
        messages.error(request, "Please add a response before resolving.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    inquiry.save()

    # Create update
    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="status_change",
        message=note or f"Status changed from {old_status} to {new_status}",
        created_by=request.user,
        old_status=old_status,
        new_status=new_status,
    )

    # Log audit
    AuditService.log_event(
        event_type="status_change",
        description=f"Inquiry status changed from {old_status} to {new_status}",
        user=request.user,
        content_object=inquiry,
        metadata={"old_status": old_status, "new_status": new_status},
    )

    messages.success(request, f"Inquiry status changed to {new_status}.")
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_reopen(request, pk):
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or (user.is_department_manager() and user.department == inquiry.department)
    ):
        messages.error(request, "You don't have permission to reopen inquiries.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    if inquiry.status not in ("resolved", "closed"):
        messages.error(request, "Only resolved or closed inquiries can be reopened.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    old_status = inquiry.status
    note = request.POST.get("note", "Inquiry reopened")

    inquiry.status = "in_progress"
    inquiry.save()

    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="status_change",
        message=note or f"Inquiry reopened from {old_status}",
        created_by=user,
    )

    AuditService.log_event(
        event_type="inquiry_reopened",
        description=f"Inquiry reopened from {old_status} by {user.get_full_name()}",
        user=user,
        content_object=inquiry,
        metadata={"old_status": old_status, "new_status": "in_progress"},
    )

    try:
        from apps.notifications.settings_service import NotificationServiceWithSettings
        NotificationServiceWithSettings.send_inquiry_reopened(inquiry)
    except Exception as e:
        logger.warning(f"Failed to send inquiry reopened notification: {e}")

    messages.success(request, "Inquiry reopened successfully.")
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_add_note(request, pk):
    """Add note to inquiry"""
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    note = request.POST.get("note")
    if not note:
        messages.error(request, "Please enter a note.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    # Create update
    InquiryUpdate.objects.create(inquiry=inquiry, update_type="note", message=note, created_by=request.user)

    messages.success(request, "Note added successfully.")
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_respond(request, pk):
    """Respond to inquiry with bilingual support and notification"""
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    can_respond = (
        user.is_px_admin()
        or user.is_hospital_admin()
        or inquiry.assigned_to == user
        or (
            user.is_champion()
            and user.department
            and user.department in [inquiry.department, inquiry.outgoing_department]
        )
    )
    if not can_respond:
        messages.error(request, "You don't have permission to respond to inquiries.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    response_en = request.POST.get("response_en", "").strip()
    response_ar = request.POST.get("response_ar", "").strip()
    response = response_en or response_ar

    if not response:
        messages.error(request, "Please enter a response in at least one language.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    inquiry.response = response
    inquiry.response_en = response_en
    inquiry.response_ar = response_ar
    inquiry.responded_at = timezone.now()
    inquiry.responded_by = request.user
    inquiry.status = "resolved"
    inquiry.save()

    InquiryUpdate.objects.create(
        inquiry=inquiry, update_type="response", message="Response sent", created_by=request.user
    )

    AuditService.log_event(
        event_type="inquiry_responded",
        description=f"Inquiry responded to: {inquiry.subject}",
        user=request.user,
        content_object=inquiry,
    )

    try:
        from apps.notifications.settings_service import NotificationServiceWithSettings
        NotificationServiceWithSettings.send_inquiry_resolved(inquiry)
    except Exception as e:
        logger.warning(f"Failed to send inquiry resolved notification: {e}")

    if inquiry.response_sent_at is None:
        inquiry.response_sent_at = timezone.now()
        inquiry.save(update_fields=["response_sent_at"])

        try:
            from apps.notifications.services import NotificationService, get_email_header_html
            from apps.core.utils import build_public_track_url

            track_url = build_public_track_url("inquiry", inquiry.reference_number)

            if inquiry.contact_phone:
                NotificationService.send_sms(
                    phone=inquiry.contact_phone,
                    message=f"PX360: Your inquiry #{inquiry.reference_number} has been responded to. View details: {track_url}",
                    related_object=inquiry,
                    metadata={"notification_type": "inquiry_response_sent"},
                )

            if inquiry.contact_email:
                email_subject = f"PX360: Response to Your Inquiry #{inquiry.reference_number}"
                email_body = (
                    f"Dear Valued Patient,\n\n"
                    f"Your inquiry #{inquiry.reference_number} has been responded to.\n\n"
                    f"To view the full response, please visit:\n{track_url}\n\n"
                    f"Thank you for your patience.\n\n"
                    f"Reference: {inquiry.reference_number}\n"
                    f"This is an automated message from PX 360."
                )
                NotificationService.send_email(
                    email=inquiry.contact_email,
                    subject=email_subject,
                    message=email_body,
                    html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Response to Your Inquiry</h2>
        <p style="margin: 0 0 12px 0;">Dear Valued Patient,</p>
        <p style="margin: 0 0 12px 0;">Your inquiry <strong>#{inquiry.reference_number}</strong> has been responded to.</p>
        <p style="margin: 0 0 12px 0;">To view the full response, please click the link below:</p>
        <div style="text-align: center; margin: 20px 0;">
            <a href="{track_url}" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">View Response</a>
        </div>
        <p style="margin: 0 0 6px 0; color: #6b7280; font-size: 13px;">Reference: {inquiry.reference_number}</p>
        <p style="margin: 0 0 6px 0; color: #6b7280; font-size: 13px;">Thank you for your patience.</p>
    </div>
</div>
""",
                    related_object=inquiry,
                    metadata={"notification_type": "inquiry_response_email"},
                )

            InquiryUpdate.objects.create(
                inquiry=inquiry,
                update_type="communication",
                message=f"Response notification sent to inquirer (phone: {bool(inquiry.contact_phone)}, email: {bool(inquiry.contact_email)})",
            )
        except Exception as e:
            logger.error(f"Failed to send inquiry response notification: {e}")

    messages.success(request, "Response sent successfully.")
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_transfer_to_department(request, pk):
    from .models import Inquiry, InquiryUpdate

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or user.is_department_manager()
        or user.is_px_management()
    ):
        messages.error(request, _("You don't have permission to transfer inquiries to departments."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    department_id = request.POST.get("department_id")
    if not department_id:
        messages.error(request, _("Please select a department."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    from apps.organizations.models import Department
    try:
        department = Department.objects.select_related("champion", "manager").get(pk=department_id, status="active")
    except Department.DoesNotExist:
        messages.error(request, _("Department not found."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    if not department.champion and not department.manager:
        messages.error(request, _(f"Cannot send to {department.get_localized_name()}. This department has no champion or manager assigned."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    contact_person_id = request.POST.get("contact_person_id")
    if not contact_person_id:
        messages.error(request, _("Please select a contact person."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    contact_info = department.is_valid_contact_person(contact_person_id)
    if not contact_info:
        messages.error(request, _("Selected person is not a role holder in this department."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    contact_person = contact_info["staff"]

    recipient_type = request.POST.get("recipient_type", "staff")

    note_en = request.POST.get("note_en", "").strip()
    note_ar = request.POST.get("note_ar", "").strip()

    note_parts = []
    if note_en:
        note_parts.append(note_en)
    if note_ar:
        note_parts.append(note_ar)
    combined_note = "\n\n".join(note_parts)

    inquiry.outgoing_department = department
    inquiry.transferred_at = timezone.now()
    inquiry.transferred_by = user
    inquiry.transferred_to_department = department
    inquiry.transfer_count = (inquiry.transfer_count or 0) + 1

    sla_config = inquiry.get_sla_config()
    if sla_config and sla_config.dept_response_hours:
        from datetime import timedelta
        inquiry.dept_response_sla_due_at = timezone.now() + timedelta(hours=sla_config.dept_response_hours)
        inquiry.dept_response_is_overdue = False
        inquiry.dept_response_reminder_sent_at = None
        inquiry.dept_response_second_reminder_sent_at = None
        inquiry.dept_response_escalated_at = None

    if inquiry.status in ("open",):
        inquiry.contact_status = "contacted"
        inquiry.contact_status_at = timezone.now()
        inquiry.contact_status_by = user
    inquiry.save()

    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="transferred_to_department",
        message=combined_note or f"Inquiry transferred to {department.get_localized_name()} for response",
        created_by=user,
    )

    try:
        import secrets
        from apps.notifications.settings_service import NotificationServiceWithSettings

        # Generate token for response link
        response_token = secrets.token_urlsafe(32)
        inquiry.response_token = response_token
        inquiry.response_token_sent_at = timezone.now()
        inquiry.save(update_fields=["response_token", "response_token_sent_at"])

        # Build response link
        from django.contrib.sites.shortcuts import get_current_site
        current_site = get_current_site(request)
        domain = current_site.domain if current_site else request.get_host()
        response_link = f"https://{domain}/inquiries/{inquiry.pk}/respond/{response_token}/"

        NotificationServiceWithSettings.send_inquiry_department_assigned(
            department, inquiry, context_note_en=note_en, context_note_ar=note_ar,
            recipient_type=recipient_type,
        )

        contact_email = contact_person.email or (contact_person.user.email if contact_person.user else None)
        if contact_email:
            from apps.notifications.services import NotificationService, get_email_header_html
            NotificationService.send_email(
                email=contact_email,
                subject=f"Inquiry #{inquiry.reference_number} - Response Required",
                message=f"An inquiry has been transferred to your department ({department.get_localized_name()}) for response.\n\nSubject: {inquiry.subject}\n\nSubmit your response here: {response_link}\n\nDeadline: {inquiry.dept_response_sla_due_at}",
                html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Inquiry #{inquiry.reference_number} - Response Required</h2>
        <p style="margin: 0 0 12px 0;">An inquiry has been transferred to your department (<strong>{department.get_localized_name()}</strong>) for response.</p>
        <table style="width: 100%; border-collapse: collapse; margin: 0 0 12px 0;">
            <tr><td style="padding: 4px 0; color: #6b7280; width: 120px;">Subject:</td><td style="padding: 4px 0;">{inquiry.subject}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Deadline:</td><td style="padding: 4px 0;">{inquiry.dept_response_sla_due_at}</td></tr>
        </table>
        <div style="text-align: center; margin: 20px 0;">
            <a href="{response_link}" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">Submit Response</a>
        </div>
        <p style="margin: 0; color: #6b7280; font-size: 13px;">This link can only be used once. After submission, it will expire.</p>
    </div>
</div>
""",
                related_object=inquiry,
            )
    except Exception as e:
        logger.warning(f"Failed to send department notification: {e}")

    if recipient_type == "department_email":
        messages.success(request, _("Inquiry transferred to %(dept)s department email.") % {"dept": department.get_localized_name()})
    else:
        messages.success(request, _("Inquiry transferred to %(dept)s. Department respondents have been notified.") % {"dept": department.get_localized_name()})
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_escalate(request, pk):
    from .models import Inquiry, InquiryUpdate
    from apps.organizations.models import Staff
    from apps.notifications.services import NotificationService, get_email_header_html

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or user.is_px_management()
    ):
        messages.error(request, _("You don't have permission to escalate inquiries."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    if inquiry.status in ("closed", "cancelled"):
        messages.error(request, _("Cannot escalate a closed or cancelled inquiry."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    escalate_to_id = request.POST.get("escalate_to", "")
    reason = request.POST.get("reason", "")

    escalate_to_staff = None
    escalate_to_user = None

    if escalate_to_id:
        try:
            escalate_to_staff = Staff.objects.get(id=escalate_to_id, status="active")
            if escalate_to_staff.user and escalate_to_staff.user.is_active:
                escalate_to_user = escalate_to_staff.user
        except Staff.DoesNotExist:
            pass

    if not escalate_to_user:
        messages.error(request, _("Please select a valid person to escalate to."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    inquiry.escalated_at = timezone.now()
    inquiry.save(update_fields=["escalated_at"])

    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="note",
        message=f"Inquiry escalated to {escalate_to_staff.get_full_name()}. Reason: {reason or 'N/A'}",
        created_by=user,
    )

    email_subject = request.POST.get("email_subject", f"Inquiry Escalated - {inquiry.reference_number}")
    email_body = request.POST.get("email_body", "")

    if escalate_to_user.email:
        try:
            NotificationService.send_email(
                email=escalate_to_user.email,
                subject=email_subject,
                message=email_body,
                html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Inquiry Escalated - {inquiry.reference_number}</h2>
        <p style="margin: 0 0 12px 0;">An inquiry has been escalated to you.</p>
        <table style="width: 100%; border-collapse: collapse; margin: 0 0 12px 0;">
            <tr><td style="padding: 4px 0; color: #6b7280; width: 120px;">Reference:</td><td style="padding: 4px 0;"><strong>{inquiry.reference_number}</strong></td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Escalated by:</td><td style="padding: 4px 0;">{user.get_full_name()}</td></tr>
            <tr><td style="padding: 4px 0; color: #6b7280;">Reason:</td><td style="padding: 4px 0;">{reason or 'N/A'}</td></tr>
        </table>
        <div style="background: #f9fafb; padding: 12px; border-radius: 6px; margin: 0 0 12px 0;">
            <p style="margin: 0;">{email_body}</p>
        </div>
    </div>
</div>
""",
                related_object=inquiry,
                metadata={
                    "notification_type": "inquiry_escalated",
                    "escalated_by": str(user.id),
                    "reason": reason,
                },
            )
        except Exception as e:
            logger.error(f"Failed to send inquiry escalation email: {e}")

    messages.success(request, _(f"Inquiry escalated to {escalate_to_staff.get_full_name()}."))
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_send_to(request, pk):
    """
    Unified AJAX endpoint to send inquiry to either a person or department.
    """
    from django.http import JsonResponse
    from apps.notifications.services import NotificationService, get_email_header_html

    inquiry = get_object_or_404(Inquiry, pk=pk)
    user = request.user

    # Check permission
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or user.is_department_manager()
        or user.is_px_management()
    ):
        return JsonResponse({
            "success": False,
            "error": str(_("You don't have permission to send this inquiry.")),
        }, status=403)

    recipient_type = request.POST.get("recipient_type", "department")
    note = request.POST.get("note", "").strip()

    try:
        if recipient_type == "person":
            person_id = request.POST.get("person_id")
            if not person_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a person.")),
                }, status=400)

            try:
                person = User.objects.get(id=person_id)
            except User.DoesNotExist:
                return JsonResponse({
                    "success": False,
                    "error": str(_("User not found.")),
                }, status=400)

            # Assign inquiry to person
            inquiry.assigned_to = person
            inquiry.assigned_at = timezone.now()
            inquiry.save(update_fields=["assigned_to", "assigned_at"])

            # Send notification
            if person.email:
                NotificationService.send_email(
                    email=person.email,
                    subject=f"Inquiry Assigned - {inquiry.reference_number}",
                    message=f"You have been assigned to inquiry #{inquiry.reference_number}.",
                    html_message=f"""
                    <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
                        {get_email_header_html()}
                        <div style="padding: 20px;">
                            <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Inquiry Assigned</h2>
                            <p>You have been assigned to inquiry <strong>#{inquiry.reference_number}</strong>.</p>
                            <p><strong>Subject:</strong> {inquiry.subject or 'N/A'}</p>
                            {f'<p><strong>Note:</strong> {note}</p>' if note else ''}
                            <p><a href="https://{request.get_host()}/inquiries/{inquiry.pk}/">View Inquiry</a></p>
                        </div>
                    </div>
                    """,
                    related_object=inquiry,
                )

            message = f"Inquiry sent to {person.get_full_name()}."

        else:  # department
            department_id = request.POST.get("department_id")
            if not department_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a department.")),
                }, status=400)

            try:
                department = Department.objects.select_related("champion", "manager").get(pk=department_id, status="active")
            except Department.DoesNotExist:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Department not found.")),
                }, status=400)

            if not department.champion and not department.manager:
                return JsonResponse({
                    "success": False,
                    "error": str(_(f"Cannot send to {department.get_localized_name()}. This department has no champion or manager assigned.")),
                }, status=400)

            contact_person_id = request.POST.get("contact_person_id")
            if not contact_person_id:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Please select a contact person.")),
                }, status=400)

            contact_info = department.is_valid_contact_person(contact_person_id)
            if not contact_info:
                return JsonResponse({
                    "success": False,
                    "error": str(_("Selected person is not a role holder in this department.")),
                }, status=400)

            # Transfer to department
            inquiry.outgoing_department = department
            inquiry.transferred_at = timezone.now()
            inquiry.transferred_by = user
            inquiry.transferred_to_department = department
            inquiry.transfer_count = (inquiry.transfer_count or 0) + 1

            if inquiry.department_id == department.pk:
                inquiry.sent_to_department = True
                inquiry.sent_to_department_at = timezone.now()

            sla_config = inquiry.get_sla_config()
            if sla_config and sla_config.dept_response_hours:
                from datetime import timedelta
                inquiry.dept_response_sla_due_at = timezone.now() + timedelta(hours=sla_config.dept_response_hours)
                inquiry.dept_response_is_overdue = False
                inquiry.dept_response_reminder_sent_at = None
                inquiry.dept_response_second_reminder_sent_at = None
                inquiry.dept_response_escalated_at = None

            message = f"Inquiry sent to {department.get_localized_name()} — {contact_info['name']} ({contact_info['role_label']})."

        # Set contact_status if open
        if inquiry.status in ("open",):
            inquiry.contact_status = "contacted"
            inquiry.contact_status_at = timezone.now()
            inquiry.contact_status_by = user

        inquiry.save()

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="transferred_to_department" if recipient_type == "department" else "assigned",
            message=note or f"Inquiry sent to {recipient_type}",
            created_by=user,
        )

        # Send department notification if applicable
        if recipient_type == "department":
            try:
                from apps.notifications.settings_service import NotificationServiceWithSettings
                NotificationServiceWithSettings.send_inquiry_department_assigned(
                    department, inquiry, context_note_en=note, context_note_ar="",
                )
            except Exception as e:
                logger.warning(f"Failed to send department notification: {e}")

        return JsonResponse({
            "success": True,
            "message": message,
        })

    except Exception as e:
        logger.error(f"Error in inquiry_send_to: {str(e)}")
        return JsonResponse({
            "success": False,
            "error": str(_("An error occurred while sending the inquiry.")),
        }, status=500)


@login_required
@require_http_methods(["GET", "POST"])
def inquiry_department_response(request, pk):
    from .models import Inquiry

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (
        user.is_px_admin()
        or user.is_hospital_admin()
        or (user.is_champion() and (
            inquiry.department == user.department
            or inquiry.outgoing_department == user.department
        ))
    ):
        messages.error(request, "You don't have permission to respond to this inquiry.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    if request.method == "POST":
        response_en = request.POST.get("response_en", "").strip()
        response_ar = request.POST.get("response_ar", "").strip()
        response = response_en or response_ar

        if not response:
            messages.error(request, "Please enter a response in at least one language.")
            return redirect("inquiries:inquiry_department_response", pk=pk)

        inquiry.department_response_en = response_en
        inquiry.department_response_ar = response_ar
        inquiry.department_responded_at = timezone.now()
        inquiry.department_responded_by = request.user
        inquiry.dept_response_is_overdue = False
        inquiry.dept_response_acceptance_status = "pending"
        inquiry.dept_response_accepted_by = None
        inquiry.dept_response_accepted_at = None
        inquiry.dept_response_acceptance_notes = ""
        inquiry.save()

        try:
            from apps.core.ai_service import AIService
            import json

            prompt = f"""You are an AI assistant for a hospital patient experience system. Summarize the following department response to a patient inquiry in 2-3 concise sentences.

Inquiry subject: {inquiry.subject}
Inquiry message: {inquiry.message[:500]}
Department response: {response[:500]}

Generate a JSON response with:
- "summary_en": A brief summary of the department's response in English (2-3 sentences)
- "summary_ar": The same summary translated to Modern Standard Arabic"""

            result = AIService.chat_completion(
                prompt=prompt,
                response_format="json_object",
            )
            parsed = json.loads(result)
            inquiry.department_response_summary_en = parsed.get("summary_en", "")
            inquiry.department_response_summary_ar = parsed.get("summary_ar", "")
            inquiry.save(update_fields=["department_response_summary_en", "department_response_summary_ar"])
        except Exception as e:
            logger.warning(f"AI summary of department response failed: {e}")

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="department_response",
            message=f"Department response submitted by {user.get_full_name()}",
            created_by=user,
        )

        AuditService.log_event(
            event_type="inquiry_department_response",
            description=f"Department response submitted for inquiry: {inquiry.subject}",
            user=user,
            content_object=inquiry,
        )

        # Notify inquirer that department has responded
        try:
            from apps.notifications.services import NotificationService
            from apps.core.utils import build_public_track_url

            track_url = build_public_track_url("inquiry", inquiry.reference_number)
            if inquiry.contact_phone:
                NotificationService.send_sms(
                    phone=inquiry.contact_phone,
                    message=f"PX360: Your inquiry {inquiry.reference_number} has been responded to. View: {track_url}",
                    related_object=inquiry,
                )
            if inquiry.contact_email:
                NotificationService.send_email(
                    email=inquiry.contact_email,
                    subject=f"PX360: Response to Your Inquiry {inquiry.reference_number}",
                    message=f"Your inquiry has been responded to.\n\nView: {track_url}",
                    related_object=inquiry,
                )
        except Exception as e:
            logger.warning(f"Failed to send inquirer notification: {e}")

        messages.success(request, "Department response submitted successfully.")
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            from django.http import JsonResponse
            redirect_url = reverse("organizations:department_detail", kwargs={"pk": user.department.pk}) if user.department else reverse("inquiries:inquiry_detail", kwargs={"pk": pk})
            return JsonResponse({"success": True, "redirect_url": redirect_url})
        if user.department:
            return redirect("organizations:department_detail", pk=user.department.pk)
        return redirect("inquiries:inquiry_detail", pk=pk)

    context = {
        "inquiry": inquiry,
    }
    return render(request, "complaints/inquiry_department_response.html", context)


@login_required
@require_http_methods(["POST"])
def inquiry_review_dept_response(request, pk):
    from .models import Inquiry, InquiryUpdate

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to review department responses.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    if not inquiry.department_responded_at:
        messages.error(request, "No department response to review.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    status = request.POST.get("acceptance_status")
    if status not in ("acceptable", "not_acceptable"):
        messages.error(request, "Invalid acceptance status.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    notes = request.POST.get("acceptance_notes", "").strip()

    if status == "not_acceptable":
        inquiry.dept_response_acceptance_status = "not_acceptable"
        inquiry.dept_response_accepted_by = user
        inquiry.dept_response_accepted_at = timezone.now()
        inquiry.dept_response_acceptance_notes = notes
        inquiry.department_response_en = ""
        inquiry.department_response_ar = ""
        inquiry.department_response_summary_en = ""
        inquiry.department_response_summary_ar = ""
        inquiry.department_responded_at = None
        inquiry.department_responded_by = None
        inquiry.save(
            update_fields=[
                "dept_response_acceptance_status",
                "dept_response_accepted_by",
                "dept_response_accepted_at",
                "dept_response_acceptance_notes",
                "department_response_en",
                "department_response_ar",
                "department_response_summary_en",
                "department_response_summary_ar",
                "department_responded_at",
                "department_responded_by",
            ]
        )

        dept = inquiry.outgoing_department or inquiry.transferred_to_department
        if dept and dept.champion and dept.champion.user and dept.champion.user.email:
            try:
                from apps.notifications.services import NotificationService, get_email_header_html

                NotificationService.send_email(
                    email=dept.champion.user.email,
                    subject=f"Action Required: Inquiry #{inquiry.reference_number} - Response Rejected",
                    message=(
                        f"Your department's response for inquiry #{inquiry.reference_number} has been rejected.\n\n"
                        f"Reason: {notes}\n\n"
                        f"Please revise and resubmit your response."
                    ),
                    html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Response Rejected - Inquiry #{inquiry.reference_number}</h2>
        <p style="margin: 0 0 12px 0;">Your department's response for inquiry <strong>#{inquiry.reference_number}</strong> has been rejected.</p>
        <div style="background: #fef2f2; padding: 12px; border-radius: 6px; margin: 0 0 12px 0;">
            <p style="margin: 0;"><strong>Reason:</strong> {notes}</p>
        </div>
        <p style="margin: 0; color: #6b7280;">Please revise and resubmit your response.</p>
    </div>
</div>
""",
                    related_object=inquiry,
                )
            except Exception:
                import logging
                logging.getLogger(__name__).exception("Failed to send inquiry dept response rejection email")

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="note",
            message=f"Department response rejected by {user.get_full_name()}. Reason: {notes}",
            created_by=user,
        )

        AuditService.log_event(
            event_type="inquiry_dept_response_review",
            description=f"Department response for inquiry {inquiry.reference_number} rejected by {user.get_full_name()}",
            user=user,
            content_object=inquiry,
        )

        messages.success(request, "Department response rejected. The department has been notified to resubmit.")
    else:
        inquiry.dept_response_acceptance_status = status
        inquiry.dept_response_accepted_by = user
        inquiry.dept_response_accepted_at = timezone.now()
        inquiry.dept_response_acceptance_notes = notes
        inquiry.save(
            update_fields=[
                "dept_response_acceptance_status",
                "dept_response_accepted_by",
                "dept_response_accepted_at",
                "dept_response_acceptance_notes",
            ]
        )

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="note",
            message=f"Department response marked as {status} by {user.get_full_name()}. {notes}",
            created_by=user,
        )

        AuditService.log_event(
            event_type="inquiry_dept_response_review",
            description=f"Department response for inquiry {inquiry.reference_number} marked as {status}",
            user=user,
            content_object=inquiry,
        )

        messages.success(request, f"Department response marked as {status}.")

    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
@require_http_methods(["POST"])
def inquiry_send_dept_response_reminder(request, pk):
    from .models import Inquiry, InquiryUpdate

    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to send reminders.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    if inquiry.department_responded_at:
        messages.warning(request, "Department has already responded.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    dept = inquiry.outgoing_department or inquiry.transferred_to_department
    if not dept:
        messages.error(request, "No department assigned.")
        return redirect("inquiries:inquiry_detail", pk=pk)

    reminder_type = request.POST.get("reminder_type", "first")

    try:
        from apps.notifications.services import NotificationService, get_email_header_html

        recipients = []
        if dept.champion and dept.champion.user and dept.champion.user.email:
            recipients.append(dept.champion.user)

        for recipient in recipients:
            NotificationService.send_email(
                email=recipient.email,
                subject=f"Reminder: Inquiry #{inquiry.reference_number} - Response Required",
                message=f"This is a reminder that inquiry #{inquiry.reference_number} is awaiting your department's response. Please submit your response as soon as possible.",
                html_message=f"""
<div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
    {get_email_header_html()}
    <div style="padding: 20px;">
        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Reminder: Response Required</h2>
        <p style="margin: 0 0 12px 0;">This is a reminder that inquiry <strong>#{inquiry.reference_number}</strong> is awaiting your department's response.</p>
        <p style="margin: 0; color: #6b7280;">Please submit your response as soon as possible.</p>
    </div>
</div>
""",
                related_object=inquiry,
            )

        if reminder_type == "first":
            inquiry.dept_response_reminder_sent_at = timezone.now()
        else:
            inquiry.dept_response_second_reminder_sent_at = timezone.now()
        inquiry.save()

        InquiryUpdate.objects.create(
            inquiry=inquiry,
            update_type="note",
            message=f"Manual {reminder_type} reminder sent by {user.get_full_name()}",
            created_by=user,
        )

        messages.success(request, f"Reminder sent to {len(recipients)} recipient(s).")
    except Exception as e:
        logger.error(f"Failed to send reminder: {e}")
        messages.error(request, "Failed to send reminder.")

    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
def inquiry_export_incoming(request):
    """Export incoming inquiries report."""
    from .utils import export_inquiries_report

    year = request.GET.get("year")
    month = request.GET.get("month")
    if not year or not month:
        messages.error(request, "Year and month are required.")
        return redirect("inquiries:inquiry_list")

    queryset = Inquiry.objects.filter(created_at__year=int(year), created_at__month=int(month), is_outgoing=False)
    if request.user.is_hospital_admin() and request.user.hospital:
        queryset = queryset.filter(hospital=request.user.hospital)
    elif request.user.is_px_admin() and request.tenant_hospital:
        queryset = queryset.filter(hospital=request.tenant_hospital)

    return export_inquiries_report(queryset, int(year), int(month), is_outgoing=False)


@login_required
def inquiry_export_outgoing(request):
    """Export outgoing inquiries report."""
    from .utils import export_inquiries_report

    year = request.GET.get("year")
    month = request.GET.get("month")
    if not year or not month:
        messages.error(request, "Year and month are required.")
        return redirect("inquiries:inquiry_list")

    queryset = Inquiry.objects.filter(created_at__year=int(year), created_at__month=int(month), is_outgoing=True)
    if request.user.is_hospital_admin() and request.user.hospital:
        queryset = queryset.filter(hospital=request.user.hospital)
    elif request.user.is_px_admin() and request.tenant_hospital:
        queryset = queryset.filter(hospital=request.tenant_hospital)

    return export_inquiries_report(queryset, int(year), int(month), is_outgoing=True)


@login_required
@require_http_methods(["POST"])
def inquiry_update_contact_stage(request, pk):
    """Update a contact tracking stage on the inquiry."""
    inquiry = get_object_or_404(Inquiry, pk=pk)

    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin() or inquiry.assigned_to == user):
        messages.error(request, _("You don't have permission to update contact tracking."))
        return redirect("inquiries:inquiry_detail", pk=pk)

    stage = request.POST.get("stage")
    import datetime as _dt

    if stage == "contacted_nr":
        date_str = request.POST.get("contacted_nr_date")
        time_str = request.POST.get("contacted_nr_time")
        duration_str = request.POST.get("contacted_nr_duration")
        if date_str:
            inquiry.contacted_nr_at = _dt.datetime.strptime(date_str, "%Y-%m-%d")
        if time_str:
            inquiry.contacted_nr_time = _dt.datetime.strptime(time_str, "%H:%M").time()
        if duration_str:
            parts = duration_str.split(":")
            inquiry.contacted_nr_duration = _dt.timedelta(
                hours=int(parts[0]), minutes=int(parts[1] if len(parts) > 1 else 0),
                seconds=int(parts[2] if len(parts) > 2 else 0),
            )
        inquiry.contacted_nr_by = user
        if inquiry.status == "open":
            inquiry.contact_status = "contacted_no_response"
            inquiry.contact_status_at = timezone.now()
            inquiry.contact_status_by = user

    elif stage == "under_process":
        date_str = request.POST.get("under_process_date")
        time_str = request.POST.get("under_process_time")
        duration_str = request.POST.get("under_process_duration")
        if date_str:
            inquiry.under_process_at = _dt.datetime.strptime(date_str, "%Y-%m-%d")
        if time_str:
            inquiry.under_process_time = _dt.datetime.strptime(time_str, "%H:%M").time()
        if duration_str:
            parts = duration_str.split(":")
            inquiry.under_process_duration = _dt.timedelta(
                hours=int(parts[0]), minutes=int(parts[1] if len(parts) > 1 else 0),
                seconds=int(parts[2] if len(parts) > 2 else 0),
            )
        inquiry.under_process_by = user
        if inquiry.status == "open":
            inquiry.status = "in_progress"

    elif stage == "contacted":
        date_str = request.POST.get("contacted_date")
        time_str = request.POST.get("contacted_time")
        duration_str = request.POST.get("contacted_duration")
        if date_str:
            inquiry.contacted_at = _dt.datetime.strptime(date_str, "%Y-%m-%d")
        if time_str:
            inquiry.contacted_time = _dt.datetime.strptime(time_str, "%H:%M").time()
        if duration_str:
            parts = duration_str.split(":")
            inquiry.contacted_duration = _dt.timedelta(
                hours=int(parts[0]), minutes=int(parts[1] if len(parts) > 1 else 0),
                seconds=int(parts[2] if len(parts) > 2 else 0),
            )
        inquiry.contacted_by = user
        if inquiry.status in ("open", "in_progress"):
            inquiry.contact_status = "contacted"
            inquiry.contact_status_at = timezone.now()
            inquiry.contact_status_by = user

    elif stage == "notes":
        inquiry.staff_notes = request.POST.get("staff_notes", inquiry.staff_notes)
        if user.is_px_admin() or user.is_hospital_admin():
            inquiry.supervisor_notes = request.POST.get("supervisor_notes", inquiry.supervisor_notes)

    elif stage == "timeline_sla":
        inquiry.timeline_sla = request.POST.get("timeline_sla", inquiry.timeline_sla)

    inquiry.save()

    stage_labels = {
        "contacted_nr": "Contacted No Response",
        "under_process": "Under Process",
        "contacted": "Contacted",
        "notes": "Notes",
        "timeline_sla": "Timeline SLA",
    }
    InquiryUpdate.objects.create(
        inquiry=inquiry,
        update_type="note",
        message=f"Contact tracking updated: {stage_labels.get(stage, stage)}",
        created_by=user,
    )
    messages.success(request, _("Contact tracking updated."))
    return redirect("inquiries:inquiry_detail", pk=pk)


@login_required
def complaints_analytics(request):
    """
    Complaints analytics dashboard.
    """
    from .analytics import ComplaintAnalytics

    user = request.user
    hospital = None

    # Apply RBAC
    if user.is_px_admin() and request.tenant_hospital:
        hospital = request.tenant_hospital
    elif not user.is_px_admin() and user.hospital:
        hospital = user.hospital

    # Get date range from request
    date_range = int(request.GET.get("date_range", 30))

    # Get analytics data
    dashboard_summary = ComplaintAnalytics.get_dashboard_summary(hospital)
    trends = ComplaintAnalytics.get_complaint_trends(hospital, date_range)
    sla_compliance = ComplaintAnalytics.get_sla_compliance(hospital, date_range)
    resolution_rate = ComplaintAnalytics.get_resolution_rate(hospital, date_range)
    top_categories = ComplaintAnalytics.get_top_categories(hospital, date_range)
    overdue_complaints = ComplaintAnalytics.get_overdue_complaints(hospital)

    context = {
        "dashboard_summary": dashboard_summary,
        "trends": trends,
        "sla_compliance": sla_compliance,
        "resolution_rate": resolution_rate,
        "top_categories": top_categories,
        "overdue_complaints": overdue_complaints,
        "date_range": date_range,
    }

    return render(request, "complaints/analytics.html", context)


# ============================================================================
# PUBLIC COMPLAINT FORM (No Authentication Required)
# ============================================================================


def public_complaint_submit(request):
    """
    Public complaint submission form (accessible without login).
    Handles both GET (show form) and POST (submit complaint).

    Updated to match form structure:
    - Location hierarchy: Location, Main Section, Subsection (3-level dropdowns)
    - Complainant information: name, email, mobile, relation to patient
    - Patient information: name, national ID, incident date
    - Staff reference: staff name
    - Complaint details and expected result
    """
    if request.method == "POST":
        try:
            # Get form data from public complaint form
            complainant_name = request.POST.get("complainant_name")
            email = request.POST.get("email", "")
            mobile_number = request.POST.get("mobile_number")
            relation_to_patient = request.POST.get("relation_to_patient", "")
            hospital_id = request.POST.get("hospital")
            category = request.POST.get("category", "")
            location_type = request.POST.get("location_type", "")
            department_id = request.POST.get("department")
            section_id = request.POST.get("section")
            area_id = request.POST.get("area")
            patient_name = request.POST.get("patient_name", "")
            national_id = request.POST.get("national_id", "")
            incident_date = request.POST.get("incident_date")
            staff_name = request.POST.get("staff_name", "")
            complaint_details = request.POST.get("complaint_details")
            expected_result = request.POST.get("expected_result", "")

            # Validate required fields
            errors = []
            if not complainant_name:
                errors.append(_("Complainant name is required"))
            if not mobile_number:
                errors.append(_("Mobile number is required"))
            if not hospital_id:
                errors.append(_("Hospital is required"))
            if not location_type:
                errors.append(_("Location type is required"))
            if not department_id:
                errors.append(_("Department is required"))
            if not complaint_details:
                errors.append(_("Complaint details are required"))
            if incident_date:
                from datetime import datetime as dt, date
                try:
                    parsed_date = dt.strptime(incident_date, "%Y-%m-%d").date()
                    if parsed_date > date.today():
                        errors.append(_("Incident date cannot be in the future"))
                except (ValueError, TypeError):
                    errors.append(_("Invalid incident date format"))

            if errors:
                if request.headers.get("x-requested-with") == "XMLHttpRequest":
                    return JsonResponse({"success": False, "errors": errors}, status=400)
                else:
                    messages.error(request, _("Please fill in all required fields."))
                    return render(
                        request,
                        "complaints/public_complaint_form.html",
                        {
                            "hospitals": Hospital.objects.filter(status="active").order_by("name"),
                        },
                    )

            # Get hospital
            hospital = Hospital.objects.get(id=hospital_id)

            from apps.organizations.models import Area, Department, Section, OrgSubSection

            department = Department.objects.get(id=department_id)
            section = Section.objects.filter(id=section_id).first() if section_id else None
            area = Area.objects.filter(id=area_id).first() if area_id else None

            # Reference number generated by Complaint.save() (unified CMP-YYYYMM-HOSP-NNNN)

            # Create complaint with location hierarchy and all form fields
            complaint = Complaint.objects.create(
                patient=None,
                hospital=hospital,
                department=department,
                section=section,
                area=area,
                location_type=location_type if location_type else "",
                title="Complaint",
                description=complaint_details,
                severity="medium",
                priority="medium",
                status="open",
                complaint_source_type=ComplaintSourceType.INTERNAL,                source=PXSource.objects.filter(name_en="Public Form").first(),
                contact_name=complainant_name,
                contact_phone=mobile_number,
                contact_email=email,
                relation_to_patient=relation_to_patient,
                patient_name=patient_name,
                national_id=national_id,
                incident_date=parsed_date if incident_date else None,
                staff_name=staff_name,
                expected_result=expected_result,
            )

            # Create initial update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="note",
                message="Complaint submitted via public form. AI analysis running in background.",
            )

            # Trigger AI analysis in the background using Celery
            from .tasks import analyze_complaint_with_ai, notify_staff_new_item

            analyze_complaint_with_ai.delay(str(complaint.id))
            notify_staff_new_item.delay("complaint", str(complaint.id))

            # If form was submitted via AJAX, return JSON
            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse(
                    {
                        "success": True,
                        "reference_number": reference_number,
                        "message": "Complaint submitted successfully. AI has analyzed and classified your complaint.",
                    }
                )

            # Otherwise, redirect to success page
            return redirect("complaints:public_complaint_success", reference=reference_number)

        except Hospital.DoesNotExist:
            error_msg = _("Selected hospital not found.")
            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse({"success": False, "message": error_msg}, status=400)
            messages.error(request, error_msg)
            return render(
                request,
                "complaints/public_complaint_form.html",
                {
                    "hospitals": Hospital.objects.filter(status="active").order_by("name"),
                },
            )
        except Exception as e:
            import traceback

            traceback.print_exc()
            # If AJAX, return error JSON
            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse({"success": False, "message": str(e)}, status=400)

            # Otherwise, show error message
            return render(
                request,
                "complaints/public_complaint_form.html",
                {"hospitals": Hospital.objects.filter(status="active").order_by("name"), "error": str(e)},
            )

    # GET request - show form
    return render(
        request,
        "complaints/public_complaint_form.html",
        {
            "hospitals": Hospital.objects.filter(status="active").order_by("name"),
        },
    )


def public_complaint_track(request):
    """
    Public complaint tracking page.

    Allows complainants to check the status of their complaint using the reference number.
    No authentication required.

    Features:
    - Form to enter reference number
    - Display complaint status when found
    - Show basic information (status, category, submission date, last update)
    - Timeline of public updates (without exposing internal notes)
    - SLA deadline information
    """
    complaint = None
    error_message = None
    reference_number = request.GET.get("reference", "").strip()

    if request.method == "POST":
        reference_number = request.POST.get("reference_number", "").strip()

        if not reference_number:
            error_message = _("Please enter a reference number.")
        else:
            # Try to find complaint by reference number
            try:
                complaint = (
                    Complaint.objects.select_related("hospital", "department")
                    .prefetch_related("updates")
                    .get(reference_number__iexact=reference_number)
                )

                # Check overdue status
                complaint.check_overdue()

            except Complaint.DoesNotExist:
                error_message = _("No complaint found with this reference number. Please check and try again.")

    elif reference_number:
        # GET request with reference parameter
        try:
            complaint = (
                Complaint.objects.select_related("hospital", "department")
                .prefetch_related("updates")
                .get(reference_number__iexact=reference_number)
            )

            # Check overdue status
            complaint.check_overdue()

        except Complaint.DoesNotExist:
            error_message = _("No complaint found with this reference number. Please check and try again.")

    public_status = None
    public_updates = []
    if complaint:
        public_status = complaint.public_status

        public_updates = list(
            complaint.updates.filter(update_type__in=["status_change", "resolution"]).order_by(
                "-created_at"
            )
        )

        _status_map = {
            "open": str(_("Received")),
            "in_progress": str(_("In Progress")),
            "partially_resolved": str(_("In Progress")),
            "resolved": str(_("Resolved")),
            "closed": str(_("Closed")),
            "cancelled": str(_("Cancelled")),
        }
        for update in public_updates:
            if update.message:
                for internal, public_label in _status_map.items():
                    update.message = update.message.replace(internal, public_label)
            if hasattr(update, "old_status") and update.old_status:
                update.old_status = _status_map.get(update.old_status, update.old_status)
            if hasattr(update, "new_status") and update.new_status:
                update.new_status = _status_map.get(update.new_status, update.new_status)

    context = {
        "complaint": complaint,
        "public_status": public_status,
        "public_updates": public_updates,
        "error_message": error_message,
        "reference_number": reference_number,
    }

    return render(request, "complaints/public_complaint_track.html", context)


def public_complaint_success(request, reference):
    """
    Success page after public complaint submission.
    """
    return render(request, "complaints/public_complaint_success.html", {"reference_number": reference})


def public_inquiry_submit(request):
    """
    Public inquiry submission form (accessible without login).
    Allows patients/public to submit general inquiries without authentication.
    """
    if request.method == "POST":
        try:
            name = request.POST.get("name")
            email = request.POST.get("email")
            phone = request.POST.get("phone")
            hospital_id = request.POST.get("hospital")
            location_type = request.POST.get("location_type", "")
            department_id = request.POST.get("department", "")
            section_id = request.POST.get("section", "")
            category = request.POST.get("category", "general")
            subject = request.POST.get("subject")
            message = request.POST.get("message")

            errors = []
            if not name:
                errors.append(_("Name is required"))
            if not phone:
                errors.append(_("Phone number is required"))
            if not hospital_id:
                errors.append(_("Hospital is required"))
            if not subject:
                errors.append(_("Subject is required"))
            if not message:
                errors.append(_("Message is required"))

            if errors:
                if request.headers.get("x-requested-with") == "XMLHttpRequest":
                    return JsonResponse({"success": False, "errors": errors}, status=400)
                else:
                    messages.error(request, _("Please fill in all required fields."))
                    return render(
                        request,
                        "complaints/public_inquiry_form.html",
                        {
                            "hospitals": Hospital.objects.filter(status="active").order_by("name"),
                            "categories": [
                                ("appointment", "Appointment"),
                                ("billing", "Billing"),
                                ("medical_records", "Medical Records"),
                                ("general", "General Information"),
                                ("other", "Other"),
                            ],
                        },
                    )

            hospital = Hospital.objects.get(id=hospital_id)

            from apps.organizations.models import Department, Section
            department = Department.objects.filter(id=department_id).first() if department_id else None
            section = Section.objects.filter(id=section_id).first() if section_id else None

            import uuid
            from datetime import datetime

            today = datetime.now().strftime("%Y%m%d")
            random_suffix = str(uuid.uuid4().int)[:6]
            reference_number = f"INQ-{today}-{random_suffix}"

            inquiry = Inquiry.objects.create(
                patient=None,
                hospital=hospital,
                department=department,
                section=section,
                location_type=location_type if location_type else "",
                subject=subject,
                message=message,
                category=category,
                contact_name=name,
                contact_phone=phone,
                contact_email=email,
                status="open",
                reference_number=reference_number,
                is_outgoing=False,
            )

            from apps.complaints.tasks import analyze_inquiry_with_ai, notify_staff_new_item

            analyze_inquiry_with_ai.delay(str(inquiry.id))
            notify_staff_new_item.delay("inquiry", str(inquiry.id))

            AuditService.log_event(
                event_type="inquiry_created_public",
                description=f"Public inquiry submitted: {subject}",
                content_object=inquiry,
                metadata={"reference": reference_number, "source": "public_form"},
            )

            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse(
                    {
                        "success": True,
                        "message": _("Inquiry submitted successfully!"),
                        "reference_number": reference_number,
                    }
                )

            return redirect("inquiries:public_inquiry_success", reference=reference_number)

        except Hospital.DoesNotExist:
            error_msg = _("Selected hospital not found.")
            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse({"success": False, "message": error_msg}, status=400)
            messages.error(request, error_msg)
        except Exception as e:
            if request.headers.get("x-requested-with") == "XMLHttpRequest":
                return JsonResponse({"success": False, "message": str(e)}, status=400)
            messages.error(request, str(e))

    return render(
        request,
        "complaints/public_inquiry_form.html",
        {
            "hospitals": Hospital.objects.filter(status="active").order_by("name"),
            "categories": [
                ("appointment", "Appointment"),
                ("billing", "Billing"),
                ("medical_records", "Medical Records"),
                ("general", "General Information"),
                ("other", "Other"),
            ],
        },
    )


def public_inquiry_success(request, reference):
    """
    Success page after public inquiry submission.
    """
    return render(request, "complaints/public_inquiry_success.html", {"reference_number": reference})


def public_inquiry_track(request):
    """
    Public inquiry tracking page. Allows users to check their inquiry status
    using the reference number received after submission.
    """
    from .models import Inquiry

    inquiry = None
    public_status = None
    error_message = None
    reference = request.GET.get("reference", "").strip() or request.POST.get("reference", "").strip()

    if request.method == "POST":
        reference = request.POST.get("reference_number", "").strip()

    if not reference and request.GET.get("reference"):
        reference = request.GET.get("reference").strip()

    if reference:
        inquiry = (
            Inquiry.objects.filter(reference_number__iexact=reference)
            .select_related("hospital", "department")
            .first()
        )
        if inquiry:
            status_map = {
                "open": {"label": _("Received"), "slug": "received", "progress": 15, "css": "amber"},
                "in_progress": {"label": _("In Progress"), "slug": "in_progress", "progress": 50, "css": "blue"},
                "contacted": {"label": _("In Progress"), "slug": "in_progress", "progress": 50, "css": "blue"},
                "contacted_no_response": {"label": _("In Progress"), "slug": "in_progress", "progress": 50, "css": "blue"},
                "resolved": {"label": _("Resolved"), "slug": "resolved", "progress": 100, "css": "emerald"},
                "closed": {"label": _("Closed"), "slug": "closed", "progress": 100, "css": "slate"},
            }
            sm = status_map.get(inquiry.status, {"label": _("Received"), "slug": "received", "progress": 15, "css": "amber"})
            public_status = {
                "label": str(sm["label"]),
                "slug": sm["slug"],
                "progress": sm["progress"],
                "css": sm["css"],
            }
        else:
            error_message = _("No inquiry found with this reference number. Please check and try again.")

    has_response = bool(inquiry and (inquiry.department_response_en or inquiry.department_response_ar))
    response_en = inquiry.department_response_en if inquiry else ""
    response_ar = inquiry.department_response_ar if inquiry else ""

    if request.headers.get("x-requested-with") == "XMLHttpRequest":
        if inquiry:
            return JsonResponse({
                "success": True,
                "reference": inquiry.reference_number,
                "status": inquiry.get_status_display(),
                "subject": inquiry.subject,
                "created_at": inquiry.created_at.strftime("%Y-%m-%d %H:%M"),
                "has_response": has_response,
                "response_en": response_en,
                "response_ar": response_ar,
            })
        else:
            return JsonResponse({"success": False, "error": "Inquiry not found"})

    return render(request, "complaints/public_inquiry_track.html", {
        "inquiry": inquiry,
        "public_status": public_status,
        "error_message": error_message,
        "reference_number": reference,
        "has_response": has_response,
        "response_en": response_en,
        "response_ar": response_ar,
    })


def api_lookup_patient(request):
    """
    AJAX endpoint to look up patient by national ID or phone.
    No authentication required for public form.
    """
    from apps.organizations.models import Patient

    national_id = request.GET.get("national_id", "").strip()
    phone = request.GET.get("phone", "").strip()

    if not national_id and not phone:
        return JsonResponse({"found": False, "error": "National ID or phone required"}, status=400)

    patient = None
    lookup_method = None

    if national_id:
        from apps.core.encryption import compute_national_id_hash

        nid_hash = compute_national_id_hash(national_id)
        patient = Patient.objects.filter(national_id_hash=nid_hash, status="active").first()
        lookup_method = "national_id"

    if not patient and phone:
        patient = Patient.objects.filter(phone=phone, status="active").first()
        lookup_method = "phone"

    if patient:
        return JsonResponse(
            {
                "found": True,
                "id": str(patient.id),
                "mrn": patient.mrn,
                "name": patient.get_full_name(),
                "phone": patient.phone or "",
                "email": patient.email or "",
                "lookup_method": lookup_method,
            }
        )

    return JsonResponse({"found": False, "message": "Patient not found"})


def api_load_departments(request):
    """
    AJAX endpoint to load departments for a hospital.
    No authentication required for public form.
    """
    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")

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


def api_load_categories(request):
    """
    AJAX endpoint to load complaint categories for a hospital.
    Shows hospital-specific categories first, then system-wide categories.
    Returns both parent categories and their subcategories with parent_id.
    Now includes level field for 4-level hierarchy support (Domain, Category, Subcategory, Classification).
    No authentication required for public form.

    Updated: Always returns system-wide categories even without hospital_id,
    to support initial form loading.
    """
    from .models import ComplaintCategory

    hospital_id = request.GET.get("hospital_id")

    # Build queryset - always include system-wide categories
    if hospital_id:
        # Return hospital-specific and system-wide categories
        # Empty hospitals list = system-wide
        categories_queryset = (
            ComplaintCategory.objects.filter(Q(hospitals__id=hospital_id) | Q(hospitals__isnull=True), is_active=True)
            .distinct()
            .order_by("level", "order", "name_en")
        )
    else:
        # Return all system-wide categories (empty hospitals list)
        # This allows form to load domains on initial page load
        categories_queryset = ComplaintCategory.objects.filter(Q(hospitals__isnull=True), is_active=True).order_by(
            "level", "order", "name_en"
        )

    # Get all categories with parent_id, level, domain_type, and descriptions
    categories = categories_queryset.values(
        "id", "name_en", "name_ar", "code", "parent_id", "level", "domain_type", "description_en", "description_ar"
    )

    return JsonResponse({"categories": list(categories)})


# ============================================================================
# AJAX/API HELPERS (Authentication Required)
# ============================================================================


@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_department(request):
    """Get staff for a department (AJAX)"""
    department_id = request.GET.get("department_id")
    if not department_id:
        return JsonResponse({"staff": []})

    staff_members = Staff.objects.filter(department_id=department_id, status="active").values(
        "id", "first_name", "last_name", "staff_type", "job_title"
    )

    return JsonResponse({"staff": list(staff_members)})


@login_required
def search_patients(request):
    """Search patients by MRN or name (AJAX)"""
    from apps.organizations.models import Patient

    query = request.GET.get("q", "")
    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)
    )[:10]

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

    return JsonResponse({"patients": results})


@px_admin_required
@login_required
def sla_management(request):
    """
    PX Admin-only SLA management page.

    Automatically uses the hospital from session (selected after login).
    Provides a clean interface to manage complaint SLA configurations.
    """
    from .models import ComplaintSLAConfig
    from apps.organizations.models import Hospital

    # Get hospital from session (set after login)
    hospital_id = request.session.get("selected_hospital_id")

    if not hospital_id:
        messages.error(request, "Please select a hospital first.")
        return redirect("core:select_hospital")

    # Get the hospital
    try:
        hospital = Hospital.objects.get(id=hospital_id)
    except Hospital.DoesNotExist:
        messages.error(request, "Selected hospital not found.")
        return redirect("core:select_hospital")

    # Get all SLA configs for this hospital
    sla_configs = (
        ComplaintSLAConfig.objects.filter(hospital=hospital, is_active=True)
        .select_related("source")
        .order_by("source", "severity", "priority")
    )

    # Group configs by type
    source_based_configs = sla_configs.filter(source__isnull=False)
    severity_based_configs = sla_configs.filter(source__isnull=True)

    context = {
        "hospital": hospital,
        "source_based_configs": source_based_configs,
        "severity_based_configs": severity_based_configs,
        "total_configs": sla_configs.count(),
    }

    return render(request, "complaints/sla_management.html", context)


@px_admin_required
@login_required
@require_http_methods(["GET", "POST"])
def sla_management_create(request):
    """
    PX Admin-only: Create new SLA configuration for selected hospital.
    """
    from .models import ComplaintSLAConfig
    from .forms import SLAConfigForm
    from apps.organizations.models import Hospital

    # Get hospital from session
    hospital_id = request.session.get("selected_hospital_id")

    if not hospital_id:
        messages.error(request, "Please select a hospital first.")
        return redirect("core:select_hospital")

    try:
        hospital = Hospital.objects.get(id=hospital_id)
    except Hospital.DoesNotExist:
        messages.error(request, "Selected hospital not found.")
        return redirect("core:select_hospital")

    if request.method == "POST":
        form = SLAConfigForm(request.POST, request=request)

        if form.is_valid():
            # Force hospital to session hospital
            sla_config = form.save(commit=False)
            sla_config.hospital = hospital
            sla_config.save()

            # Log audit
            AuditService.log_event(
                event_type="sla_config_created",
                description=f"SLA configuration created: {sla_config}",
                user=request.user,
                content_object=sla_config,
                metadata={
                    "hospital": str(sla_config.hospital),
                    "severity": sla_config.severity,
                    "priority": sla_config.priority,
                    "sla_hours": sla_config.sla_hours,
                },
            )

            messages.success(request, "SLA configuration created successfully.")
            return redirect("complaints:sla_management")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = SLAConfigForm(request=request)
        # Pre-select hospital (hidden field)
        form.fields["hospital"].initial = hospital.id

    context = {
        "form": form,
        "hospital": hospital,
        "title": "Create SLA Configuration",
        "action": "Create",
    }

    return render(request, "complaints/sla_management_form.html", context)


@px_admin_required
@login_required
@require_http_methods(["GET", "POST"])
def sla_management_edit(request, pk):
    """
    PX Admin-only: Edit SLA configuration for selected hospital.
    """
    from .models import ComplaintSLAConfig
    from .forms import SLAConfigForm
    from apps.organizations.models import Hospital

    # Get hospital from session
    hospital_id = request.session.get("selected_hospital_id")

    if not hospital_id:
        messages.error(request, "Please select a hospital first.")
        return redirect("core:select_hospital")

    try:
        hospital = Hospital.objects.get(id=hospital_id)
    except Hospital.DoesNotExist:
        messages.error(request, "Selected hospital not found.")
        return redirect("core:select_hospital")

    sla_config = get_object_or_404(ComplaintSLAConfig, pk=pk)

    if request.method == "POST":
        form = SLAConfigForm(request.POST, request=request, instance=sla_config)

        if form.is_valid():
            sla_config = form.save()

            # Log audit
            AuditService.log_event(
                event_type="sla_config_updated",
                description=f"SLA configuration updated: {sla_config}",
                user=request.user,
                content_object=sla_config,
                metadata={
                    "hospital": str(sla_config.hospital),
                    "severity": sla_config.severity,
                    "priority": sla_config.priority,
                    "sla_hours": sla_config.sla_hours,
                },
            )

            messages.success(request, "SLA configuration updated successfully.")
            return redirect("complaints:sla_management")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = SLAConfigForm(request=request, instance=sla_config)

    context = {
        "form": form,
        "sla_config": sla_config,
        "hospital": hospital,
        "title": "Edit SLA Configuration",
        "action": "Update",
    }

    return render(request, "complaints/sla_management_form.html", context)


@px_admin_required
@login_required
@require_http_methods(["POST"])
def sla_management_toggle(request, pk):
    """
    PX Admin-only: Toggle SLA configuration active/inactive status.
    """
    from .models import ComplaintSLAConfig

    sla_config = get_object_or_404(ComplaintSLAConfig, pk=pk)

    # Toggle status
    sla_config.is_active = not sla_config.is_active
    sla_config.save()

    # Log audit
    AuditService.log_event(
        event_type="sla_config_toggled",
        description=f"SLA configuration {'activated' if sla_config.is_active else 'deactivated'}: {sla_config}",
        user=request.user,
        content_object=sla_config,
        metadata={
            "hospital": str(sla_config.hospital),
            "is_active": sla_config.is_active,
        },
    )

    status_text = "activated" if sla_config.is_active else "deactivated"
    messages.success(request, f"SLA configuration {status_text} successfully.")
    return redirect("complaints:sla_management")


@login_required
def escalation_rule_list(request):
    """
    Escalation Rules list view with filters.

    Allows Hospital Admins and PX Admins to manage escalation rules.
    """
    from .models import EscalationRule

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to manage escalation rules.")
        return redirect("accounts:settings")

    # Base queryset
    queryset = EscalationRule.objects.select_related("hospital", "escalate_to_user").all()

    # Apply hospital filter
    if not user.is_px_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)

    # Apply filters from request
    hospital_filter = request.GET.get("hospital")
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    escalation_level_filter = request.GET.get("escalation_level")
    if escalation_level_filter:
        queryset = queryset.filter(escalation_level=escalation_level_filter)

    is_active_filter = request.GET.get("is_active")
    if is_active_filter:
        queryset = queryset.filter(is_active=(is_active_filter == "true"))

    # Ordering
    order_by = request.GET.get("order_by", "hospital__name")
    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)

    context = {
        "page_obj": page_obj,
        "escalation_rules": page_obj.object_list,
        "filters": request.GET,
    }

    return render(request, "complaints/escalation_rule_list.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def escalation_rule_create(request):
    """
    Create new escalation rule.
    """
    from .models import EscalationRule
    from .forms import EscalationRuleForm

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to create escalation rules.")
        return redirect("accounts:settings")

    if request.method == "POST":
        form = EscalationRuleForm(request.POST, request=request)

        if form.is_valid():
            escalation_rule = form.save()

            # Log audit
            AuditService.log_event(
                event_type="escalation_rule_created",
                description=f"Escalation rule created: {escalation_rule}",
                user=request.user,
                content_object=escalation_rule,
                metadata={
                    "hospital": str(escalation_rule.hospital),
                    "name": escalation_rule.name,
                    "escalation_level": escalation_rule.escalation_level,
                },
            )

            messages.success(request, "Escalation rule created successfully.")
            return redirect("complaints:escalation_rule_list")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = EscalationRuleForm(request=request)

    context = {
        "form": form,
        "title": "Create Escalation Rule",
        "action": "Create",
    }

    return render(request, "complaints/escalation_rule_form.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def escalation_rule_edit(request, pk):
    """
    Edit existing escalation rule.
    """
    from .models import EscalationRule
    from .forms import EscalationRuleForm

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to edit escalation rules.")
        return redirect("accounts:settings")

    escalation_rule = get_object_or_404(EscalationRule, pk=pk)

    # Check if user can edit this rule
    if not user.is_px_admin() and escalation_rule.hospital != user.hospital:
        messages.error(request, "You don't have permission to edit this escalation rule.")
        return redirect("complaints:escalation_rule_list")

    if request.method == "POST":
        form = EscalationRuleForm(request.POST, request=request, instance=escalation_rule)

        if form.is_valid():
            escalation_rule = form.save()

            # Log audit
            AuditService.log_event(
                event_type="escalation_rule_updated",
                description=f"Escalation rule updated: {escalation_rule}",
                user=request.user,
                content_object=escalation_rule,
                metadata={
                    "hospital": str(escalation_rule.hospital),
                    "name": escalation_rule.name,
                    "escalation_level": escalation_rule.escalation_level,
                },
            )

            messages.success(request, "Escalation rule updated successfully.")
            return redirect("complaints:escalation_rule_list")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = EscalationRuleForm(request=request, instance=escalation_rule)

    context = {
        "form": form,
        "escalation_rule": escalation_rule,
        "title": "Edit Escalation Rule",
        "action": "Update",
    }

    return render(request, "complaints/escalation_rule_form.html", context)


@login_required
@require_http_methods(["POST"])
def escalation_rule_delete(request, pk):
    """
    Delete escalation rule.
    """
    from .models import EscalationRule

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to delete escalation rules.")
        return redirect("accounts:settings")

    escalation_rule = get_object_or_404(EscalationRule, pk=pk)

    # Check if user can delete this rule
    if not user.is_px_admin() and escalation_rule.hospital != user.hospital:
        messages.error(request, "You don't have permission to delete this escalation rule.")
        return redirect("complaints:escalation_rule_list")

    escalation_rule.delete()

    # Log audit
    AuditService.log_event(
        event_type="escalation_rule_deleted",
        description=f"Escalation rule deleted: {escalation_rule}",
        user=request.user,
        metadata={
            "hospital": str(escalation_rule.hospital),
            "name": escalation_rule.name,
        },
    )

    messages.success(request, "Escalation rule deleted successfully.")
    return redirect("complaints:escalation_rule_list")


@login_required
def complaint_threshold_list(request):
    """
    Complaint Threshold list view with filters.

    Allows Hospital Admins and PX Admins to manage complaint thresholds.
    """
    from .models import ComplaintThreshold

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to manage complaint thresholds.")
        return redirect("accounts:settings")

    # Base queryset
    queryset = ComplaintThreshold.objects.select_related("hospital").all()

    # Apply hospital filter
    if not user.is_px_admin() and user.hospital:
        queryset = queryset.filter(hospital=user.hospital)

    # Apply filters from request
    hospital_filter = request.GET.get("hospital")
    if hospital_filter:
        queryset = queryset.filter(hospital_id=hospital_filter)

    threshold_type_filter = request.GET.get("threshold_type")
    if threshold_type_filter:
        queryset = queryset.filter(threshold_type=threshold_type_filter)

    is_active_filter = request.GET.get("is_active")
    if is_active_filter:
        queryset = queryset.filter(is_active=(is_active_filter == "true"))

    # Ordering
    order_by = request.GET.get("order_by", "hospital__name")
    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)

    context = {
        "page_obj": page_obj,
        "thresholds": page_obj.object_list,
        "filters": request.GET,
    }

    return render(request, "complaints/complaint_threshold_list.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def complaint_threshold_create(request):
    """
    Create new complaint threshold.
    """
    from .models import ComplaintThreshold
    from .forms import ComplaintThresholdForm

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to create complaint thresholds.")
        return redirect("accounts:settings")

    if request.method == "POST":
        form = ComplaintThresholdForm(request.POST, request=request)

        if form.is_valid():
            threshold = form.save()

            # Log audit
            AuditService.log_event(
                event_type="complaint_threshold_created",
                description=f"Complaint threshold created: {threshold}",
                user=request.user,
                content_object=threshold,
                metadata={
                    "hospital": str(threshold.hospital),
                    "threshold_type": threshold.threshold_type,
                    "threshold_value": threshold.threshold_value,
                },
            )

            messages.success(request, "Complaint threshold created successfully.")
            return redirect("complaints:complaint_threshold_list")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = ComplaintThresholdForm(request=request)

    context = {
        "form": form,
        "title": "Create Complaint Threshold",
        "action": "Create",
    }

    return render(request, "complaints/complaint_threshold_form.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def complaint_threshold_edit(request, pk):
    """
    Edit existing complaint threshold.
    """
    from .models import ComplaintThreshold
    from .forms import ComplaintThresholdForm

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to edit complaint thresholds.")
        return redirect("accounts:settings")

    threshold = get_object_or_404(ComplaintThreshold, pk=pk)

    # Check if user can edit this threshold
    if not user.is_px_admin() and threshold.hospital != user.hospital:
        messages.error(request, "You don't have permission to edit this complaint threshold.")
        return redirect("complaints:complaint_threshold_list")

    if request.method == "POST":
        form = ComplaintThresholdForm(request.POST, request=request, instance=threshold)

        if form.is_valid():
            threshold = form.save()

            # Log audit
            AuditService.log_event(
                event_type="complaint_threshold_updated",
                description=f"Complaint threshold updated: {threshold}",
                user=request.user,
                content_object=threshold,
                metadata={
                    "hospital": str(threshold.hospital),
                    "threshold_type": threshold.threshold_type,
                    "threshold_value": threshold.threshold_value,
                },
            )

            messages.success(request, "Complaint threshold updated successfully.")
            return redirect("complaints:complaint_threshold_list")
        else:
            messages.error(request, "Please correct the errors below.")
    else:
        form = ComplaintThresholdForm(request=request, instance=threshold)

    context = {
        "form": form,
        "threshold": threshold,
        "title": "Edit Complaint Threshold",
        "action": "Update",
    }

    return render(request, "complaints/complaint_threshold_form.html", context)


@login_required
@require_http_methods(["POST"])
def complaint_threshold_delete(request, pk):
    """
    Delete complaint threshold.
    """
    from .models import ComplaintThreshold

    # Check permission
    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, "You don't have permission to delete complaint thresholds.")
        return redirect("accounts:settings")

    threshold = get_object_or_404(ComplaintThreshold, pk=pk)

    # Check if user can delete this threshold
    if not user.is_px_admin() and threshold.hospital != user.hospital:
        messages.error(request, "You don't have permission to delete this complaint threshold.")
        return redirect("complaints:complaint_threshold_list")

    threshold.delete()

    # Log audit
    AuditService.log_event(
        event_type="complaint_threshold_deleted",
        description=f"Complaint threshold deleted: {threshold}",
        user=request.user,
        metadata={
            "hospital": str(threshold.hospital),
            "threshold_type": threshold.threshold_type,
        },
    )

    messages.success(request, "Complaint threshold deleted successfully.")
    return redirect("complaints:complaint_threshold_list")


# ============================================================================
# Involved Departments and Staff Views
# ============================================================================


@login_required
@require_http_methods(["POST"])
def confirm_ai_department_suggestion(request, complaint_pk):
    """
    Confirm the AI-suggested department and add it as an involved department.
    """
    from .models import ComplaintInvolvedDepartment

    complaint = get_object_or_404(Complaint, pk=complaint_pk)

    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    suggested_department = complaint.department
    if not suggested_department:
        messages.warning(request, _("No AI department suggestion found."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    already_involved = complaint.involved_departments.filter(department=suggested_department).exists()
    if already_involved:
        messages.info(request, _("This department is already involved."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    ComplaintInvolvedDepartment.objects.create(
        complaint=complaint,
        department=suggested_department,
        role="primary",
        is_primary=True,
        added_by=user,
        assigned_at=timezone.now(),
    )

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="assignment",
        message=f"AI suggested department confirmed: {suggested_department.name} (Primary)",
        created_by=user,
    )

    AuditService.log_event(
        event_type="complaint_department_added",
        description=f"AI department suggestion confirmed: {suggested_department.name} for complaint {complaint.reference_number}",
        user=user,
        content_object=complaint,
        metadata={
            "department_id": str(suggested_department.pk),
            "department_name": suggested_department.name,
            "role": "primary",
            "is_primary": True,
            "source": "ai_suggestion",
        },
    )

    messages.success(
        request,
        _("Department '%(dept)s' added as Primary (AI suggestion confirmed).") % {"dept": suggested_department.name},
    )
    return redirect("complaints:complaint_detail", pk=complaint.pk)


@login_required
@require_http_methods(["GET", "POST"])
def involved_department_add(request, complaint_pk):
    """
    Add an involved department to a complaint.

    Allows assigning multiple departments with different roles:
    - Primary: Main responsible department
    - Secondary/Supporting: Assisting departments
    - Coordination: Only for coordination
    - Investigating: Leading the investigation
    """
    complaint = get_object_or_404(Complaint, pk=complaint_pk)

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if request.method == "POST":
        form = ComplaintInvolvedDepartmentForm(request.POST, complaint=complaint, user=user)

        if form.is_valid():
            involved_dept = form.save(commit=False)
            involved_dept.complaint = complaint
            involved_dept.added_by = user

            # Set assignment timestamp if assigned
            if involved_dept.assigned_to and not involved_dept.assigned_at:
                involved_dept.assigned_at = timezone.now()

            involved_dept.save()

            # Log the update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="assignment",
                message=f"Department added: {involved_dept.department.name} ({involved_dept.get_role_display()})",
                created_by=user,
            )

            # Audit log
            AuditService.log_event(
                event_type="complaint_department_added",
                description=f"Department {involved_dept.department.name} added to complaint {complaint.reference_number}",
                user=user,
                content_object=complaint,
                metadata={
                    "department_id": str(involved_dept.department.pk),
                    "department_name": involved_dept.department.name,
                    "role": involved_dept.role,
                    "is_primary": involved_dept.is_primary,
                },
            )

            messages.success(
                request,
                _("Department '%(dept)s' added successfully as %(role)s.")
                % {"dept": involved_dept.department.name, "role": involved_dept.get_role_display()},
            )
            return redirect("complaints:complaint_detail", pk=complaint.pk)
        else:
            messages.error(request, _("Please correct the errors below."))
    else:
        form = ComplaintInvolvedDepartmentForm(complaint=complaint, user=user)

    context = {
        "form": form,
        "complaint": complaint,
        "title": _("Add Involved Department"),
    }

    return render(request, "complaints/involved_department_form.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def involved_department_edit(request, pk):
    """
    Edit an involved department's details.
    """
    from .models import ComplaintInvolvedDepartment

    involved_dept = get_object_or_404(ComplaintInvolvedDepartment, pk=pk)
    complaint = involved_dept.complaint

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if request.method == "POST":
        form = ComplaintInvolvedDepartmentForm(request.POST, instance=involved_dept, complaint=complaint, user=user)

        if form.is_valid():
            # Check if assignment is being changed
            old_assigned_to = involved_dept.assigned_to
            involved_dept = form.save(commit=False)

            # Set assignment timestamp if newly assigned
            if involved_dept.assigned_to and not old_assigned_to:
                involved_dept.assigned_at = timezone.now()

            involved_dept.save()

            # Log the update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="assignment",
                message=f"Department updated: {involved_dept.department.name} ({involved_dept.get_role_display()})",
                created_by=user,
            )

            messages.success(request, _("Department involvement updated successfully."))
            return redirect("complaints:complaint_detail", pk=complaint.pk)
        else:
            messages.error(request, _("Please correct the errors below."))
    else:
        form = ComplaintInvolvedDepartmentForm(instance=involved_dept, complaint=complaint, user=user)

    context = {
        "form": form,
        "complaint": complaint,
        "involved_dept": involved_dept,
        "title": _("Edit Involved Department"),
    }

    return render(request, "complaints/involved_department_form.html", context)


@login_required
@require_http_methods(["POST"])
def involved_department_remove(request, pk):
    """
    Remove an involved department from a complaint.
    """
    from .models import ComplaintInvolvedDepartment

    involved_dept = get_object_or_404(ComplaintInvolvedDepartment, pk=pk)
    complaint = involved_dept.complaint
    department_name = involved_dept.department.name

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    involved_dept.delete()

    # Log the update
    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="assignment",
        message=f"Department removed: {department_name}",
        created_by=user,
    )

    # Audit log
    AuditService.log_event(
        event_type="complaint_department_removed",
        description=f"Department {department_name} removed from complaint {complaint.reference_number}",
        user=user,
        content_object=complaint,
    )

    messages.success(request, _("Department removed successfully."))
    return redirect("complaints:complaint_detail", pk=complaint.pk)


@login_required
@require_http_methods(["POST"])
def involved_department_response(request, pk):
    """
    Submit a department's response to the complaint.
    Supports both regular POST and AJAX requests.
    """
    from .models import ComplaintInvolvedDepartment
    from django.http import JsonResponse

    involved_dept = get_object_or_404(ComplaintInvolvedDepartment, pk=pk)
    complaint = involved_dept.complaint
    user = request.user

    # Check permission - must be champion/manager of this department, assigned to it, or have complaint management rights
    is_dept_champion = (
        user.is_champion()
        and user.department == involved_dept.department
    )
    is_dept_manager = (
        user.is_department_manager()
        and user.department == involved_dept.department
    )
    can_respond = (
        is_dept_champion
        or is_dept_manager
        or involved_dept.assigned_to == user
        or can_manage_complaint(user, complaint)
    )

    if not can_respond:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                "success": False,
                "error": str(_("You don't have permission to submit a response for this department.")),
            }, status=403)
        messages.error(request, _("You don't have permission to submit a response for this department."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    response_notes = request.POST.get("response_notes", "").strip()
    response_notes_en = request.POST.get("response_notes_en", "").strip()
    response_notes_ar = request.POST.get("response_notes_ar", "").strip()

    if not response_notes and not response_notes_en and not response_notes_ar:
        if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
            return JsonResponse({
                "success": False,
                "error": str(_("Please provide a valid response.")),
            }, status=400)
        messages.error(request, _("Please provide a valid response."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    involved_dept.response_notes = response_notes or response_notes_en or response_notes_ar
    involved_dept.response_notes_en = response_notes_en
    involved_dept.response_notes_ar = response_notes_ar
    involved_dept.response_submitted = True
    involved_dept.response_submitted_at = timezone.now()
    involved_dept.acceptance_status = "pending"
    involved_dept.accepted_by = None
    involved_dept.accepted_at = None
    involved_dept.acceptance_notes = ""
    involved_dept.manager_review_status = "pending"
    involved_dept.manager_reviewed_by = None
    involved_dept.manager_reviewed_at = None
    involved_dept.save()

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="note",
        message=f"Response submitted by {involved_dept.department.name}",
        created_by=user,
    )

    # Notify complainant that department has responded
    try:
        from apps.notifications.services import NotificationService
        from apps.core.utils import build_public_track_url

        track_url = build_public_track_url("complaint", complaint.reference_number)
        if complaint.contact_phone:
            NotificationService.send_sms(
                phone=complaint.contact_phone,
                message=f"PX360: Your complaint {complaint.reference_number} has been responded to. View: {track_url}",
                related_object=complaint,
            )
        if complaint.contact_email:
            NotificationService.send_email(
                email=complaint.contact_email,
                subject=f"PX360: Response to Your Complaint {complaint.reference_number}",
                message=f"Your complaint has been responded to.\n\nView: {track_url}",
                related_object=complaint,
            )
    except Exception as e:
        logger.warning(f"Failed to send complainant notification: {e}")

    dept = involved_dept.department
    if dept.manager and dept.manager.email:
        try:
            from apps.notifications.services import NotificationService, get_email_header_html
            review_url = request.build_absolute_uri(
                reverse("organizations:department_manager_review", kwargs={"pk": dept.pk, "idept_pk": involved_dept.pk})
            )
            NotificationService.send_email(
                dept.manager.email,
                subject=f"Champion Response Requires Your Review - {complaint.reference_number}",
                message=(
                    f"A champion response for complaint {complaint.reference_number} "
                    f"from {involved_dept.department.name} requires your review and approval.\n\n"
                    f"Please review at: {review_url}"
                ),
                html_message=f"""
                <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
                    {get_email_header_html()}
                    <div style="padding: 20px;">
                        <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Champion Response Requires Your Review</h2>
                        <p>A champion from <strong>{involved_dept.department.name}</strong> has submitted a response
                        for complaint <strong>{complaint.reference_number}</strong>.</p>
                        <p>Your review and approval is required before it is forwarded to the PX team.</p>
                        <p style="margin-top: 16px;">
                            <a href="{review_url}" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">Review Response</a>
                        </p>
                    </div>
                </div>
                """,
                related_object=complaint,
            )
        except Exception as e:
            logger.error(f"Failed to send manager review notification: {e}")

    if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
        redirect_url = reverse("organizations:department_detail", kwargs={"pk": user.department.pk}) if user.department else reverse("complaints:complaint_detail", kwargs={"pk": complaint.pk})
        return JsonResponse({
            "success": True,
            "message": str(_("Department response submitted successfully.")),
            "redirect_url": redirect_url,
        })

    messages.success(request, _("Department response submitted successfully."))
    if user.department:
        return redirect("organizations:department_detail", pk=user.department.pk)
    return redirect("complaints:complaint_detail", pk=complaint.pk)


@login_required
@require_http_methods(["POST"])
def involved_department_review_response(request, pk):
    """
    Review (accept/reject) a department's response to a complaint.
    On rejection, notifies the champion and resets for resubmission.
    """
    from .models import ComplaintInvolvedDepartment

    involved_dept = get_object_or_404(ComplaintInvolvedDepartment, pk=pk)
    complaint = involved_dept.complaint

    user = request.user
    if not (user.is_px_admin() or user.is_hospital_admin()):
        messages.error(request, _("You don't have permission to review department responses."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if not involved_dept.response_submitted:
        messages.error(request, _("No department response to review."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if involved_dept.manager_review_status != "approved":
        messages.error(request, _("This response has not been approved by the department manager yet."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    acceptance = request.POST.get("acceptance_status")
    if acceptance not in ("acceptable", "not_acceptable"):
        messages.error(request, _("Invalid acceptance status."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    notes = request.POST.get("acceptance_notes", "").strip()

    involved_dept.acceptance_status = acceptance
    involved_dept.accepted_by = user
    involved_dept.accepted_at = timezone.now()
    involved_dept.acceptance_notes = notes

    if acceptance == "not_acceptable":
        involved_dept.response_submitted = False
        involved_dept.response_submitted_at = None
        involved_dept.response_notes = ""
        involved_dept.response_notes_en = ""
        involved_dept.response_notes_ar = ""
        involved_dept.acceptance_status = "not_acceptable"

    involved_dept.save()

    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="note",
        message=f"Department response from {involved_dept.department.name} marked as {acceptance} by {user.get_full_name()}. {notes}",
        created_by=user,
    )

    AuditService.log_event(
        event_type="complaint_dept_response_review",
        description=f"Department response for complaint {complaint.reference_number} marked as {acceptance}",
        user=user,
        content_object=complaint,
    )

    if acceptance == "not_acceptable":
        dept = involved_dept.department
        recipients = set()
        if dept.champion and dept.champion.user and dept.champion.user.email:
            recipients.add(dept.champion.user.email)
        if dept.manager and dept.manager.email:
            recipients.add(dept.manager.email)
        for email in recipients:
            try:
                    from apps.notifications.services import NotificationService, get_email_header_html
                    NotificationService.send_email(
                        email,
                        subject=f"Response Rejected - {complaint.reference_number}",
                    message=(
                        f"Your department's response for complaint {complaint.reference_number} was not accepted.\n\n"
                        f"Reason: {notes or 'No reason provided.'}\n\n"
                        f"Please submit a new response."
                    ),
                    html_message=f"""
                    <div style="font-family: 'Segoe UI', Tahoma, sans-serif; max-width: 600px; margin: 0 auto; border: 1px solid #e5e7eb; border-radius: 8px; overflow: hidden;">
                        {get_email_header_html()}
                        <div style="padding: 20px;">
                            <h2 style="color: #005696; font-size: 18px; margin: 0 0 12px 0;">Response Not Accepted</h2>
                            <p>Your department's response for complaint <strong>{complaint.reference_number}</strong> was not accepted.</p>
                            <p><strong>Reason:</strong> {notes or 'No reason provided.'}</p>
                            <p style="margin-top: 16px;">Please review and submit a new response.</p>
                        </div>
                    </div>
                    """,
                    related_object=complaint,
                )
            except Exception as e:
                logger.error(f"Failed to send rejection notification: {e}")

    messages.success(request, _(f"Department response marked as {acceptance}."))
    return redirect("complaints:complaint_detail", pk=complaint.pk)


@login_required
@require_http_methods(["GET", "POST"])
def involved_staff_add(request, complaint_pk):
    """
    Add an involved staff member to a complaint.

    Allows assigning multiple staff members with different roles:
    - Accused/Involved: Staff member involved in the incident
    - Witness: Staff member who witnessed the incident
    - Responsible: Staff responsible for resolution
    - Investigator: Staff investigating the complaint
    - Support: Support staff
    - PX Employee: Coordination role
    """
    complaint = get_object_or_404(Complaint, pk=complaint_pk)

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if request.method == "POST":
        form = ComplaintInvolvedStaffForm(request.POST, complaint=complaint, user=user)

        if form.is_valid():
            involved_staff = form.save(commit=False)
            involved_staff.complaint = complaint
            involved_staff.added_by = user
            involved_staff.save()

            # Log the update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="assignment",
                message=f"Staff added: {involved_staff.staff} ({involved_staff.get_role_display()})",
                created_by=user,
            )

            # Audit log
            AuditService.log_event(
                event_type="complaint_staff_added",
                description=f"Staff {involved_staff.staff} added to complaint {complaint.reference_number}",
                user=user,
                content_object=complaint,
                metadata={
                    "staff_id": str(involved_staff.staff.pk),
                    "staff_name": str(involved_staff.staff),
                    "role": involved_staff.role,
                },
            )

            messages.success(
                request,
                _("Staff member '%(staff)s' added successfully as %(role)s.")
                % {"staff": involved_staff.staff, "role": involved_staff.get_role_display()},
            )
            return redirect("complaints:complaint_detail", pk=complaint.pk)
        else:
            messages.error(request, _("Please correct the errors below."))
    else:
        form = ComplaintInvolvedStaffForm(complaint=complaint, user=user)

    context = {
        "form": form,
        "complaint": complaint,
        "title": _("Add Involved Staff"),
    }

    return render(request, "complaints/involved_staff_form.html", context)


@login_required
@require_http_methods(["GET", "POST"])
def involved_staff_edit(request, pk):
    """
    Edit an involved staff member's details.
    """
    from .models import ComplaintInvolvedStaff

    involved_staff = get_object_or_404(ComplaintInvolvedStaff, pk=pk)
    complaint = involved_staff.complaint

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    if request.method == "POST":
        form = ComplaintInvolvedStaffForm(request.POST, instance=involved_staff, complaint=complaint, user=user)

        if form.is_valid():
            form.save()

            # Log the update
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="assignment",
                message=f"Staff updated: {involved_staff.staff} ({involved_staff.get_role_display()})",
                created_by=user,
            )

            messages.success(request, _("Staff involvement updated successfully."))
            return redirect("complaints:complaint_detail", pk=complaint.pk)
        else:
            messages.error(request, _("Please correct the errors below."))
    else:
        form = ComplaintInvolvedStaffForm(instance=involved_staff, complaint=complaint, user=user)

    context = {
        "form": form,
        "complaint": complaint,
        "involved_staff": involved_staff,
        "title": _("Edit Involved Staff"),
    }

    return render(request, "complaints/involved_staff_form.html", context)


@login_required
@require_http_methods(["POST"])
def involved_staff_remove(request, pk):
    """
    Remove an involved staff member from a complaint.
    """
    from .models import ComplaintInvolvedStaff

    involved_staff = get_object_or_404(ComplaintInvolvedStaff, pk=pk)
    complaint = involved_staff.complaint
    staff_name = str(involved_staff.staff)

    # Check permission
    user = request.user
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to manage this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    involved_staff.delete()

    # Log the update
    ComplaintUpdate.objects.create(
        complaint=complaint,
        update_type="assignment",
        message=f"Staff removed: {staff_name}",
        created_by=user,
    )

    # Audit log
    AuditService.log_event(
        event_type="complaint_staff_removed",
        description=f"Staff {staff_name} removed from complaint {complaint.reference_number}",
        user=user,
        content_object=complaint,
    )

    messages.success(request, _("Staff member removed successfully."))
    return redirect("complaints:complaint_detail", pk=complaint.pk)


@login_required
@require_http_methods(["POST"])
def involved_staff_explanation(request, pk):
    """
    Submit an explanation as an involved staff member.
    """
    from .models import ComplaintInvolvedStaff

    involved_staff = get_object_or_404(ComplaintInvolvedStaff, pk=pk)
    complaint = involved_staff.complaint
    user = request.user

    # Check permission - must be the staff member themselves or have management rights
    can_submit = (
        involved_staff.staff.user == user if hasattr(involved_staff.staff, "user") else False
    ) or can_manage_complaint(user, complaint)

    if not can_submit:
        messages.error(request, _("You don't have permission to submit an explanation for this staff member."))
        return redirect("complaints:complaint_detail", pk=complaint.pk)

    form = StaffExplanationForm(request.POST, instance=involved_staff)

    if form.is_valid():
        involved_staff = form.save(commit=False)
        involved_staff.explanation_received = True
        involved_staff.explanation_received_at = timezone.now()
        involved_staff.save()

        # Log the update
        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="note",
            message=f"Explanation submitted by {involved_staff.staff}",
            created_by=user,
        )

        messages.success(request, _("Explanation submitted successfully."))
    else:
        messages.error(request, _("Please provide a valid explanation."))

    return redirect("complaints:complaint_detail", pk=complaint.pk)


# =============================================================================
# Complaint Adverse Action Views
# =============================================================================


@login_required
def adverse_action_list(request):
    """
    List all adverse actions related to complaints.

    Features:
    - Filter by status, severity, action type
    - Search by complaint reference or description
    - Paginated results
    """
    # Check permission
    user = request.user
    if not user.is_px_admin() and not user.is_hospital_admin():
        messages.error(request, _("You don't have permission to view adverse actions."))
        return redirect("complaints:complaint_list")

    # Base queryset
    queryset = ComplaintAdverseAction.objects.select_related(
        "complaint", "complaint__hospital", "reported_by"
    ).prefetch_related("involved_staff")

    # 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)

    action_type_filter = request.GET.get("action_type")
    if action_type_filter:
        queryset = queryset.filter(action_type=action_type_filter)

    # Filter by hospital for hospital admins
    if user.is_hospital_admin() and user.hospital:
        queryset = queryset.filter(complaint__hospital=user.hospital)

    # Search
    search_query = request.GET.get("search")
    if search_query:
        queryset = queryset.filter(
            Q(complaint__reference_number__icontains=search_query)
            | Q(description__icontains=search_query)
            | Q(patient_impact__icontains=search_query)
        )

    # Pagination
    paginator = Paginator(queryset.order_by("-incident_date"), 25)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)

    context = {
        "page_obj": page_obj,
        "status_choices": ComplaintAdverseAction.VerificationStatus.choices,
        "severity_choices": ComplaintAdverseAction.SeverityLevel.choices,
        "action_type_choices": ComplaintAdverseAction.ActionType.choices,
        "filters": request.GET,
    }

    return render(request, "complaints/adverse_action_list.html", context)


@login_required
def adverse_action_add(request, complaint_pk):
    """
    Add a new adverse action to a complaint.
    """
    complaint = get_object_or_404(Complaint, pk=complaint_pk)
    user = request.user

    # Check permission
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to add adverse actions to this complaint."))
        return redirect("complaints:complaint_detail", pk=complaint_pk)

    if request.method == "POST":
        try:
            # Parse form data
            action_type = request.POST.get("action_type")
            severity = request.POST.get("severity")
            description = request.POST.get("description", "").strip()
            patient_impact = request.POST.get("patient_impact", "").strip()
            incident_date = request.POST.get("incident_date")
            location = request.POST.get("location", "").strip()
            involved_staff_ids = request.POST.getlist("involved_staff")

            if not description:
                messages.error(request, _("Description is required."))
                return render(
                    request,
                    "complaints/adverse_action_form.html",
                    {
                        "complaint": complaint,
                        "action_type_choices": ComplaintAdverseAction.ActionType.choices,
                        "severity_choices": ComplaintAdverseAction.SeverityLevel.choices,
                        "staff_list": Staff.objects.filter(hospital=complaint.hospital, is_active=True),
                    },
                )

            # Create adverse action
            adverse_action = ComplaintAdverseAction.objects.create(
                complaint=complaint,
                action_type=action_type or ComplaintAdverseAction.ActionType.OTHER,
                severity=severity or ComplaintAdverseAction.SeverityLevel.MEDIUM,
                description=description,
                patient_impact=patient_impact,
                incident_date=incident_date or timezone.now(),
                location=location,
                reported_by=user,
                status=ComplaintAdverseAction.VerificationStatus.REPORTED,
            )

            # Add involved staff
            if involved_staff_ids:
                adverse_action.involved_staff.set(involved_staff_ids)

            # Create timeline entry
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="note",
                message=f"Adverse action reported: {adverse_action.get_action_type_display()}",
                created_by=user,
            )

            # Log audit
            AuditService.log_event(
                event_type="adverse_action_created",
                description=f"Adverse action added to complaint {complaint.reference_number}: {adverse_action.get_action_type_display()}",
                user=user,
                content_object=adverse_action,
                metadata={
                    "complaint_id": str(complaint.id),
                    "action_type": action_type,
                    "severity": severity,
                },
            )

            messages.success(request, _("Adverse action reported successfully."))
            return redirect("complaints:complaint_detail", pk=complaint_pk)

        except Exception as e:
            logger.error(f"Error creating adverse action: {str(e)}", exc_info=True)
            messages.error(request, f"Error creating adverse action: {str(e)}")

    context = {
        "complaint": complaint,
        "action_type_choices": ComplaintAdverseAction.ActionType.choices,
        "severity_choices": ComplaintAdverseAction.SeverityLevel.choices,
        "staff_list": Staff.objects.filter(hospital=complaint.hospital, is_active=True)
        if complaint.hospital
        else Staff.objects.filter(is_active=True),
    }

    return render(request, "complaints/adverse_action_form.html", context)


@login_required
def adverse_action_edit(request, pk):
    """
    Edit an existing adverse action.
    """
    adverse_action = get_object_or_404(ComplaintAdverseAction.objects.select_related("complaint"), pk=pk)
    complaint = adverse_action.complaint
    user = request.user

    # Check permission
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to edit this adverse action."))
        return redirect("complaints:complaint_detail", pk=complaint.id)

    if request.method == "POST":
        try:
            # Update fields
            adverse_action.action_type = request.POST.get("action_type", adverse_action.action_type)
            adverse_action.severity = request.POST.get("severity", adverse_action.severity)
            adverse_action.description = request.POST.get("description", adverse_action.description).strip()
            adverse_action.patient_impact = request.POST.get("patient_impact", adverse_action.patient_impact).strip()
            adverse_action.location = request.POST.get("location", adverse_action.location).strip()

            incident_date = request.POST.get("incident_date")
            if incident_date:
                adverse_action.incident_date = incident_date

            # Update involved staff
            involved_staff_ids = request.POST.getlist("involved_staff")
            if involved_staff_ids:
                adverse_action.involved_staff.set(involved_staff_ids)

            adverse_action.save()

            # Log audit
            AuditService.log_event(
                event_type="adverse_action_updated",
                description=f"Adverse action updated for complaint {complaint.reference_number}",
                user=user,
                content_object=adverse_action,
            )

            messages.success(request, _("Adverse action updated successfully."))
            return redirect("complaints:complaint_detail", pk=complaint.id)

        except Exception as e:
            logger.error(f"Error updating adverse action: {str(e)}", exc_info=True)
            messages.error(request, f"Error updating adverse action: {str(e)}")

    context = {
        "adverse_action": adverse_action,
        "complaint": complaint,
        "action_type_choices": ComplaintAdverseAction.ActionType.choices,
        "severity_choices": ComplaintAdverseAction.SeverityLevel.choices,
        "staff_list": Staff.objects.filter(hospital=complaint.hospital, is_active=True)
        if complaint.hospital
        else Staff.objects.filter(is_active=True),
        "selected_staff": list(adverse_action.involved_staff.values_list("id", flat=True)),
    }

    return render(request, "complaints/adverse_action_form.html", context)


@login_required
def adverse_action_update_status(request, pk):
    """
    Update the status of an adverse action (investigation, resolution).
    """
    adverse_action = get_object_or_404(ComplaintAdverseAction.objects.select_related("complaint"), pk=pk)
    complaint = adverse_action.complaint
    user = request.user

    # Check permission
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to update this adverse action."))
        return redirect("complaints:complaint_detail", pk=complaint.id)

    if request.method == "POST":
        try:
            new_status = request.POST.get("status")
            investigation_notes = request.POST.get("investigation_notes", "").strip()
            resolution = request.POST.get("resolution", "").strip()

            old_status = adverse_action.status
            adverse_action.status = new_status

            if investigation_notes:
                adverse_action.investigation_notes = investigation_notes

            if resolution:
                adverse_action.resolution = resolution

            # Handle status-specific updates
            if new_status == ComplaintAdverseAction.VerificationStatus.UNDER_INVESTIGATION:
                adverse_action.investigated_by = user
                adverse_action.investigated_at = timezone.now()

            elif new_status == ComplaintAdverseAction.VerificationStatus.RESOLVED:
                adverse_action.resolved_by = user
                adverse_action.resolved_at = timezone.now()

            elif new_status == ComplaintAdverseAction.VerificationStatus.VERIFIED:
                adverse_action.investigated_by = user
                adverse_action.investigated_at = timezone.now()

            adverse_action.save()

            # Create timeline entry
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="note",
                message=f"Adverse action status changed from {adverse_action.get_status_display()} to {dict(ComplaintAdverseAction.VerificationStatus.choices)[new_status]}",
                created_by=user,
            )

            # Log audit
            AuditService.log_event(
                event_type="adverse_action_status_changed",
                description=f"Adverse action status changed from {old_status} to {new_status} for complaint {complaint.reference_number}",
                user=user,
                content_object=adverse_action,
                metadata={
                    "old_status": old_status,
                    "new_status": new_status,
                },
            )

            messages.success(request, _("Adverse action status updated successfully."))

        except Exception as e:
            logger.error(f"Error updating adverse action status: {str(e)}", exc_info=True)
            messages.error(request, f"Error updating status: {str(e)}")

    return redirect("complaints:complaint_detail", pk=complaint.id)


@login_required
def adverse_action_escalate(request, pk):
    """
    Escalate an adverse action to management.
    """
    adverse_action = get_object_or_404(ComplaintAdverseAction.objects.select_related("complaint"), pk=pk)
    complaint = adverse_action.complaint
    user = request.user

    # Check permission
    if not can_manage_complaint(user, complaint):
        messages.error(request, _("You don't have permission to escalate this adverse action."))
        return redirect("complaints:complaint_detail", pk=complaint.id)

    if request.method == "POST":
        try:
            adverse_action.is_escalated = True
            adverse_action.escalated_at = timezone.now()
            adverse_action.save()

            # Create timeline entry
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="escalation",
                message=f"Adverse action escalated: {adverse_action.get_action_type_display()}",
                created_by=user,
            )

            # Log audit
            AuditService.log_event(
                event_type="adverse_action_escalated",
                description=f"Adverse action escalated for complaint {complaint.reference_number}",
                user=user,
                content_object=adverse_action,
            )

            messages.success(request, _("Adverse action escalated successfully."))

        except Exception as e:
            logger.error(f"Error escalating adverse action: {str(e)}", exc_info=True)
            messages.error(request, f"Error escalating: {str(e)}")

    return redirect("complaints:complaint_detail", pk=complaint.id)


@login_required
def adverse_action_delete(request, pk):
    """
    Delete an adverse action.
    """
    adverse_action = get_object_or_404(ComplaintAdverseAction.objects.select_related("complaint"), pk=pk)
    complaint = adverse_action.complaint
    user = request.user

    # Check permission - only PX Admin or Hospital Admin can delete
    if not (user.is_px_admin() or (user.is_hospital_admin() and user.hospital == complaint.hospital)):
        messages.error(request, _("You don't have permission to delete adverse actions."))
        return redirect("complaints:complaint_detail", pk=complaint.id)

    if request.method == "POST":
        try:
            complaint_pk = complaint.id

            # Log before deletion
            AuditService.log_event(
                event_type="adverse_action_deleted",
                description=f"Adverse action deleted from complaint {complaint.reference_number}: {adverse_action.get_action_type_display()}",
                user=user,
                metadata={
                    "complaint_id": str(complaint.id),
                    "action_type": adverse_action.action_type,
                    "description": adverse_action.description[:100],
                },
            )

            adverse_action.delete()
            messages.success(request, _("Adverse action deleted successfully."))
            return redirect("complaints:complaint_detail", pk=complaint_pk)

        except Exception as e:
            logger.error(f"Error deleting adverse action: {str(e)}", exc_info=True)
            messages.error(request, f"Error deleting: {str(e)}")

    return redirect("complaints:complaint_detail", pk=complaint.id)


def patient_complaint_portal(request, token):
    """Hospital selection page - first step of patient complaint flow."""
    from apps.complaints.models import PatientComplaintSession
    from apps.integrations.models import HISPatientVisit
    from django.http import Http404
    from django.db.models import Count

    try:
        session = PatientComplaintSession.objects.get(token=token, is_active=True)
    except PatientComplaintSession.DoesNotExist:
        raise Http404("Invalid or expired link")

    if session.is_expired():
        return render(request, "complaints/patient_complaint_expired.html")

    patient = session.patient

    hospitals = (
        HISPatientVisit.objects.filter(patient=patient)
        .values("hospital__id", "hospital__name", "hospital__name_ar")
        .annotate(visit_count=Count("id"))
        .order_by("-visit_count")
    )

    context = {
        "patient": patient,
        "session": session,
        "hospitals": hospitals,
    }
    return render(request, "complaints/patient_complaint_portal.html", context)


def patient_complaint_hospital_visits(request, token, hospital_id):
    """Visit list for a selected hospital - second step."""
    from apps.complaints.models import PatientComplaintSession
    from apps.integrations.models import HISPatientVisit
    from django.http import Http404

    try:
        session = PatientComplaintSession.objects.get(token=token, is_active=True)
    except PatientComplaintSession.DoesNotExist:
        raise Http404("Invalid or expired link")

    if session.is_expired():
        return render(request, "complaints/patient_complaint_expired.html")

    patient = session.patient

    visits = HISPatientVisit.objects.filter(patient=patient, hospital_id=hospital_id).order_by("-admit_date")[:50]

    hospital = None
    if visits:
        hospital = visits[0].hospital

    context = {
        "patient": patient,
        "session": session,
        "hospital": hospital,
        "visits": visits,
    }
    return render(request, "complaints/patient_complaint_visits.html", context)


def patient_complaint_visit_form(request, token, visit_id):
    """Complaint form for a selected visit - third step."""
    from apps.complaints.models import PatientComplaintSession, Complaint
    from apps.integrations.models import HISPatientVisit
    from django.http import Http404

    try:
        session = PatientComplaintSession.objects.get(token=token, is_active=True)
    except PatientComplaintSession.DoesNotExist:
        raise Http404("Invalid or expired link")

    if session.is_expired():
        return render(request, "complaints/patient_complaint_expired.html")

    patient = session.patient
    visit = get_object_or_404(HISPatientVisit, id=visit_id, patient=patient)

    if request.method == "POST":
        description = request.POST.get("description", "").strip()
        if not description:
            return render(
                request,
                "complaints/patient_complaint_visit_form.html",
                {
                    "patient": patient,
                    "session": session,
                    "visit": visit,
                    "error": "Please enter a description of your complaint.",
                },
            )

        title = f"Complaint - {visit.patient_type} Visit ({visit.admission_id})"
        complaint = Complaint.objects.create(
            patient=patient,
            hospital=visit.hospital,
            title=title,
            description=description,
            encounter_id=visit.admission_id,
            complaint_source_type="internal",
            priority="medium",
            severity="medium",
            status="open",
            metadata={
                "session_id": str(session.id),
                "visit_id": str(visit.id),
                "visit_type": visit.patient_type,
                "submitted_via": "patient_link",
            },
        )

        session.is_active = False
        session.save()

        return render(
            request,
            "complaints/patient_complaint_success.html",
            {
                "complaint": complaint,
                "patient": patient,
            },
        )

    context = {
        "patient": patient,
        "session": session,
        "visit": visit,
    }
    return render(request, "complaints/patient_complaint_visit_form.html", context)


# ==================== Government Ticket Views ====================


@login_required
def government_ticket_list(request):
    """List government tickets with filters"""
    # Permission check: PX Admin or PX Employee only
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to view government tickets."))
        return redirect("dashboard:index")

    # Base queryset
    queryset = GovernmentTicket.objects.select_related("source", "department", "assigned_to").all()

    # Filters
    source_filter = request.GET.get("source")
    status_filter = request.GET.get("status")
    department_filter = request.GET.get("department")
    search_query = request.GET.get("q", "").strip()
    converted_filter = request.GET.get("converted")

    if source_filter:
        queryset = queryset.filter(source_id=source_filter)
    if status_filter:
        queryset = queryset.filter(status=status_filter)
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)
    if converted_filter:
        is_converted = converted_filter == "yes"
        queryset = queryset.filter(converted_to_complaint=is_converted)
    if search_query:
        queryset = queryset.filter(
            Q(ticket_number__icontains=search_query)
            | Q(complainant_name__icontains=search_query)
            | Q(national_id__icontains=search_query)
            | Q(content__icontains=search_query)
        )

    # Pagination
    paginator = Paginator(queryset.order_by("-received_date"), 25)
    page_number = request.GET.get("page")
    page_obj = paginator.get_page(page_number)

    # Context
    context = {
        "page_obj": page_obj,
        "sources": PXSource.objects.filter(source_type="government", is_active=True),
        "departments": Department.objects.filter(status="active"),
        "status_choices": GovernmentTicket.TicketStatus.choices,
        "source_filter": source_filter,
        "status_filter": status_filter,
        "department_filter": department_filter,
        "converted_filter": converted_filter,
        "search_query": search_query,
        "total_count": queryset.count(),
    }

    return render(request, "complaints/government_ticket_list.html", context)


@login_required
def government_ticket_detail(request, pk):
    """Detail view for a government ticket"""
    ticket = get_object_or_404(
        GovernmentTicket.objects.select_related("source", "department", "assigned_to", "complaint"),
        pk=pk,
    )

    # Permission check
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to view this ticket."))
        return redirect("complaints:government_ticket_list")

    context = {
        "ticket": ticket,
    }
    return render(request, "complaints/government_ticket_detail.html", context)


@login_required
def government_ticket_create(request):
    """Create a new government ticket"""
    # Permission check
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to create government tickets."))
        return redirect("complaints:government_ticket_list")

    if request.method == "POST":
        form = GovernmentTicketForm(request.POST)
        if form.is_valid():
            ticket = form.save()
            messages.success(request, _("Government ticket created successfully."))
            return redirect("complaints:government_ticket_detail", pk=ticket.pk)
    else:
        form = GovernmentTicketForm()

    context = {
        "form": form,
        "is_create": True,
    }
    return render(request, "complaints/government_ticket_form.html", context)


@login_required
def government_ticket_update(request, pk):
    """Update an existing government ticket"""
    ticket = get_object_or_404(GovernmentTicket, pk=pk)

    # Permission check
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to update this ticket."))
        return redirect("complaints:government_ticket_list")

    if request.method == "POST":
        form = GovernmentTicketForm(request.POST, instance=ticket)
        if form.is_valid():
            form.save()
            messages.success(request, _("Government ticket updated successfully."))
            return redirect("complaints:government_ticket_detail", pk=ticket.pk)
    else:
        form = GovernmentTicketForm(instance=ticket)

    context = {
        "form": form,
        "ticket": ticket,
        "is_create": False,
    }
    return render(request, "complaints/government_ticket_form.html", context)


@login_required
def convert_to_complaint(request, pk):
    """Convert a government ticket to a complaint"""
    ticket = get_object_or_404(GovernmentTicket, pk=pk)

    # Permission check
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to convert this ticket."))
        return redirect("complaints:government_ticket_list")

    if ticket.converted_to_complaint:
        messages.warning(request, _("This ticket has already been converted to a complaint."))
        return redirect("complaints:government_ticket_detail", pk=ticket.pk)

    # Build redirect URL to complaint create form with pre-filled data
    import urllib.parse

    params = {
        "source": ticket.source_id,
        "complaint_source_type": "external" if ticket.source.code.upper() in ("MOH", "CCHI") else "internal",
        "title": f"[{ticket.ticket_number}] {ticket.classification or 'Government Ticket'}",
        "description": ticket.content,
        "main_section": ticket.main_section_id or "",
        "subsection": ticket.subsection_id or "",
        "patient_name": ticket.complainant_name,
        "contact_phone": ticket.contact_number or "",
        "moh_reference": ticket.ticket_number if "moh" in ticket.source.code.lower() else "",
        "chi_reference": ticket.ticket_number if "chi" in ticket.source.code.lower() else "",
    }

    query_string = urllib.parse.urlencode({k: v for k, v in params.items() if v})
    url = f"{reverse('complaints:complaint_create')}?{query_string}"

    return redirect(url)


@login_required
def government_ticket_import(request):
    """Import government tickets from Excel file"""
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to import government tickets."))
        return redirect("complaints:government_ticket_list")

    preview_data = None
    import_count = 0
    error_count = 0
    errors = []

    if request.method == "POST":
        action = request.POST.get("action")

        if action == "preview":
            # Handle file upload and show preview
            file = request.FILES.get("file")
            if not file:
                messages.error(request, _("Please select a file to import."))
                return redirect("complaints:government_ticket_import")

            try:
                import pandas as pd

                # Read Excel file
                df = pd.read_excel(file, header=1)  # Header is on row 2 (index 1)

                # Column mapping (Arabic to English)
                column_map = {
                    "رقم التذكرة": "ticket_number",
                    "اسم المشتكي": "complainant_name",
                    "رقم الهوية": "national_id",
                    "رقم التواصل": "contact_number",
                    "الموقع": "location",
                    "القسم الرئيسي": "main_section",
                    "القسم الفرعي": "subsection",
                    "تاريخ إنشاء التذكرة": "received_date",
                    "وقت إنشاء التذكرة": "received_time",
                    "تصنيف الشكوى": "classification",
                    "محتوى الشكوى": "content",
                    "حالة الشكوى": "status",
                    "اسم الموظف": "assigned_to",
                }

                # Rename columns
                df.rename(columns=column_map, inplace=True)

                # Take first 5 rows for preview
                preview_df = df.head(5)
                preview_data = preview_df.fillna("").to_dict("records")

                # Store full dataframe in session for actual import
                request.session["import_df"] = df.to_json()
                request.session["import_filename"] = file.name

                messages.info(request, _("Preview ready. Review the data below and confirm to import."))

            except Exception as e:
                messages.error(request, f"Error reading file: {str(e)}")
                return redirect("complaints:government_ticket_import")

        elif action == "import":
            # Handle actual import
            json_data = request.session.get("import_df")
            if not json_data:
                messages.error(request, _("No data to import. Please upload a file first."))
                return redirect("complaints:government_ticket_import")

            try:
                import pandas as pd
                from apps.px_sources.models import PXSource
                from apps.organizations.models import LegacyLocation, LegacyMainSection, LegacySubSection
                from apps.accounts.models import User

                df = pd.read_json(json_data)

                # Get MOH source (default for import)
                moh_source = PXSource.objects.filter(code__icontains="MOH", source_type="government").first()
                if not moh_source:
                    messages.error(request, _("MOH source not found in system. Please configure it first."))
                    return redirect("complaints:government_ticket_import")

                # Status mapping
                status_map = {
                    "مفتوحة": "pending",
                    "قيد المعالجة": "in_progress",
                    "تم الحل": "resolved",
                    "مغلقة": "closed",
                    "pending": "pending",
                    "in_progress": "in_progress",
                    "resolved": "resolved",
                    "closed": "closed",
                }

                for idx, row in df.iterrows():
                    try:
                        # Skip if ticket number is missing
                        if pd.isna(row.get("ticket_number")):
                            errors.append(f"Row {idx + 1}: Missing ticket number")
                            error_count += 1
                            continue

                        # Check for duplicate
                        if GovernmentTicket.objects.filter(ticket_number=str(row["ticket_number"])).exists():
                            errors.append(f"Row {idx + 1}: Ticket {row['ticket_number']} already exists")
                            error_count += 1
                            continue

                        # Parse received date
                        received_date = None
                        if pd.notna(row.get("received_date")):
                            received_date = pd.to_datetime(row["received_date"])
                            if pd.notna(row.get("received_time")):
                                time_part = pd.to_datetime(row["received_time"])
                                received_date = received_date.replace(
                                    hour=time_part.hour,
                                    minute=time_part.minute,
                                    second=time_part.second,
                                )
                        else:
                            received_date = timezone.now()

                        # Lookup location
                        ticket_location = None
                        if pd.notna(row.get("location")):
                            loc_name = str(row["location"]).strip()
                            ticket_location = LegacyLocation.objects.filter(
                                models.Q(name_en__icontains=loc_name) | models.Q(name_ar__icontains=loc_name)
                            ).first()

                        # Lookup main section
                        ticket_main_section = None
                        if pd.notna(row.get("main_section")):
                            sec_name = str(row["main_section"]).strip()
                            ticket_main_section = LegacyMainSection.objects.filter(
                                models.Q(name_en__icontains=sec_name) | models.Q(name_ar__icontains=sec_name)
                            ).first()

                        # Lookup subsection
                        ticket_subsection = None
                        if pd.notna(row.get("subsection")):
                            sub_name = str(row["subsection"]).strip()
                            qs = LegacySubSection.objects.filter(
                                models.Q(name_en__icontains=sub_name) | models.Q(name_ar__icontains=sub_name)
                            )
                            if ticket_location:
                                qs = qs.filter(location=ticket_location)
                            if ticket_main_section:
                                qs = qs.filter(main_section=ticket_main_section)
                            ticket_subsection = qs.first()

                        # Lookup assigned user
                        assigned_user = None
                        if pd.notna(row.get("assigned_to")):
                            assigned_user = User.objects.filter(
                                models.Q(first_name__icontains=str(row["assigned_to"]).strip()) |
                                models.Q(last_name__icontains=str(row["assigned_to"]).strip()) |
                                models.Q(get_full_name__icontains=str(row["assigned_to"]).strip())
                            ).first()

                        # Map status
                        status = "pending"
                        if pd.notna(row.get("status")):
                            status = status_map.get(str(row["status"]).strip().lower(), "pending")

                        # Create ticket
                        GovernmentTicket.objects.create(
                            source=moh_source,
                            ticket_number=str(row["ticket_number"]).strip(),
                            complainant_name=str(row.get("complainant_name", "")).strip() or "Unknown",
                            national_id=str(row.get("national_id", "")).strip() if pd.notna(row.get("national_id")) else "",
                            contact_number=str(row.get("contact_number", "")).strip() if pd.notna(row.get("contact_number")) else "",
                            legacy_location=ticket_location,
                            legacy_main_section=ticket_main_section,
                            legacy_subsection=ticket_subsection,
                            received_date=received_date,
                            classification=str(row.get("classification", "")).strip() if pd.notna(row.get("classification")) else "",
                            content=str(row.get("content", "")).strip() if pd.notna(row.get("content")) else "",
                            status=status,
                            assigned_to=assigned_user,
                        )
                        import_count += 1

                    except Exception as e:
                        errors.append(f"Row {idx + 1}: {str(e)}")
                        error_count += 1

                # Clear session data
                del request.session["import_df"]
                del request.session["import_filename"]

                if import_count > 0:
                    messages.success(request, f"Successfully imported {import_count} tickets.")
                if error_count > 0:
                    messages.warning(request, f"{error_count} rows had errors.")

                return redirect("complaints:government_ticket_list")

            except Exception as e:
                messages.error(request, f"Import failed: {str(e)}")
                return redirect("complaints:government_ticket_import")

    context = {
        "preview_data": preview_data,
        "errors": errors,
        "import_count": import_count,
        "error_count": error_count,
    }
    return render(request, "complaints/government_ticket_import.html", context)


@login_required
def government_ticket_export(request):
    """Export government tickets to Excel"""
    if not (request.user.is_px_admin() or request.user.is_px_management()):
        messages.error(request, _("You don't have permission to export government tickets."))
        return redirect("complaints:government_ticket_list")

    import pandas as pd
    from django.http import HttpResponse

    # Get filtered queryset (same filters as list view)
    queryset = GovernmentTicket.objects.select_related("source", "department", "assigned_to").all()

    source_filter = request.GET.get("source")
    status_filter = request.GET.get("status")
    department_filter = request.GET.get("department")
    search_query = request.GET.get("q", "").strip()

    if source_filter:
        queryset = queryset.filter(source_id=source_filter)
    if status_filter:
        queryset = queryset.filter(status=status_filter)
    if department_filter:
        queryset = queryset.filter(department_id=department_filter)
    if search_query:
        queryset = queryset.filter(
            models.Q(ticket_number__icontains=search_query)
            | models.Q(complainant_name__icontains=search_query)
            | models.Q(national_id__icontains=search_query)
            | models.Q(content__icontains=search_query)
        )

    # Prepare data
    data = []
    for ticket in queryset.order_by("-received_date"):
        data.append({
            "رقم التذكرة": ticket.ticket_number,
            "اسم المشتكي": ticket.complainant_name,
            "رقم الهوية": ticket.national_id or "",
            "رقم التواصل": ticket.contact_number or "",
            "القسم": ticket.department.name_en if ticket.department else "",
            "نوع الموقع": ticket.department.location_type if ticket.department and ticket.department.location_type else "",
            "تاريخ إنشاء التذكرة": ticket.received_date.strftime("%Y-%m-%d") if ticket.received_date else "",
            "وقت إنشاء التذكرة": ticket.received_date.strftime("%H:%M:%S") if ticket.received_date else "",
            "تصنيف الشكوى": ticket.classification or "",
            "محتوى الشكوى": ticket.content or "",
            "حالة الشكوى": ticket.get_status_display(),
            "اسم الموظف": ticket.assigned_to.get_full_name() if ticket.assigned_to else "",
            "تم التحويل": "نعم" if ticket.converted_to_complaint else "لا",
        })

    df = pd.DataFrame(data)

    # Create response
    response = HttpResponse(content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
    response["Content-Disposition"] = 'attachment; filename="government_tickets.xlsx"'

    with pd.ExcelWriter(response, engine="openpyxl") as writer:
        df.to_excel(writer, index=False, sheet_name="Government Tickets")

    return response


@login_required
@require_http_methods(["POST"])
def complaint_soft_delete(request, pk):
    complaint = get_object_or_404(Complaint, pk=pk)
    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        return HttpResponseForbidden(_("You don't have permission to delete complaints."))
    complaint.soft_delete(user=request.user)
    messages.success(request, _("Complaint moved to trash."))
    return redirect("complaints:complaint_list")


@login_required
@require_http_methods(["POST"])
def complaint_restore(request, pk):
    complaint = get_object_or_404(Complaint.all_objects, pk=pk, is_deleted=True)
    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        return HttpResponseForbidden(_("You don't have permission to restore complaints."))
    complaint.restore()
    messages.success(request, _("Complaint restored successfully."))
    return redirect("config:deleted_items")


@login_required
@require_http_methods(["POST"])
def inquiry_restore(request, pk):
    inquiry = get_object_or_404(Inquiry.all_objects, pk=pk, is_deleted=True)
    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        return HttpResponseForbidden(_("You don't have permission to restore inquiries."))
    inquiry.restore()
    messages.success(request, _("Inquiry restored successfully."))
    return redirect("config:deleted_items")


@login_required
def trash_list(request):
    if not (request.user.is_px_admin() or request.user.is_hospital_admin()):
        return HttpResponseForbidden(_("You don't have permission to view trash."))

    deleted_complaints = Complaint.all_objects.filter(is_deleted=True).select_related(
        "hospital", "department", "created_by"
    ).order_by("-deleted_at")

    deleted_observations = Observation.all_objects.filter(is_deleted=True).select_related(
        "hospital", "assigned_department"
    ).order_by("-deleted_at")

    return render(request, "complaints/trash_list.html", {
        "deleted_complaints": deleted_complaints,
        "deleted_observations": deleted_observations,
    })
