"""
Procurement Alert Service - Simplified

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

import asyncio
from typing import List, Dict, Any, Optional
from uuid import UUID
from datetime import datetime
import structlog

from shared.messaging import UnifiedEventPublisher, EVENT_TYPES

logger = structlog.get_logger()


class ProcurementAlertService:
    """Simplified procurement alert service using UnifiedEventPublisher"""

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

    async def emit_po_approval_needed(
        self,
        tenant_id: UUID,
        po_id: UUID,
        po_number: str,
        supplier_name: str,
        total_amount: float,
        currency: str,
        items_count: int,
        required_delivery_date: str
    ):
        """Emit PO approval needed event"""

        metadata = {
            "po_id": str(po_id),
            "po_number": po_number,
            "supplier_name": supplier_name,
            "total_amount": total_amount,
            "po_amount": total_amount,  # Alias for compatibility
            "currency": currency,
            "items_count": items_count,
            "required_delivery_date": required_delivery_date
        }

        await self.publisher.publish_alert(
            event_type="supply_chain.po_approval_needed",
            tenant_id=tenant_id,
            severity="high",
            data=metadata
        )

        logger.info(
            "po_approval_needed_emitted",
            tenant_id=str(tenant_id),
            po_number=po_number,
            total_amount=total_amount
        )

    async def emit_delivery_overdue(
        self,
        tenant_id: UUID,
        po_id: UUID,
        po_number: str,
        supplier_name: str,
        supplier_contact: Optional[str],
        expected_date: str,
        days_overdue: int,
        items: List[Dict[str, Any]]
    ):
        """Emit delivery overdue alert"""

        # Determine severity based on days overdue
        if days_overdue > 7:
            severity = "urgent"
        elif days_overdue > 3:
            severity = "high"
        else:
            severity = "medium"

        metadata = {
            "po_id": str(po_id),
            "po_number": po_number,
            "supplier_name": supplier_name,
            "expected_date": expected_date,
            "days_overdue": days_overdue,
            "items": items,
            "items_count": len(items)
        }

        if supplier_contact:
            metadata["supplier_contact"] = supplier_contact

        await self.publisher.publish_alert(
            event_type="supply_chain.delivery_overdue",
            tenant_id=tenant_id,
            severity=severity,
            data=metadata
        )

        logger.info(
            "delivery_overdue_emitted",
            tenant_id=str(tenant_id),
            po_number=po_number,
            days_overdue=days_overdue
        )

    async def emit_supplier_performance_issue(
        self,
        tenant_id: UUID,
        supplier_id: UUID,
        supplier_name: str,
        issue_type: str,
        issue_description: str,
        affected_orders: int = 0,
        total_value_affected: Optional[float] = None
    ):
        """Emit supplier performance issue alert"""

        metadata = {
            "supplier_id": str(supplier_id),
            "supplier_name": supplier_name,
            "issue_type": issue_type,
            "issue_description": issue_description,
            "affected_orders": affected_orders
        }

        if total_value_affected:
            metadata["total_value_affected"] = total_value_affected

        await self.publisher.publish_alert(
            event_type="supply_chain.supplier_performance_issue",
            tenant_id=tenant_id,
            severity="high",
            data=metadata
        )

        logger.info(
            "supplier_performance_issue_emitted",
            tenant_id=str(tenant_id),
            supplier_name=supplier_name,
            issue_type=issue_type
        )

    async def emit_price_increase_alert(
        self,
        tenant_id: UUID,
        supplier_id: UUID,
        supplier_name: str,
        ingredient_name: str,
        old_price: float,
        new_price: float,
        increase_percent: float
    ):
        """Emit price increase alert"""

        metadata = {
            "supplier_id": str(supplier_id),
            "supplier_name": supplier_name,
            "ingredient_name": ingredient_name,
            "old_price": old_price,
            "new_price": new_price,
            "increase_percent": increase_percent
        }

        # Determine severity based on increase
        if increase_percent > 20:
            severity = "high"
        elif increase_percent > 10:
            severity = "medium"
        else:
            severity = "low"

        await self.publisher.publish_alert(
            event_type="supply_chain.price_increase",
            tenant_id=tenant_id,
            severity=severity,
            data=metadata
        )

        logger.info(
            "price_increase_emitted",
            tenant_id=str(tenant_id),
            ingredient_name=ingredient_name,
            increase_percent=increase_percent
        )

    async def emit_partial_delivery(
        self,
        tenant_id: UUID,
        po_id: UUID,
        po_number: str,
        supplier_name: str,
        ordered_quantity: float,
        delivered_quantity: float,
        missing_quantity: float,
        ingredient_name: str
    ):
        """Emit partial delivery alert"""

        metadata = {
            "po_id": str(po_id),
            "po_number": po_number,
            "supplier_name": supplier_name,
            "ordered_quantity": ordered_quantity,
            "delivered_quantity": delivered_quantity,
            "missing_quantity": missing_quantity,
            "ingredient_name": ingredient_name
        }

        await self.publisher.publish_alert(
            event_type="supply_chain.partial_delivery",
            tenant_id=tenant_id,
            severity="medium",
            data=metadata
        )

        logger.info(
            "partial_delivery_emitted",
            tenant_id=str(tenant_id),
            po_number=po_number,
            missing_quantity=missing_quantity
        )

    async def emit_delivery_quality_issue(
        self,
        tenant_id: UUID,
        po_id: UUID,
        po_number: str,
        supplier_name: str,
        issue_description: str,
        affected_items: List[Dict[str, Any]],
        requires_return: bool = False
    ):
        """Emit delivery quality issue alert"""

        metadata = {
            "po_id": str(po_id),
            "po_number": po_number,
            "supplier_name": supplier_name,
            "issue_description": issue_description,
            "affected_items": affected_items,
            "requires_return": requires_return,
            "affected_items_count": len(affected_items)
        }

        await self.publisher.publish_alert(
            event_type="supply_chain.delivery_quality_issue",
            tenant_id=tenant_id,
            severity="high",
            data=metadata
        )

        logger.info(
            "delivery_quality_issue_emitted",
            tenant_id=str(tenant_id),
            po_number=po_number,
            requires_return=requires_return
        )

    async def emit_low_supplier_rating(
        self,
        tenant_id: UUID,
        supplier_id: UUID,
        supplier_name: str,
        current_rating: float,
        issues_count: int,
        recommendation: str
    ):
        """Emit low supplier rating alert"""

        metadata = {
            "supplier_id": str(supplier_id),
            "supplier_name": supplier_name,
            "current_rating": current_rating,
            "issues_count": issues_count,
            "recommendation": recommendation
        }

        await self.publisher.publish_alert(
            event_type="supply_chain.low_supplier_rating",
            tenant_id=tenant_id,
            severity="medium",
            data=metadata
        )

        logger.info(
            "low_supplier_rating_emitted",
            tenant_id=str(tenant_id),
            supplier_name=supplier_name,
            current_rating=current_rating
        )

    # Recommendation methods

    async def emit_supplier_consolidation(
        self,
        tenant_id: UUID,
        current_suppliers_count: int,
        suggested_suppliers: List[str],
        potential_savings_eur: float
    ):
        """Emit supplier consolidation recommendation"""

        metadata = {
            "current_suppliers_count": current_suppliers_count,
            "suggested_suppliers": suggested_suppliers,
            "potential_savings_eur": potential_savings_eur
        }

        await self.publisher.publish_recommendation(
            event_type="supply_chain.supplier_consolidation",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "supplier_consolidation_emitted",
            tenant_id=str(tenant_id),
            potential_savings=potential_savings_eur
        )

    async def emit_bulk_purchase_opportunity(
        self,
        tenant_id: UUID,
        ingredient_name: str,
        current_order_frequency: int,
        suggested_bulk_size: float,
        potential_discount_percent: float,
        estimated_savings_eur: float
    ):
        """Emit bulk purchase opportunity recommendation"""

        metadata = {
            "ingredient_name": ingredient_name,
            "current_order_frequency": current_order_frequency,
            "suggested_bulk_size": suggested_bulk_size,
            "potential_discount_percent": potential_discount_percent,
            "estimated_savings_eur": estimated_savings_eur
        }

        await self.publisher.publish_recommendation(
            event_type="supply_chain.bulk_purchase_opportunity",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "bulk_purchase_opportunity_emitted",
            tenant_id=str(tenant_id),
            ingredient_name=ingredient_name,
            estimated_savings=estimated_savings_eur
        )

    async def emit_alternative_supplier_suggestion(
        self,
        tenant_id: UUID,
        ingredient_name: str,
        current_supplier: str,
        alternative_supplier: str,
        price_difference_eur: float,
        quality_rating: float
    ):
        """Emit alternative supplier suggestion"""

        metadata = {
            "ingredient_name": ingredient_name,
            "current_supplier": current_supplier,
            "alternative_supplier": alternative_supplier,
            "price_difference_eur": price_difference_eur,
            "quality_rating": quality_rating
        }

        await self.publisher.publish_recommendation(
            event_type="supply_chain.alternative_supplier_suggestion",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "alternative_supplier_suggestion_emitted",
            tenant_id=str(tenant_id),
            ingredient_name=ingredient_name
        )

    async def emit_reorder_point_optimization(
        self,
        tenant_id: UUID,
        ingredient_name: str,
        current_reorder_point: float,
        suggested_reorder_point: float,
        rationale: str
    ):
        """Emit reorder point optimization recommendation"""

        metadata = {
            "ingredient_name": ingredient_name,
            "current_reorder_point": current_reorder_point,
            "suggested_reorder_point": suggested_reorder_point,
            "rationale": rationale
        }

        await self.publisher.publish_recommendation(
            event_type="supply_chain.reorder_point_optimization",
            tenant_id=tenant_id,
            data=metadata
        )

        logger.info(
            "reorder_point_optimization_emitted",
            tenant_id=str(tenant_id),
            ingredient_name=ingredient_name
        )
