import logging

from django.conf import settings
from django.utils import timezone
from datetime import timedelta

from apps.organizations.models import Department

logger = logging.getLogger(__name__)


class RoutingRuleEvaluationService:
    CATEGORY_DEPARTMENT_MAP = {
        "clinical_quality": ["Quality", "Clinical Quality"],
        "patient_safety": ["Patient Safety", "Quality"],
        "staff_behavior": ["Human Resources", "HR"],
        "facility": ["Facility Management", "Operations"],
        "service_quality": ["Customer Service", "Patient Experience"],
    }

    @staticmethod
    def evaluate_and_route(action):
        decisions = {}

        RoutingRuleEvaluationService._assign_department(action, decisions)
        RoutingRuleEvaluationService._adjust_priority_severity(action, decisions)
        RoutingRuleEvaluationService._calculate_due_at(action, decisions)

        action.save()
        logger.info("Routing decisions for action %s: %s", action.pk, decisions)
        return decisions

    @staticmethod
    def _assign_department(action, decisions):
        if action.department_id:
            return

        category = action.category
        dept_names = RoutingRuleEvaluationService.CATEGORY_DEPARTMENT_MAP.get(category, [])

        for name in dept_names:
            dept = Department.objects.filter(name__iexact=name).first()
            if dept:
                action.department = dept
                decisions["auto_assigned_department"] = dept.name
                return

    @staticmethod
    def _adjust_priority_severity(action, decisions):
        if action.category == "patient_safety":
            action.severity = "critical"
            decisions["severity_override"] = "critical (patient_safety)"

        if action.source_type == "complaint":
            if action.priority in ("low", ""):
                action.priority = "medium"
                decisions["priority_override"] = "medium (complaint)"

        if action.source_type == "social_media":
            metadata = action.metadata or {}
            sentiment = metadata.get("sentiment", "")
            if sentiment == "negative":
                if action.priority in ("low", "medium", ""):
                    action.priority = "high"
                    decisions["priority_override"] = "high (social_media negative)"

        if action.source_type == "survey":
            metadata = action.metadata or {}
            rating = metadata.get("rating")
            if rating is not None and isinstance(rating, (int, float)) and rating <= 2:
                if action.severity in ("low", "medium", ""):
                    action.severity = "high"
                    decisions["severity_override"] = decisions.get("severity_override", "high (survey low rating)")

    @staticmethod
    def _calculate_due_at(action, decisions):
        if action.due_at:
            return

        sla_hours = getattr(settings, "SLA_DEFAULTS", {}).get("action", {}).get(action.severity, 48)
        action.due_at = timezone.now() + timedelta(hours=sla_hours)
        decisions["auto_calculated_due_at"] = action.due_at.isoformat()
        decisions["sla_hours"] = sla_hours
