"""
Production Notification Service - Simplified

Emits minimal events using EventPublisher.
All enrichment handled by alert_processor.

These are NOTIFICATIONS (not alerts) - informational state changes that don't require user action.
"""

from datetime import datetime, timezone
from typing import Optional, Dict, Any
from uuid import UUID
import structlog

from shared.messaging import UnifiedEventPublisher

logger = structlog.get_logger()


class ProductionNotificationService:
    """
    Service for emitting production notifications using EventPublisher.
    """

    def __init__(self, event_publisher: UnifiedEventPublisher):
        self.publisher = event_publisher

    async def emit_batch_state_changed_notification(
        self,
        tenant_id: UUID,
        batch_id: str,
        product_sku: str,
        product_name: str,
        old_status: str,
        new_status: str,
        quantity: float,
        unit: str,
        assigned_to: Optional[str] = None,
    ) -> None:
        """
        Emit notification when a production batch changes state.
        """
        # Build message based on state transition
        transition_messages = {
            ("PENDING", "IN_PROGRESS"): f"Production started for {product_name}",
            ("IN_PROGRESS", "COMPLETED"): f"Production completed for {product_name}",
            ("IN_PROGRESS", "PAUSED"): f"Production paused for {product_name}",
            ("PAUSED", "IN_PROGRESS"): f"Production resumed for {product_name}",
            ("IN_PROGRESS", "FAILED"): f"Production failed for {product_name}",
        }

        message = transition_messages.get(
            (old_status, new_status),
            f"{product_name} status changed from {old_status} to {new_status}"
        )

        metadata = {
            "batch_id": batch_id,
            "product_sku": product_sku,
            "product_name": product_name,
            "old_status": old_status,
            "new_status": new_status,
            "quantity": float(quantity),
            "unit": unit,
            "assigned_to": assigned_to,
            "state_changed_at": datetime.now(timezone.utc).isoformat(),
        }

        await self.publisher.publish_notification(
            event_type="production.batch_state_changed",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "batch_state_changed_notification_emitted",
            tenant_id=str(tenant_id),
            batch_id=batch_id,
            old_status=old_status,
            new_status=new_status
        )

    async def emit_batch_completed_notification(
        self,
        tenant_id: UUID,
        batch_id: str,
        product_sku: str,
        product_name: str,
        quantity_produced: float,
        unit: str,
        production_duration_minutes: Optional[int] = None,
        quality_score: Optional[float] = None,
    ) -> None:
        """
        Emit notification when a production batch is completed.
        """
        message_parts = [f"Produced {quantity_produced} {unit} of {product_name}"]
        if production_duration_minutes:
            message_parts.append(f"in {production_duration_minutes} minutes")
        if quality_score:
            message_parts.append(f"(Quality: {quality_score:.1f}%)")
        
        message = " ".join(message_parts)

        metadata = {
            "batch_id": batch_id,
            "product_sku": product_sku,
            "product_name": product_name,
            "quantity_produced": float(quantity_produced),
            "unit": unit,
            "production_duration_minutes": production_duration_minutes,
            "quality_score": quality_score,
            "completed_at": datetime.now(timezone.utc).isoformat(),
        }

        await self.publisher.publish_notification(
            event_type="production.batch_completed",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "batch_completed_notification_emitted",
            tenant_id=str(tenant_id),
            batch_id=batch_id,
            quantity_produced=quantity_produced
        )

    async def emit_batch_started_notification(
        self,
        tenant_id: UUID,
        batch_id: str,
        product_sku: str,
        product_name: str,
        quantity_planned: float,
        unit: str,
        estimated_duration_minutes: Optional[int] = None,
        assigned_to: Optional[str] = None,
    ) -> None:
        """
        Emit notification when a production batch is started.
        """
        message_parts = [f"Started production of {quantity_planned} {unit} of {product_name}"]
        if estimated_duration_minutes:
            message_parts.append(f"(Est. {estimated_duration_minutes} min)")
        if assigned_to:
            message_parts.append(f"- Assigned to {assigned_to}")
        
        message = " ".join(message_parts)

        metadata = {
            "batch_id": batch_id,
            "product_sku": product_sku,
            "product_name": product_name,
            "quantity_planned": float(quantity_planned),
            "unit": unit,
            "estimated_duration_minutes": estimated_duration_minutes,
            "assigned_to": assigned_to,
            "started_at": datetime.now(timezone.utc).isoformat(),
        }

        await self.publisher.publish_notification(
            event_type="production.batch_started",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "batch_started_notification_emitted",
            tenant_id=str(tenant_id),
            batch_id=batch_id
        )

    async def emit_equipment_status_notification(
        self,
        tenant_id: UUID,
        equipment_id: str,
        equipment_name: str,
        old_status: str,
        new_status: str,
        reason: Optional[str] = None,
    ) -> None:
        """
        Emit notification when equipment status changes.
        """
        message = f"{equipment_name} status: {old_status} → {new_status}"
        if reason:
            message += f" - {reason}"

        metadata = {
            "equipment_id": equipment_id,
            "equipment_name": equipment_name,
            "old_status": old_status,
            "new_status": new_status,
            "reason": reason,
            "status_changed_at": datetime.now(timezone.utc).isoformat(),
        }

        await self.publisher.publish_notification(
            event_type="production.equipment_status_changed",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "equipment_status_notification_emitted",
            tenant_id=str(tenant_id),
            equipment_id=equipment_id,
            new_status=new_status
        )