# shared/clients/orders_client.py
"""
Orders Service Client for Inter-Service Communication
Provides access to orders and procurement planning from other services
"""

import structlog
from typing import Dict, Any, Optional, List
from uuid import UUID
from shared.clients.base_service_client import BaseServiceClient
from shared.config.base import BaseServiceSettings

logger = structlog.get_logger()


class OrdersServiceClient(BaseServiceClient):
    """Client for communicating with the Orders Service"""

    def __init__(self, config: BaseServiceSettings):
        super().__init__("orders", config)

    def get_service_base_path(self) -> str:
        return "/api/v1"

    # ================================================================
    # PROCUREMENT PLANNING
    # ================================================================

    async def get_demand_requirements(self, tenant_id: str, date: str) -> Optional[Dict[str, Any]]:
        """Get demand requirements for production planning"""
        try:
            params = {"date": date}
            result = await self.get("orders/demand-requirements", tenant_id=tenant_id, params=params)
            if result:
                logger.info("Retrieved demand requirements from orders service",
                          date=date, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting demand requirements",
                        error=str(e), date=date, tenant_id=tenant_id)
            return None

    async def get_procurement_requirements(self, tenant_id: str, horizon: Optional[str] = None) -> Optional[Dict[str, Any]]:
        """Get procurement requirements for purchasing planning"""
        try:
            params = {}
            if horizon:
                params["horizon"] = horizon

            result = await self.get("orders/procurement-requirements", tenant_id=tenant_id, params=params)
            if result:
                logger.info("Retrieved procurement requirements from orders service",
                          horizon=horizon, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting procurement requirements",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def get_weekly_ingredient_needs(self, tenant_id: str) -> Optional[Dict[str, Any]]:
        """Get weekly ingredient ordering needs for dashboard"""
        try:
            result = await self.get("orders/dashboard/weekly-ingredient-needs", tenant_id=tenant_id)
            if result:
                logger.info("Retrieved weekly ingredient needs from orders service",
                          tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting weekly ingredient needs",
                        error=str(e), tenant_id=tenant_id)
            return None

    # ================================================================
    # CUSTOMER ORDERS
    # ================================================================

    async def get_customer_orders(self, tenant_id: str, params: Optional[Dict[str, Any]] = None) -> Optional[Dict[str, Any]]:
        """Get customer orders with optional filtering"""
        try:
            result = await self.get("orders/list", tenant_id=tenant_id, params=params)
            if result:
                orders_count = len(result.get('orders', [])) if isinstance(result, dict) else len(result) if isinstance(result, list) else 0
                logger.info("Retrieved customer orders from orders service",
                          orders_count=orders_count, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting customer orders",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def create_customer_order(self, tenant_id: str, order_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
        """Create a new customer order"""
        try:
            result = await self.post("orders/list", data=order_data, tenant_id=tenant_id)
            if result:
                logger.info("Created customer order",
                          order_id=result.get('id'), tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error creating customer order",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def update_customer_order(self, tenant_id: str, order_id: str, order_data: Dict[str, Any]) -> Optional[Dict[str, Any]]:
        """Update an existing customer order"""
        try:
            result = await self.put(f"orders/list/{order_id}", data=order_data, tenant_id=tenant_id)
            if result:
                logger.info("Updated customer order",
                          order_id=order_id, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error updating customer order",
                        error=str(e), order_id=order_id, tenant_id=tenant_id)
            return None

    # ================================================================
    # CENTRAL BAKERY ORDERS
    # ================================================================

    async def get_daily_finalized_orders(self, tenant_id: str, date: Optional[str] = None) -> Optional[Dict[str, Any]]:
        """Get daily finalized orders for central bakery"""
        try:
            params = {}
            if date:
                params["date"] = date

            result = await self.get("orders/daily-finalized", tenant_id=tenant_id, params=params)
            if result:
                logger.info("Retrieved daily finalized orders from orders service",
                          date=date, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting daily finalized orders",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def get_weekly_order_summaries(self, tenant_id: str) -> Optional[Dict[str, Any]]:
        """Get weekly order summaries for central bakery dashboard"""
        try:
            result = await self.get("orders/dashboard/weekly-summaries", tenant_id=tenant_id)
            if result:
                logger.info("Retrieved weekly order summaries from orders service",
                          tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting weekly order summaries",
                        error=str(e), tenant_id=tenant_id)
            return None

    # ================================================================
    # DASHBOARD AND ANALYTICS
    # ================================================================

    async def get_dashboard_summary(self, tenant_id: str) -> Optional[Dict[str, Any]]:
        """Get orders dashboard summary data"""
        try:
            result = await self.get("orders/dashboard/summary", tenant_id=tenant_id)
            if result:
                logger.info("Retrieved orders dashboard summary",
                          tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting orders dashboard summary",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def get_order_trends(self, tenant_id: str, start_date: str, end_date: str) -> Optional[Dict[str, Any]]:
        """Get order trends analysis"""
        try:
            params = {
                "start_date": start_date,
                "end_date": end_date
            }
            result = await self.get("orders/analytics/trends", tenant_id=tenant_id, params=params)
            if result:
                logger.info("Retrieved order trends from orders service",
                          start_date=start_date, end_date=end_date, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error getting order trends",
                        error=str(e), tenant_id=tenant_id)
            return None

    # ================================================================
    # ALERTS AND NOTIFICATIONS
    # ================================================================

    async def get_central_bakery_alerts(self, tenant_id: str) -> Optional[List[Dict[str, Any]]]:
        """Get central bakery specific alerts"""
        try:
            result = await self.get("orders/alerts", tenant_id=tenant_id)
            alerts = result.get('alerts', []) if result else []
            logger.info("Retrieved central bakery alerts from orders service",
                      alerts_count=len(alerts), tenant_id=tenant_id)
            return alerts
        except Exception as e:
            logger.error("Error getting central bakery alerts",
                        error=str(e), tenant_id=tenant_id)
            return []

    async def acknowledge_alert(self, tenant_id: str, alert_id: str) -> Optional[Dict[str, Any]]:
        """Acknowledge an order-related alert"""
        try:
            result = await self.post(f"orders/alerts/{alert_id}/acknowledge", data={}, tenant_id=tenant_id)
            if result:
                logger.info("Acknowledged order alert",
                          alert_id=alert_id, tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error acknowledging order alert",
                        error=str(e), alert_id=alert_id, tenant_id=tenant_id)
            return None

    # ================================================================
    # UTILITY METHODS
    # ================================================================

    async def download_orders_pdf(self, tenant_id: str, order_ids: List[str], format_type: str = "supplier_communication") -> Optional[bytes]:
        """Download orders as PDF for supplier communication"""
        try:
            data = {
                "order_ids": order_ids,
                "format": format_type,
                "include_delivery_schedule": True
            }
            # Note: This would need special handling for binary data
            result = await self.post("orders/operations/download-pdf", data=data, tenant_id=tenant_id)
            if result:
                logger.info("Generated orders PDF",
                          orders_count=len(order_ids), tenant_id=tenant_id)
            return result
        except Exception as e:
            logger.error("Error generating orders PDF",
                        error=str(e), tenant_id=tenant_id)
            return None

    async def health_check(self) -> bool:
        """Check if orders service is healthy"""
        try:
            result = await self.get("../health")  # Health endpoint is not tenant-scoped
            return result is not None
        except Exception as e:
            logger.error("Orders service health check failed", error=str(e))
            return False


# Factory function for dependency injection
def create_orders_client(config: BaseServiceSettings) -> OrdersServiceClient:
    """Create orders service client instance"""
    return OrdersServiceClient(config)
