"""
Enrichment orchestrator service.

Coordinates the complete enrichment pipeline for events.
"""

from typing import Dict, Any
import structlog
from uuid import uuid4

from shared.messaging import MinimalEvent
from app.schemas.events import EnrichedEvent, I18nContent, BusinessImpact, Urgency, UserAgency, OrchestratorContext
from app.enrichment.message_generator import MessageGenerator
from app.enrichment.priority_scorer import PriorityScorer
from app.enrichment.orchestrator_client import OrchestratorClient
from app.enrichment.smart_actions import SmartActionGenerator
from app.enrichment.business_impact import BusinessImpactAnalyzer
from app.enrichment.urgency_analyzer import UrgencyAnalyzer
from app.enrichment.user_agency import UserAgencyAnalyzer

logger = structlog.get_logger()


class EnrichmentOrchestrator:
    """Coordinates the enrichment pipeline for events"""

    def __init__(self):
        self.message_gen = MessageGenerator()
        self.priority_scorer = PriorityScorer()
        self.orchestrator_client = OrchestratorClient()
        self.action_gen = SmartActionGenerator()
        self.impact_analyzer = BusinessImpactAnalyzer()
        self.urgency_analyzer = UrgencyAnalyzer()
        self.agency_analyzer = UserAgencyAnalyzer()

    async def enrich_event(self, event: MinimalEvent) -> EnrichedEvent:
        """
        Run complete enrichment pipeline.

        Steps:
        1. Generate i18n message keys and parameters
        2. Query orchestrator for AI context
        3. Analyze business impact
        4. Assess urgency
        5. Determine user agency
        6. Calculate priority score (0-100)
        7. Determine priority level
        8. Generate smart actions
        9. Determine type class
        10. Build enriched event

        Args:
            event: Minimal event from service

        Returns:
            Enriched event with all context
        """

        logger.info("enrichment_started", event_type=event.event_type, tenant_id=event.tenant_id)

        # 1. Generate i18n message keys and parameters
        i18n_dict = self.message_gen.generate_message(event.event_type, event.metadata, event.event_class)
        i18n = I18nContent(**i18n_dict)

        # 2. Query orchestrator for AI context (parallel with other enrichments)
        orchestrator_context_dict = await self.orchestrator_client.get_context(
            tenant_id=event.tenant_id,
            event_type=event.event_type,
            metadata=event.metadata
        )

        # Fallback: If orchestrator service didn't return context with already_addressed,
        # check if the event metadata contains orchestrator_context (e.g., from demo seeder)
        if not orchestrator_context_dict.get("already_addressed"):
            metadata_context = event.metadata.get("orchestrator_context")
            if metadata_context and isinstance(metadata_context, dict):
                # Merge metadata context into orchestrator context
                orchestrator_context_dict.update(metadata_context)
                logger.debug(
                    "using_metadata_orchestrator_context",
                    event_type=event.event_type,
                    already_addressed=metadata_context.get("already_addressed")
                )

        # Convert to OrchestratorContext if data exists
        orchestrator_context = None
        if orchestrator_context_dict:
            orchestrator_context = OrchestratorContext(**orchestrator_context_dict)

        # 3. Analyze business impact
        business_impact_dict = self.impact_analyzer.analyze(
            event_type=event.event_type,
            metadata=event.metadata
        )
        business_impact = BusinessImpact(**business_impact_dict)

        # 4. Assess urgency
        urgency_dict = self.urgency_analyzer.analyze(
            event_type=event.event_type,
            metadata=event.metadata
        )
        urgency = Urgency(**urgency_dict)

        # 5. Determine user agency
        user_agency_dict = self.agency_analyzer.analyze(
            event_type=event.event_type,
            metadata=event.metadata,
            orchestrator_context=orchestrator_context_dict
        )
        user_agency = UserAgency(**user_agency_dict)

        # 6. Calculate priority score (0-100)
        priority_score = self.priority_scorer.calculate_priority(
            business_impact=business_impact_dict,
            urgency=urgency_dict,
            user_agency=user_agency_dict,
            orchestrator_context=orchestrator_context_dict
        )

        # 7. Determine priority level
        priority_level = self._get_priority_level(priority_score)

        # 8. Generate smart actions
        smart_actions = self.action_gen.generate_actions(
            event_type=event.event_type,
            metadata=event.metadata,
            orchestrator_context=orchestrator_context_dict
        )

        # 9. Determine type class
        type_class = self._determine_type_class(orchestrator_context_dict, event.metadata)

        # 10. Extract AI reasoning from metadata (if present)
        reasoning_data = event.metadata.get('reasoning_data')
        ai_reasoning_details = None
        confidence_score = None

        if reasoning_data:
            # Store the complete reasoning data structure
            ai_reasoning_details = reasoning_data

            # Extract confidence if available
            if isinstance(reasoning_data, dict):
                metadata_section = reasoning_data.get('metadata', {})
                if isinstance(metadata_section, dict) and 'confidence' in metadata_section:
                    confidence_score = metadata_section.get('confidence')

        # 11. Build enriched event
        enriched = EnrichedEvent(
            id=str(uuid4()),
            tenant_id=event.tenant_id,
            event_class=event.event_class,
            event_domain=event.event_domain,
            event_type=event.event_type,
            service=event.service,
            i18n=i18n,
            priority_score=priority_score,
            priority_level=priority_level,
            type_class=type_class,
            orchestrator_context=orchestrator_context,
            business_impact=business_impact,
            urgency=urgency,
            user_agency=user_agency,
            smart_actions=smart_actions,
            ai_reasoning_details=ai_reasoning_details,
            confidence_score=confidence_score,
            entity_links=self._extract_entity_links(event.metadata),
            status="active",
            event_metadata=event.metadata
        )

        logger.info(
            "enrichment_completed",
            event_type=event.event_type,
            priority_score=priority_score,
            priority_level=priority_level,
            type_class=type_class
        )

        return enriched

    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 >= 90:
            return "critical"
        elif score >= 70:
            return "important"
        elif score >= 50:
            return "standard"
        else:
            return "info"

    def _determine_type_class(self, orchestrator_context: dict, metadata: dict = None) -> str:
        """
        Determine type class based on orchestrator context or metadata override.

        Priority order:
        1. Explicit type_class in metadata (e.g., from demo seeder)
        2. orchestrator_context.already_addressed = True -> "prevented_issue"
        3. Default: "action_needed"

        - prevented_issue: AI already handled it
        - action_needed: User action required
        """
        # Check for explicit type_class in metadata (allows demo seeder override)
        if metadata:
            explicit_type_class = metadata.get("type_class")
            if explicit_type_class in ("prevented_issue", "action_needed"):
                return explicit_type_class

        # Determine from orchestrator context
        if orchestrator_context and orchestrator_context.get("already_addressed"):
            return "prevented_issue"
        return "action_needed"

    def _extract_entity_links(self, metadata: dict) -> Dict[str, str]:
        """
        Extract entity references from metadata.

        Maps metadata keys to entity types for frontend deep linking.
        """
        links = {}

        # Map metadata keys to entity types
        entity_mappings = {
            "po_id": "purchase_order",
            "batch_id": "production_batch",
            "ingredient_id": "ingredient",
            "order_id": "order",
            "supplier_id": "supplier",
            "equipment_id": "equipment",
            "sensor_id": "sensor"
        }

        for key, entity_type in entity_mappings.items():
            if key in metadata:
                links[entity_type] = str(metadata[key])

        return links
