"""
Multi-factor priority scoring for alerts.

Calculates priority score (0-100) based on:
- Business impact (40%): Financial impact, affected orders, customer impact
- Urgency (30%): Time until consequence, deadlines
- User agency (20%): Can user fix it? External dependencies?
- Confidence (10%): AI confidence in assessment

Also applies escalation boosts for age and deadline proximity.
"""

from typing import Dict, Any
import structlog

logger = structlog.get_logger()


class PriorityScorer:
    """Calculate multi-factor priority score (0-100)"""

    # Weights for priority calculation
    BUSINESS_IMPACT_WEIGHT = 0.4
    URGENCY_WEIGHT = 0.3
    USER_AGENCY_WEIGHT = 0.2
    CONFIDENCE_WEIGHT = 0.1

    # Priority thresholds
    CRITICAL_THRESHOLD = 90
    IMPORTANT_THRESHOLD = 70
    STANDARD_THRESHOLD = 50

    def calculate_priority(
        self,
        business_impact: dict,
        urgency: dict,
        user_agency: dict,
        orchestrator_context: dict
    ) -> int:
        """
        Calculate weighted priority score.

        Args:
            business_impact: Business impact context
            urgency: Urgency context
            user_agency: User agency context
            orchestrator_context: AI orchestrator context

        Returns:
            Priority score (0-100)
        """

        # Score each dimension (0-100)
        impact_score = self._score_business_impact(business_impact)
        urgency_score = self._score_urgency(urgency)
        agency_score = self._score_user_agency(user_agency)
        confidence_score = orchestrator_context.get("confidence", 0.8) * 100

        # Weighted average
        total_score = (
            impact_score * self.BUSINESS_IMPACT_WEIGHT +
            urgency_score * self.URGENCY_WEIGHT +
            agency_score * self.USER_AGENCY_WEIGHT +
            confidence_score * self.CONFIDENCE_WEIGHT
        )

        # Apply escalation boost if needed
        escalation_boost = self._calculate_escalation_boost(urgency)
        total_score = min(100, total_score + escalation_boost)

        score = int(total_score)

        logger.debug(
            "priority_calculated",
            score=score,
            impact_score=impact_score,
            urgency_score=urgency_score,
            agency_score=agency_score,
            confidence_score=confidence_score,
            escalation_boost=escalation_boost
        )

        return score

    def _score_business_impact(self, impact: dict) -> int:
        """
        Score business impact (0-100).

        Considers:
        - Financial impact in EUR
        - Number of affected orders
        - Customer impact level
        - Production delays
        - Revenue at risk
        """
        score = 50  # Base score

        # Financial impact
        financial_impact = impact.get("financial_impact_eur", 0)
        if financial_impact > 1000:
            score += 30
        elif financial_impact > 500:
            score += 20
        elif financial_impact > 100:
            score += 10

        # Affected orders
        affected_orders = impact.get("affected_orders", 0)
        if affected_orders > 10:
            score += 15
        elif affected_orders > 5:
            score += 10
        elif affected_orders > 0:
            score += 5

        # Customer impact
        customer_impact = impact.get("customer_impact", "low")
        if customer_impact == "high":
            score += 15
        elif customer_impact == "medium":
            score += 5

        # Production delay hours
        production_delay_hours = impact.get("production_delay_hours", 0)
        if production_delay_hours > 4:
            score += 10
        elif production_delay_hours > 2:
            score += 5

        # Revenue loss
        revenue_loss = impact.get("estimated_revenue_loss_eur", 0)
        if revenue_loss > 500:
            score += 10
        elif revenue_loss > 200:
            score += 5

        return min(100, score)

    def _score_urgency(self, urgency: dict) -> int:
        """
        Score urgency (0-100).

        Considers:
        - Time until consequence
        - Can it wait until tomorrow?
        - Deadline proximity
        - Peak hour relevance
        """
        score = 50  # Base score

        # Time until consequence
        hours_until = urgency.get("hours_until_consequence", 24)
        if hours_until < 2:
            score += 40
        elif hours_until < 6:
            score += 30
        elif hours_until < 12:
            score += 20
        elif hours_until < 24:
            score += 10

        # Can it wait?
        if not urgency.get("can_wait_until_tomorrow", True):
            score += 10

        # Deadline present
        if urgency.get("deadline_utc"):
            score += 5

        # Peak hour relevant (production/demand related)
        if urgency.get("peak_hour_relevant", False):
            score += 5

        return min(100, score)

    def _score_user_agency(self, agency: dict) -> int:
        """
        Score user agency (0-100).

        Higher score when user CAN fix the issue.
        Lower score when blocked or requires external parties.

        Considers:
        - Can user fix it?
        - Requires external party?
        - Has blockers?
        - Suggested workarounds available?
        """
        score = 50  # Base score

        # Can user fix?
        if agency.get("can_user_fix", False):
            score += 30
        else:
            score -= 20

        # Requires external party?
        if agency.get("requires_external_party", False):
            score -= 10

        # Has blockers?
        blockers = agency.get("blockers", [])
        score -= len(blockers) * 5

        # Has suggested workaround?
        if agency.get("suggested_workaround"):
            score += 5

        return max(0, min(100, score))

    def _calculate_escalation_boost(self, urgency: dict) -> int:
        """
        Calculate escalation boost for pending alerts.

        Boosts priority for:
        - Age-based escalation (pending >48h, >72h)
        - Deadline proximity (<6h, <24h)

        Maximum boost: +30 points
        """
        boost = 0

        # Age-based escalation
        hours_pending = urgency.get("hours_pending", 0)
        if hours_pending > 72:
            boost += 20
        elif hours_pending > 48:
            boost += 10

        # Deadline proximity
        hours_until = urgency.get("hours_until_consequence", 24)
        if hours_until < 6:
            boost += 30
        elif hours_until < 24:
            boost += 15

        # Cap at +30
        return min(30, boost)

    def get_priority_level(self, score: int) -> str:
        """
        Convert numeric score to priority level.

        - 90-100: critical
        - 70-89: important
        - 50-69: standard
        - 0-49: info
        """
        if score >= self.CRITICAL_THRESHOLD:
            return "critical"
        elif score >= self.IMPORTANT_THRESHOLD:
            return "important"
        elif score >= self.STANDARD_THRESHOLD:
            return "standard"
        else:
            return "info"
