"""
Urgency analyzer for alerts.

Assesses time sensitivity, deadlines, and determines if action can wait.
"""

from typing import Dict, Any
from datetime import datetime, timedelta, timezone
import structlog

logger = structlog.get_logger()


class UrgencyAnalyzer:
    """Analyze urgency from event metadata"""

    def analyze(self, event_type: str, metadata: Dict[str, Any]) -> dict:
        """
        Analyze urgency for an event.

        Returns dict with:
        - hours_until_consequence: Time until impact occurs
        - can_wait_until_tomorrow: Boolean
        - deadline_utc: ISO datetime if deadline exists
        - peak_hour_relevant: Boolean
        - hours_pending: Age of alert
        """

        urgency = {
            "hours_until_consequence": 24,  # Default: 24 hours
            "can_wait_until_tomorrow": True,
            "deadline_utc": None,
            "peak_hour_relevant": False,
            "hours_pending": 0
        }

        # Calculate based on event type
        if "critical" in event_type or "urgent" in event_type:
            urgency["hours_until_consequence"] = 2
            urgency["can_wait_until_tomorrow"] = False

        elif "production" in event_type:
            urgency.update(self._analyze_production_urgency(metadata))

        elif "stock" in event_type or "shortage" in event_type:
            urgency.update(self._analyze_stock_urgency(metadata))

        elif "delivery" in event_type or "overdue" in event_type:
            urgency.update(self._analyze_delivery_urgency(metadata))

        elif "po_approval" in event_type:
            urgency.update(self._analyze_po_approval_urgency(metadata))

        # Check for explicit deadlines
        if "required_delivery_date" in metadata:
            urgency.update(self._calculate_deadline_urgency(metadata["required_delivery_date"]))

        if "production_date" in metadata:
            urgency.update(self._calculate_deadline_urgency(metadata["production_date"]))

        if "expected_date" in metadata:
            urgency.update(self._calculate_deadline_urgency(metadata["expected_date"]))

        return urgency

    def _analyze_production_urgency(self, metadata: Dict[str, Any]) -> dict:
        """Analyze urgency for production alerts"""
        urgency = {}

        delay_minutes = metadata.get("delay_minutes", 0)

        if delay_minutes > 120:
            urgency["hours_until_consequence"] = 1
            urgency["can_wait_until_tomorrow"] = False
        elif delay_minutes > 60:
            urgency["hours_until_consequence"] = 4
            urgency["can_wait_until_tomorrow"] = False
        else:
            urgency["hours_until_consequence"] = 8

        # Production is peak-hour sensitive
        urgency["peak_hour_relevant"] = True

        return urgency

    def _analyze_stock_urgency(self, metadata: Dict[str, Any]) -> dict:
        """Analyze urgency for stock alerts"""
        urgency = {}

        # Hours until needed
        if "hours_until" in metadata:
            urgency["hours_until_consequence"] = metadata["hours_until"]
            urgency["can_wait_until_tomorrow"] = urgency["hours_until_consequence"] > 24

        # Days until expiry
        elif "days_until_expiry" in metadata:
            days = metadata["days_until_expiry"]
            if days <= 1:
                urgency["hours_until_consequence"] = days * 24
                urgency["can_wait_until_tomorrow"] = False
            else:
                urgency["hours_until_consequence"] = days * 24

        return urgency

    def _analyze_delivery_urgency(self, metadata: Dict[str, Any]) -> dict:
        """Analyze urgency for delivery alerts"""
        urgency = {}

        days_overdue = metadata.get("days_overdue", 0)

        if days_overdue > 3:
            urgency["hours_until_consequence"] = 2
            urgency["can_wait_until_tomorrow"] = False
        elif days_overdue > 1:
            urgency["hours_until_consequence"] = 8
            urgency["can_wait_until_tomorrow"] = False

        return urgency

    def _analyze_po_approval_urgency(self, metadata: Dict[str, Any]) -> dict:
        """
        Analyze urgency for PO approval alerts.

        Uses stockout time (when you run out of stock) instead of delivery date
        to determine true urgency.
        """
        urgency = {}

        # Extract min_depletion_hours from reasoning_data.parameters
        reasoning_data = metadata.get("reasoning_data", {})
        parameters = reasoning_data.get("parameters", {})
        min_depletion_hours = parameters.get("min_depletion_hours")

        if min_depletion_hours is not None:
            urgency["hours_until_consequence"] = max(0, round(min_depletion_hours, 1))
            urgency["can_wait_until_tomorrow"] = min_depletion_hours > 24

            # Set deadline_utc to when stock runs out
            now = datetime.now(timezone.utc)
            stockout_time = now + timedelta(hours=min_depletion_hours)
            urgency["deadline_utc"] = stockout_time.isoformat()

            logger.info(
                "po_approval_urgency_calculated",
                min_depletion_hours=min_depletion_hours,
                stockout_deadline=urgency["deadline_utc"],
                can_wait=urgency["can_wait_until_tomorrow"]
            )

        return urgency

    def _calculate_deadline_urgency(self, deadline_str: str) -> dict:
        """Calculate urgency based on deadline"""
        try:
            if isinstance(deadline_str, str):
                deadline = datetime.fromisoformat(deadline_str.replace('Z', '+00:00'))
            else:
                deadline = deadline_str

            now = datetime.now(timezone.utc)
            time_until = deadline - now

            hours_until = time_until.total_seconds() / 3600

            return {
                "deadline_utc": deadline.isoformat(),
                "hours_until_consequence": max(0, round(hours_until, 1)),
                "can_wait_until_tomorrow": hours_until > 24
            }
        except Exception as e:
            logger.warning("deadline_parse_failed", deadline=deadline_str, error=str(e))
            return {}
