import logging

from datetime import timedelta

from django.utils import timezone

from apps.core.services import AuditService
from apps.notifications.services import NotificationService, get_email_header_html
from apps.organizations.models import Department
from apps.complaints.models import Complaint, ComplaintExplanation, ComplaintStatus, ComplaintUpdate

logger = logging.getLogger(__name__)


def _get_explanation_sla_config(hospital):
    """Get explanation SLA configuration for a hospital."""
    from apps.complaints.models import ExplanationSLAConfig
    try:
        return ExplanationSLAConfig.objects.get(hospital=hospital, is_active=True)
    except ExplanationSLAConfig.DoesNotExist:
        return None


class ComplaintServiceError(Exception):
    pass


class ComplaintService:
    @staticmethod
    def get_escalation_target(complaint, staff=None):
        """
        Resolve an escalation target using a fallback chain.

        For explanation escalation (staff provided):
            staff.report_to -> staff.department.manager ->
            complaint.department.manager -> hospital admins & PX staff

        For complaint-level escalation (no staff):
            complaint.department.manager -> hospital admins & PX staff

        Args:
            complaint: Complaint instance
            staff: Optional Staff instance (the person being escalated from)

        Returns:
            tuple: (target_user, fallback_path) where target_user is a User
                   (or None if no target found) and fallback_path describes
                   which step succeeded.
        """
        from apps.complaints.tasks import get_hospital_admins_and_staff

        if staff:
            if staff.report_to and staff.report_to.user and staff.report_to.user.is_active:
                return staff.report_to.user, "staff.report_to"

            staff_dept = getattr(staff, "department", None)
            if staff_dept and staff_dept.manager and staff_dept.manager.is_active:
                return staff_dept.manager, "staff.department.manager"

        if complaint.department and complaint.department.manager and complaint.department.manager.is_active:
            if not staff or (staff and getattr(staff, "department", None) != complaint.department):
                return complaint.department.manager, "complaint.department.manager"

        hospital = complaint.hospital
        if hospital:
            fallback = get_hospital_admins_and_staff(hospital).first()
            if fallback:
                return fallback, "hospital_admins_staff"

        return None, "no_target_found"

    @staticmethod
    def can_manage(user, complaint):
        if user.is_px_admin():
            return True
        if user.is_hospital_admin() and user.hospital == complaint.hospital:
            return True
        if user.is_px_management() and user.hospital == complaint.hospital:
            return True
        if user.is_px_employee() and user.hospital == complaint.hospital:
            return True
        if user.is_department_manager() and user.department == complaint.department:
            return True
        if complaint.assigned_to and complaint.assigned_to == user:
            return True
        if complaint.involved_departments.filter(id=user.department_id).exists() if user.department_id else False:
            return True
        return False

    @staticmethod
    def can_activate(user, complaint):
        return (
            user.is_px_admin()
            or user.is_hospital_admin()
            or user.is_px_management()
            or (user.is_department_manager() and complaint.department == user.department)
            or complaint.hospital == user.hospital
        )

    @staticmethod
    def activate(complaint, user, request=None):
        if not complaint.is_active_status:
            raise ComplaintServiceError(
                f"Cannot activate complaint with status '{complaint.get_status_display()}'. "
                "Complaint must be Open, In Progress, or Partially Resolved."
            )

        if not ComplaintService.can_activate(user, complaint):
            raise ComplaintServiceError("You don't have permission to activate this complaint.")

        if complaint.assigned_to == user:
            raise ComplaintServiceError("This complaint is already assigned to you.")

        previous_assignee = complaint.assigned_to
        old_status = complaint.status

        complaint.assigned_to = user
        complaint.assigned_at = timezone.now()

        if complaint.status == ComplaintStatus.OPEN:
            complaint.status = ComplaintStatus.IN_PROGRESS
            complaint.activated_at = timezone.now()
            complaint.save(update_fields=["assigned_to", "assigned_at", "status", "activated_at"])
        else:
            complaint.save(update_fields=["assigned_to", "assigned_at"])

        assign_message = f"Complaint activated and assigned to {user.get_full_name()}"
        if previous_assignee:
            assign_message += f" (reassigned from {previous_assignee.get_full_name()})"

        roles_display = ", ".join(user.get_role_names())

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="assignment",
            message=f"{assign_message} ({roles_display})",
            created_by=user,
            metadata={
                "old_assignee_id": str(previous_assignee.id) if previous_assignee else None,
                "new_assignee_id": str(user.id),
                "assignee_roles": user.get_role_names(),
                "old_status": old_status,
                "new_status": complaint.status,
                "activated_by_current_user": True,
            },
        )

        metadata = {
            "old_assignee_id": str(previous_assignee.id) if previous_assignee else None,
            "new_assignee_id": str(user.id),
            "old_status": old_status,
            "new_status": complaint.status,
        }

        if request:
            AuditService.log_from_request(
                event_type="complaint_activated",
                description=f"Complaint activated by {user.get_full_name()}",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="complaint_activated",
                description=f"Complaint activated by {user.get_full_name()}",
                user=user,
                content_object=complaint,
                metadata=metadata,
            )

        return {
            "success": True,
            "complaint": complaint,
            "old_assignee": previous_assignee,
            "old_status": old_status,
        }

    @staticmethod
    def assign(complaint, target_user, assigned_by, request=None):
        if not complaint.is_active_status and complaint.status not in (
            ComplaintStatus.RESOLVED,
            ComplaintStatus.CLOSED,
            ComplaintStatus.CANCELLED,
        ):
            raise ComplaintServiceError(
                f"Cannot assign complaint with status '{complaint.get_status_display()}'. "
                "Complaint must be in an active or terminal status."
            )

        if not (
            assigned_by.is_px_admin()
            or assigned_by.is_hospital_admin()
            or complaint.assigned_to == assigned_by
        ):
            raise ComplaintServiceError("You don't have permission to assign complaints.")

        old_assignee = complaint.assigned_to
        old_status = complaint.status

        complaint.assigned_to = target_user
        complaint.assigned_at = timezone.now()

        reopened = False
        if old_status in (ComplaintStatus.RESOLVED, ComplaintStatus.CLOSED, ComplaintStatus.CANCELLED):
            complaint.status = ComplaintStatus.IN_PROGRESS
            complaint.resolved_at = None
            complaint.resolved_by = None
            complaint.closed_at = None
            complaint.closed_by = None
            complaint.reopened_at = timezone.now()
            complaint.reopened_by = assigned_by
            reopened = True
            complaint.save(update_fields=["assigned_to", "assigned_at", "status", "resolved_at", "resolved_by", "closed_at", "closed_by", "reopened_at", "reopened_by"])
        else:
            complaint.save(update_fields=["assigned_to", "assigned_at"])

        roles_display = ", ".join(target_user.get_role_names())

        msg = f"Assigned to {target_user.get_full_name()} ({roles_display})"
        if old_assignee:
            msg += f" (reassigned from {old_assignee.get_full_name()})"
        if reopened:
            msg = f"Reopened and {msg}"

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="assignment",
            message=msg,
            created_by=assigned_by,
            metadata={
                "old_assignee_id": str(old_assignee.id) if old_assignee else None,
                "new_assignee_id": str(target_user.id),
                "assignee_roles": target_user.get_role_names(),
                "reopened": reopened,
                "old_status": old_status,
            },
        )

        metadata = {
            "old_assignee_id": str(old_assignee.id) if old_assignee else None,
            "new_assignee_id": str(target_user.id),
        }

        if request:
            AuditService.log_from_request(
                event_type="assignment",
                description=f"Complaint assigned to {target_user.get_full_name()} ({roles_display})",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="assignment",
                description=f"Complaint assigned to {target_user.get_full_name()}",
                user=assigned_by,
                content_object=complaint,
                metadata=metadata,
            )

        return {
            "success": True,
            "complaint": complaint,
            "old_assignee": old_assignee,
        }

    # Valid status transitions for lifecycle enforcement
    VALID_STATUS_TRANSITIONS = {
        "open": ["in_progress", "cancelled"],
        "in_progress": ["partially_resolved", "resolved", "cancelled", "pending_external", "ovr_pending"],
        "partially_resolved": ["resolved", "in_progress", "cancelled", "pending_external"],
        "resolved": ["closed", "in_progress"],
        "closed": ["in_progress"],
        "cancelled": ["open", "in_progress"],
        "pending_external": ["resolved", "in_progress", "cancelled", "closed"],
        "ovr_pending": ["in_progress", "resolved", "cancelled"],
    }

    @staticmethod
    def reopen(complaint, reopened_by, request=None, *, note=""):
        if complaint.status not in (
            ComplaintStatus.RESOLVED,
            ComplaintStatus.CLOSED,
            ComplaintStatus.CANCELLED,
        ):
            raise ComplaintServiceError("Only resolved, closed, or cancelled complaints can be reopened.")

        old_status = complaint.status

        new_complaint = Complaint.objects.create(
            patient=complaint.patient,
            contact_name=complaint.contact_name,
            contact_phone=complaint.contact_phone,
            contact_email=complaint.contact_email,
            hospital=complaint.hospital,
            department=complaint.department,
            staff=complaint.staff,
            title=complaint.title,
            description=complaint.description,
            domain=complaint.domain,
            category=complaint.category,
            subcategory=complaint.subcategory,
            classification=complaint.classification,
            subcategory_obj=complaint.subcategory_obj,
            classification_obj=complaint.classification_obj,
            complaint_type=complaint.complaint_type,
            complaint_source_type=complaint.complaint_source_type,
            priority=complaint.priority,
            severity=complaint.severity,
            source=complaint.source,
            status=ComplaintStatus.OPEN,
            reopened_from=complaint,
            reopened_at=timezone.now(),
            reopened_by=reopened_by,
        )

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="status_change",
            message=note or f"Complaint reopened as new complaint #{new_complaint.reference_number or new_complaint.id}",
            created_by=reopened_by,
            old_status=old_status,
            new_status=old_status,
            metadata={"reopened_as_new": True, "new_complaint_id": str(new_complaint.id)},
        )

        ComplaintUpdate.objects.create(
            complaint=new_complaint,
            update_type="status_change",
            message=f"Created as reopen of complaint #{complaint.reference_number or complaint.id}",
            created_by=reopened_by,
            old_status="",
            new_status=ComplaintStatus.OPEN,
            metadata={"reopened_from": str(complaint.id)},
        )

        metadata = {
            "old_status": old_status,
            "new_complaint_id": str(new_complaint.id),
            "original_complaint_id": str(complaint.id),
        }
        if request:
            AuditService.log_from_request(
                event_type="complaint_reopened",
                description=f"Complaint #{complaint.reference_number or complaint.id} reopened as new complaint by {reopened_by.get_full_name()}",
                request=request,
                content_object=new_complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="complaint_reopened",
                description=f"Complaint #{complaint.reference_number or complaint.id} reopened as new complaint by {reopened_by.get_full_name()}",
                user=reopened_by,
                content_object=new_complaint,
                metadata=metadata,
            )

        return {"success": True, "complaint": new_complaint, "old_status": old_status, "original_complaint": complaint}

    @staticmethod
    def change_status(
        complaint,
        new_status,
        changed_by,
        request=None,
        *,
        note="",
        resolution="",
        resolution_outcome="",
        resolution_outcome_other="",
        resolution_category="",
    ):
        if not (changed_by.is_px_admin() or changed_by.is_hospital_admin()):
            raise ComplaintServiceError("You don't have permission to change complaint status.")

        if not new_status:
            raise ComplaintServiceError("Please select a status.")

        old_status = complaint.status

        # Enforce valid status transitions
        valid_next = ComplaintService.VALID_STATUS_TRANSITIONS.get(old_status, [])
        if new_status not in valid_next and not changed_by.is_px_admin():
            raise ComplaintServiceError(
                f"Invalid status transition from '{old_status}' to '{new_status}'. "
                f"Allowed transitions: {', '.join(valid_next)}"
            )
        complaint.status = new_status

        if new_status == ComplaintStatus.RESOLVED or new_status == "resolved":
            if complaint.was_pending_external and complaint.pending_external_set_at:
                complaint.resolved_at = complaint.pending_external_set_at
            else:
                complaint.resolved_at = timezone.now()
            complaint.resolved_by = changed_by
            if resolution:
                complaint.resolution = resolution
                complaint.resolution_sent_at = timezone.now()
            if resolution_category:
                complaint.resolution_category = resolution_category
            if resolution_outcome:
                complaint.resolution_outcome = resolution_outcome
                if resolution_outcome == "other" and resolution_outcome_other:
                    complaint.resolution_outcome_other = resolution_outcome_other

        elif new_status == ComplaintStatus.CLOSED or new_status == "closed":
            complaint.closed_at = timezone.now()
            complaint.closed_by = changed_by
            from apps.complaints.tasks import send_complaint_resolution_survey

            send_complaint_resolution_survey.delay(str(complaint.id))

        elif new_status == ComplaintStatus.PENDING_EXTERNAL or new_status == "pending_external":
            complaint.pending_external_set_at = timezone.now()
            complaint.was_pending_external = True

        elif new_status == ComplaintStatus.CANCELLED or new_status == "cancelled":
            complaint.cancelled_at = timezone.now()
            complaint.cancelled_by = changed_by

        elif new_status == ComplaintStatus.PARTIALLY_RESOLVED or new_status == "partially_resolved":
            complaint.partially_resolved_at = timezone.now()
            complaint.partially_resolved_by = changed_by

        complaint.save()

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="status_change",
            message=note or f"Status changed from {old_status} to {new_status}",
            created_by=changed_by,
            old_status=old_status,
            new_status=new_status,
            metadata={
                "resolution_text": resolution if resolution else None,
                "resolution_category": resolution_category if resolution_category else None,
            },
        )

        metadata = {
            "old_status": old_status,
            "new_status": new_status,
            "resolution_category": resolution_category if resolution_category else None,
        }

        if request:
            AuditService.log_from_request(
                event_type="status_change",
                description=f"Complaint status changed from {old_status} to {new_status}",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="status_change",
                description=f"Complaint status changed from {old_status} to {new_status}",
                user=changed_by,
                content_object=complaint,
                metadata=metadata,
            )

        return {
            "success": True,
            "complaint": complaint,
            "old_status": old_status,
            "new_status": new_status,
        }

    @staticmethod
    def add_note(complaint, message, created_by, request=None):
        if not complaint.is_active_status:
            raise ComplaintServiceError(
                f"Cannot add notes to complaint with status '{complaint.get_status_display()}'. "
                "Complaint must be Open, In Progress, or Partially Resolved."
            )

        if not message:
            raise ComplaintServiceError("Please enter a note.")

        update = ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="note",
            message=message,
            created_by=created_by,
        )

        metadata = {
            "note_id": str(update.id),
        }

        if request:
            AuditService.log_from_request(
                event_type="note_added",
                description=f"Note added to complaint",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="note_added",
                description=f"Note added to complaint",
                user=created_by,
                content_object=complaint,
                metadata=metadata,
            )

        return update

    @staticmethod
    def change_department(complaint, department, changed_by, request=None):
        if not complaint.is_active_status:
            raise ComplaintServiceError(
                f"Cannot change department for complaint with status '{complaint.get_status_display()}'. "
                "Complaint must be Open, In Progress, or Partially Resolved."
            )

        if not (changed_by.is_px_admin() or changed_by.is_hospital_admin()):
            raise ComplaintServiceError("You don't have permission to change complaint department.")

        if department.hospital != complaint.hospital:
            raise ComplaintServiceError("Department does not belong to this complaint's hospital.")

        old_department = complaint.department
        complaint.department = department
        complaint.save(update_fields=["department"])

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="assignment",
            message=f"Department changed to {department.name}",
            created_by=changed_by,
            metadata={
                "old_department_id": str(old_department.id) if old_department else None,
                "new_department_id": str(department.id),
            },
        )

        metadata = {
            "old_department_id": str(old_department.id) if old_department else None,
            "new_department_id": str(department.id),
        }

        if request:
            AuditService.log_from_request(
                event_type="department_change",
                description=f"Complaint department changed to {department.name}",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="department_change",
                description=f"Complaint department changed to {department.name}",
                user=changed_by,
                content_object=complaint,
                metadata=metadata,
            )

        return {
            "success": True,
            "complaint": complaint,
            "old_department": old_department,
        }

    @staticmethod
    def send_to_department(
        complaint,
        department_groups,
        selected_dept_ids,
        request_message,
        requested_by,
        domain,
        request=None,
        contact_person_map=None,
    ):
        import secrets

        if not complaint.is_active_status:
            raise ComplaintServiceError(
                f"Cannot send complaint to department with status '{complaint.get_status_display()}'. "
                "Complaint must be Open, In Progress, or Partially Resolved."
            )

        champion_count = 0
        skipped_no_email = 0
        results = []

        for dept_id, dept_info in department_groups.items():
            if dept_id not in selected_dept_ids:
                continue

            champion = None
            champion_email = None
            champion_display = None

            if contact_person_map and dept_id in contact_person_map:
                cp_id = contact_person_map[dept_id]
                dept_obj = Department.objects.filter(id=dept_id).first()
                if dept_obj:
                    cinfo = dept_obj.is_valid_contact_person(cp_id)
                    if cinfo:
                        champion = cinfo["staff"]
                        champion_email = cinfo["email"]
                        champion_display = f"{cinfo['name']} ({cinfo['role_label']})"

            if not champion or not champion_email:
                champion = dept_info.get("champion")
                champion_email = dept_info.get("champion_email")

            if not champion or not champion_email:
                dept_obj = Department.objects.filter(id=dept_id).select_related("manager", "manager__staff_profile").first()
                if dept_obj and dept_obj.manager:
                    manager_staff = getattr(dept_obj.manager, 'staff_profile', None)
                    if manager_staff:
                        champion = manager_staff
                        champion_email = manager_staff.email or dept_obj.manager.email
                if not champion:
                    skipped_no_email += 1
                    continue

            staff_names = [s["staff_name"] for s in dept_info["staff_list"]]

            champion_token = secrets.token_urlsafe(32)

            explanation, created = ComplaintExplanation.objects.update_or_create(
                complaint=complaint,
                staff=champion,
                defaults={
                    "token": champion_token,
                    "is_used": False,
                    "requested_by": requested_by,
                    "request_message": request_message,
                    "email_sent_at": timezone.now(),
                    "submitted_via": "email_link",
                },
            )

            champion_link = f"https://{domain}/complaints/{complaint.id}/explain/{champion_token}/"
            champion_subject = f"Explanation Request - Complaint #{complaint.reference_number}"
            champion_display = champion_display or dept_info.get("champion_name", str(champion))

            staff_list_text = "\n".join(f"  - {n}" for n in staff_names)

            champion_email_body = f"""Dear {champion.get_full_name()},

We are requesting your assistance in gathering explanations for a complaint involving staff from {dept_info['department_name']}.

INVOLVED STAFF FROM YOUR DEPARTMENT:
-----------------------------------
{staff_list_text}

COMPLAINT DETAILS:
----------------
Reference: {complaint.reference_number}
Title: {complaint.title}
Severity: {complaint.get_severity_display()}
Priority: {complaint.get_priority_display()}

{complaint.description or "No description provided."}"""

            if complaint.patient:
                champion_email_body += f"""

PATIENT INFORMATION:
------------------
Name: {complaint.patient.get_full_name()}
MRN: {complaint.patient.mrn or "N/A"}"""

            if request_message:
                champion_email_body += f"""

ADDITIONAL MESSAGE:
------------------
{request_message}"""

            champion_email_body += f"""

SUBMIT EXPLANATION:
------------------
Please coordinate with the involved staff and submit the explanation:
{champion_link}

Note: This link can only be used once. After submission, it will expire.

If you have any questions, please contact the PX team.

---
This is an automated message from PX360 Complaint Management System."""

            try:
                NotificationService.send_email(
                    email=champion_email,
                    subject=champion_subject,
                    message=champion_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;">Explanation Request - Complaint #{complaint.reference_number}</h2>
        <p style="margin: 0 0 12px 0;">Dear {champion.get_full_name()},</p>
        <p style="margin: 0 0 12px 0;">We are requesting your assistance in gathering explanations for a complaint involving staff from <strong>{dept_info['department_name']}</strong>.</p>
        <p style="margin: 0 0 12px 0;">Please coordinate with the involved staff and submit the explanation.</p>
        <div style="text-align: center; margin: 20px 0;">
            <a href="{champion_link}" style="background: #005696; color: white; padding: 10px 24px; border-radius: 8px; text-decoration: none; font-weight: 600;">Submit Explanation</a>
        </div>
        <p style="margin: 0 0 6px 0; color: #6b7280; font-size: 13px;">This link can only be used once. After submission, it will expire.</p>
    </div>
</div>
""",
                    related_object=complaint,
                    metadata={
                        "notification_type": "explanation_request",
                        "staff_id": str(champion.id),
                        "complaint_id": str(complaint.id),
                        "department_id": dept_id,
                    },
                )
                champion_count += 1
                results.append(
                    {
                        "recipient_type": "champion",
                        "recipient": champion_display,
                        "email": champion_email,
                        "department": dept_info["department_name"],
                        "explanation_id": str(explanation.id),
                        "sent": True,
                    }
                )
            except Exception as e:
                logger.error(f"Failed to send explanation request to champion {champion.id}: {e}")
                results.append(
                    {
                        "recipient_type": "champion",
                        "recipient": champion_display,
                        "email": champion_email,
                        "department": dept_info["department_name"],
                        "explanation_id": str(explanation.id),
                        "sent": False,
                        "error": str(e),
                    }
                )

        # Set SLA due date on each created explanation
        now = timezone.now()
        sla_config = _get_explanation_sla_config(complaint.hospital)
        sla_hours = sla_config.response_hours if sla_config else 48
        for result in results:
            if result.get("sent") and result.get("explanation_id"):
                ComplaintExplanation.objects.filter(id=result["explanation_id"]).update(
                    sla_due_at=now + timedelta(hours=sla_hours)
                )

        # Mark complaint as sent to department and set forwarded timestamp
        if champion_count > 0:
            complaint.sent_to_department = True
            complaint.sent_to_department_at = complaint.sent_to_department_at or now
            complaint.forwarded_to_dept_at = complaint.forwarded_to_dept_at or now
            complaint.explanation_requested = True
            complaint.explanation_requested_at = complaint.explanation_requested_at or now

            # Create/update ComplaintInvolvedDepartment records for each selected dept
            from apps.complaints.models import ComplaintInvolvedDepartment as CID
            for dept_id in selected_dept_ids:
                dept_info = department_groups.get(dept_id)
                if not dept_info:
                    continue
                try:
                    dept = Department.objects.get(id=dept_id)
                except Department.DoesNotExist:
                    continue
                inv_dept, created = CID.objects.get_or_create(
                    complaint=complaint,
                    department=dept,
                    defaults={
                        "role": "secondary",
                        "added_by": requested_by,
                        "sent": True,
                        "sent_at": now,
                        "forwarded_at": now,
                    },
                )
                if not created and not inv_dept.sent:
                    inv_dept.sent = True
                    inv_dept.sent_at = inv_dept.sent_at or now
                    inv_dept.forwarded_at = inv_dept.forwarded_at or now
                    inv_dept.save()

        metadata = {
            "champion_count": champion_count,
            "skipped_no_email": skipped_no_email,
            "selected_dept_ids": selected_dept_ids,
        }

        if request:
            AuditService.log_from_request(
                event_type="explanation_requested",
                description=f"Explanation requests sent to {champion_count} department champions",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="explanation_requested",
                description=f"Explanation requests sent to {champion_count} department champions",
                user=requested_by,
                content_object=complaint,
                metadata=metadata,
            )

        if champion_count > 0:
            recipients_str = ", ".join([r["recipient"] for r in results if r["sent"]])
            ComplaintUpdate.objects.create(
                complaint=complaint,
                update_type="communication",
                message=f"Explanation request sent to department champions: {recipients_str}",
                created_by=requested_by,
                metadata={
                    "champion_count": champion_count,
                    "results": results,
                },
            )
            complaint.save(update_fields=[
                "updated_at",
                "sent_to_department", "sent_to_department_at",
                "forwarded_to_dept_at",
                "explanation_requested", "explanation_requested_at",
            ])

        return {
            "champion_count": champion_count,
            "skipped_no_email": skipped_no_email,
            "results": results,
            "manager_count": 0,
        }

    @staticmethod
    def post_create_hooks(complaint, created_by, request=None):
        from apps.complaints.tasks import analyze_complaint_with_ai, notify_admins_new_complaint

        ComplaintUpdate.objects.create(
            complaint=complaint,
            update_type="note",
            message="Complaint created. AI analysis running in background.",
            created_by=created_by,
        )

        analyze_complaint_with_ai.delay(str(complaint.id))
        notify_admins_new_complaint.delay(str(complaint.id))

        metadata = {
            "severity": complaint.severity,
            "patient_name": complaint.patient_name,
            "national_id": complaint.national_id,
            "hospital": complaint.hospital.name if complaint.hospital else None,
            "ai_analysis_pending": True,
        }

        if request:
            AuditService.log_from_request(
                event_type="complaint_created",
                description=f"Complaint created: {complaint.title}",
                request=request,
                content_object=complaint,
                metadata=metadata,
            )
        else:
            AuditService.log_event(
                event_type="complaint_created",
                description=f"Complaint created: {complaint.title}",
                user=created_by,
                content_object=complaint,
                metadata=metadata,
            )
