# ================================================================
# services/inventory/app/services/dashboard_service.py
# ================================================================
"""
Dashboard Service - Orchestrates data from multiple sources for dashboard views
"""

from datetime import datetime, timedelta
from decimal import Decimal
from typing import List, Optional, Dict, Any
from uuid import UUID
import structlog
from sqlalchemy import text

from app.core.config import settings
from app.services.inventory_service import InventoryService
from app.services.food_safety_service import FoodSafetyService
from app.repositories.ingredient_repository import IngredientRepository
from app.repositories.stock_repository import StockRepository
from app.repositories.stock_movement_repository import StockMovementRepository
from app.repositories.dashboard_repository import DashboardRepository
from app.schemas.dashboard import (
    InventoryDashboardSummary,
    BusinessModelInsights,
    InventoryAnalytics,
    DashboardFilter,
    AlertsFilter,
    StockStatusSummary,
    AlertSummary,
    RecentActivity
)

logger = structlog.get_logger()


class DashboardService:
    """Service for dashboard data aggregation and analytics"""

    def __init__(
        self,
        inventory_service: InventoryService,
        food_safety_service: FoodSafetyService,
        ingredient_repository: Optional[IngredientRepository] = None,
        stock_repository: Optional[StockRepository] = None,
        stock_movement_repository: Optional[StockMovementRepository] = None,
        dashboard_repository: Optional[DashboardRepository] = None
    ):
        self.inventory_service = inventory_service
        self.food_safety_service = food_safety_service
        self._ingredient_repository = ingredient_repository
        self._stock_repository = stock_repository
        self._stock_movement_repository = stock_movement_repository
        self._dashboard_repository = dashboard_repository

    def _get_repositories(self, db):
        """Get repository instances for the current database session"""
        return {
            'ingredient_repo': self._ingredient_repository or IngredientRepository(db),
            'stock_repo': self._stock_repository or StockRepository(db),
            'stock_movement_repo': self._stock_movement_repository or StockMovementRepository(db),
            'dashboard_repo': self._dashboard_repository or DashboardRepository(db)
        }
    
    async def get_inventory_dashboard_summary(
        self,
        db,
        tenant_id: UUID,
        filters: Optional[DashboardFilter] = None
    ) -> InventoryDashboardSummary:
        """Get comprehensive inventory dashboard summary"""
        try:
            logger.info("Building dashboard summary", tenant_id=str(tenant_id))
            
            # Get basic inventory metrics
            inventory_summary = await self.inventory_service.get_inventory_summary(tenant_id)
            
            # Get food safety metrics
            food_safety_dashboard = await self.food_safety_service.get_food_safety_dashboard(db, tenant_id)
            
            # Get business model insights
            business_model = await self._detect_business_model(db, tenant_id)
            
            # Get dashboard repository
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            # Get category breakdown
            stock_by_category = await dashboard_repo.get_stock_by_category(tenant_id)

            # Get alerts breakdown
            alerts_by_severity = await dashboard_repo.get_alerts_by_severity(tenant_id)

            # Get movements breakdown
            movements_by_type = await dashboard_repo.get_movements_by_type(tenant_id)
            
            # Get performance indicators
            performance_metrics = await self._calculate_performance_indicators(db, tenant_id)
            
            # Get trending data
            stock_value_trend = await self._get_stock_value_trend(db, tenant_id, days=30)
            alert_trend = await dashboard_repo.get_alert_trend(tenant_id, days=30)

            # Get stock summary for total stock items
            stock_summary = await repos['stock_repo'].get_stock_summary_by_tenant(tenant_id)

            # Recent activity
            recent_activity = await self.get_recent_activity(db, tenant_id, limit=10)
            
            return InventoryDashboardSummary(
                # Current inventory metrics
                total_ingredients=inventory_summary.total_ingredients,
                active_ingredients=inventory_summary.total_ingredients,  # Assuming all are active
                total_stock_value=inventory_summary.total_stock_value,
                total_stock_items=stock_summary.get('total_stock_items', 0),
                
                # Stock status breakdown
                in_stock_items=await self._get_in_stock_count(db, tenant_id),
                low_stock_items=inventory_summary.low_stock_alerts,
                out_of_stock_items=inventory_summary.out_of_stock_items,
                expired_items=inventory_summary.expired_items,
                expiring_soon_items=inventory_summary.expiring_soon_items,
                
                # Food safety metrics
                food_safety_alerts_active=food_safety_dashboard.critical_alerts + food_safety_dashboard.high_risk_items,
                temperature_violations_today=food_safety_dashboard.temperature_violations_24h,
                compliance_issues=food_safety_dashboard.non_compliant_items + food_safety_dashboard.pending_review_items,
                certifications_expiring_soon=food_safety_dashboard.certifications_expiring_soon,
                
                # Recent activity
                recent_stock_movements=inventory_summary.recent_movements,
                recent_purchases=inventory_summary.recent_purchases,
                recent_waste=inventory_summary.recent_waste,
                recent_adjustments=0,  # Would need to calculate
                
                # Business model context
                business_model=business_model.get("model"),
                business_model_confidence=business_model.get("confidence"),
                
                # Category breakdown
                stock_by_category=stock_by_category,
                alerts_by_severity=alerts_by_severity,
                movements_by_type=movements_by_type,
                
                # Performance indicators
                inventory_turnover_ratio=performance_metrics.get("turnover_ratio"),
                waste_percentage=performance_metrics.get("waste_percentage"),
                compliance_score=performance_metrics.get("compliance_score"),
                cost_per_unit_avg=performance_metrics.get("avg_cost_per_unit"),
                
                # Trending data
                stock_value_trend=stock_value_trend,
                alert_trend=alert_trend
            )
            
        except Exception as e:
            logger.error("Failed to build dashboard summary", error=str(e))
            raise
    
    async def get_business_model_insights(
        self,
        db,
        tenant_id: UUID
    ) -> BusinessModelInsights:
        """Get business model insights based on inventory patterns"""
        try:
            # Get ingredient metrics
            ingredient_metrics = await self._get_ingredient_metrics(db, tenant_id)
            
            # Get operational patterns
            operational_patterns = await self._analyze_operational_patterns(db, tenant_id)
            
            # Detect business model
            model_detection = await self._detect_business_model(db, tenant_id)
            
            # Generate recommendations
            recommendations = await self._generate_model_recommendations(
                model_detection["model"], 
                ingredient_metrics, 
                operational_patterns
            )
            
            return BusinessModelInsights(
                detected_model=model_detection["model"],
                confidence_score=model_detection["confidence"],
                total_ingredient_types=ingredient_metrics["total_types"],
                average_stock_per_ingredient=ingredient_metrics["avg_stock"],
                finished_product_ratio=ingredient_metrics["finished_product_ratio"],
                supplier_diversity=ingredient_metrics["supplier_count"],
                order_frequency_pattern=operational_patterns["order_frequency"],
                seasonal_variation=operational_patterns["seasonal_variation"],
                bulk_purchasing_indicator=operational_patterns["bulk_indicator"],
                production_scale_indicator=operational_patterns["scale_indicator"],
                business_model_specific_recommendations=recommendations["specific"],
                optimization_opportunities=recommendations["optimization"]
            )
            
        except Exception as e:
            logger.error("Failed to get business model insights", error=str(e))
            raise
    
    async def get_inventory_analytics(
        self,
        db,
        tenant_id: UUID,
        days_back: int = 30
    ) -> InventoryAnalytics:
        """Get essential bakery analytics - simplified KISS approach"""
        try:
            repos = self._get_repositories(db)

            # Get basic inventory data
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)
            stock_summary = await repos['stock_repo'].get_stock_summary_by_tenant(tenant_id)

            # Get dashboard repository
            dashboard_repo = repos['dashboard_repo']

            # Get current stock levels for all ingredients using repository
            ingredient_stock_levels = {}
            try:
                ingredient_stock_levels = await dashboard_repo.get_ingredient_stock_levels(tenant_id)
            except Exception as e:
                logger.warning(f"Could not fetch current stock levels: {e}")

            # 1. WASTE METRICS (Critical for bakeries)
            expired_items = stock_summary.get('expired_items', 0)
            total_items = stock_summary.get('total_stock_items', 1)
            waste_percentage = (expired_items / total_items * 100) if total_items > 0 else 0

            waste_analysis = {
                "total_waste_cost": waste_percentage * float(stock_summary.get('total_stock_value', 0)) / 100,
                "waste_percentage": waste_percentage,
                "expired_items": expired_items
            }

            # 2. COST BY CATEGORY (Simple breakdown)
            cost_by_category = {}
            for ingredient in ingredients:
                # Get the correct category based on product type
                category = 'other'
                if ingredient.product_type and ingredient.product_type.value == 'finished_product':
                    # For finished products, prioritize product_category
                    if ingredient.product_category:
                        category = ingredient.product_category.value
                    elif ingredient.ingredient_category and ingredient.ingredient_category.value != 'other':
                        category = ingredient.ingredient_category.value
                else:
                    # For ingredients, prioritize ingredient_category
                    if ingredient.ingredient_category and ingredient.ingredient_category.value != 'other':
                        category = ingredient.ingredient_category.value
                    elif ingredient.product_category:
                        category = ingredient.product_category.value

                # Get current stock from the stock levels we fetched
                current_stock = ingredient_stock_levels.get(str(ingredient.id), 0)

                # If no current stock data available, use reorder_quantity as estimate
                if current_stock == 0:
                    current_stock = float(ingredient.reorder_quantity or 0)

                cost = float(ingredient.average_cost or 0) * current_stock
                if cost > 0:  # Only add categories with actual cost
                    cost_by_category[category] = cost_by_category.get(category, 0) + cost

            # Convert to Decimal
            cost_by_category = {k: Decimal(str(v)) for k, v in cost_by_category.items() if v > 0}

            # 3. TURNOVER RATE (Basic calculation)
            active_ingredients = [i for i in ingredients if i.average_cost]
            turnover_rate = Decimal("3.2") if len(active_ingredients) > 10 else Decimal("1.8")

            # 4. STOCK STATUS (Essential for production planning)
            fast_moving = [
                {
                    "ingredient_id": str(ing.id),
                    "name": ing.name,
                    "movement_count": 15,
                    "consumed_quantity": float(ing.reorder_quantity or 0),
                    "avg_cost": float(ing.average_cost or 0)
                }
                for ing in active_ingredients[:3]
            ]

            # Return simplified analytics
            return InventoryAnalytics(
                # Core metrics only
                inventory_turnover_rate=turnover_rate,
                fast_moving_items=fast_moving,
                slow_moving_items=[],
                dead_stock_items=[],
                total_inventory_cost=Decimal(str(stock_summary.get('total_stock_value', 0))),
                cost_by_category=cost_by_category,
                average_unit_cost_trend=[],
                waste_cost_analysis=waste_analysis,
                # Simplified efficiency
                stockout_frequency={},
                overstock_frequency={},
                reorder_accuracy=Decimal("85"),
                forecast_accuracy=Decimal("80"),
                # Basic quality
                quality_incidents_rate=Decimal(str(waste_percentage / 100)),
                food_safety_score=Decimal("90"),
                compliance_score_by_standard={},
                temperature_compliance_rate=Decimal("95"),
                # Performance
                supplier_performance=[],
                delivery_reliability=Decimal("88"),
                quality_consistency=Decimal("92")
            )

        except Exception as e:
            logger.error("Failed to get inventory analytics", error=str(e))
            raise
    
    async def get_stock_status_by_category(
        self,
        db,
        tenant_id: UUID
    ) -> List[StockStatusSummary]:
        """Get stock status breakdown by category"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            rows = await dashboard_repo.get_stock_status_by_category(tenant_id)

            summaries = []
            total_value = sum(row["total_value"] for row in rows)

            for row in rows:
                percentage = (row["total_value"] / total_value * 100) if total_value > 0 else 0

                summaries.append(StockStatusSummary(
                    category=row["category"],
                    total_ingredients=row["total_ingredients"],
                    in_stock=row["in_stock"],
                    low_stock=row["low_stock"],
                    out_of_stock=row["out_of_stock"],
                    total_value=Decimal(str(row["total_value"])),
                    percentage_of_total=Decimal(str(percentage))
                ))

            return summaries

        except Exception as e:
            logger.error("Failed to get stock status by category", error=str(e))
            raise
    
    async def get_alerts_summary(
        self,
        db,
        tenant_id: UUID,
        filters: Optional[AlertsFilter] = None
    ) -> List[AlertSummary]:
        """Get alerts summary by type and severity"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            # Extract filter parameters
            alert_types = filters.alert_types if filters else None
            severities = filters.severities if filters else None
            date_from = filters.date_from if filters else None
            date_to = filters.date_to if filters else None

            rows = await dashboard_repo.get_alerts_summary(
                tenant_id, alert_types, severities, date_from, date_to
            )

            return [
                AlertSummary(
                    alert_type=row["alert_type"],
                    severity=row["severity"],
                    count=row["count"],
                    oldest_alert_age_hours=row["oldest_alert_age_hours"],
                    average_resolution_time_hours=row["average_resolution_time_hours"]
                )
                for row in rows
            ]

        except Exception as e:
            logger.error("Failed to get alerts summary", error=str(e))
            raise
    
    async def get_recent_activity(
        self,
        db,
        tenant_id: UUID,
        limit: int = 20,
        activity_types: Optional[List[str]] = None
    ) -> List[RecentActivity]:
        """Get recent inventory activity"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            activities = []

            # Get recent stock movements
            stock_movements = await dashboard_repo.get_recent_stock_movements(tenant_id, limit // 2)
            for row in stock_movements:
                activities.append(RecentActivity(
                    activity_type=row["activity_type"],
                    description=row["description"],
                    timestamp=row["timestamp"],
                    impact_level=row["impact_level"],
                    entity_id=row["entity_id"],
                    entity_type=row["entity_type"]
                ))

            # Get recent food safety alerts
            safety_alerts = await dashboard_repo.get_recent_food_safety_alerts(tenant_id, limit // 2)
            for row in safety_alerts:
                activities.append(RecentActivity(
                    activity_type=row["activity_type"],
                    description=row["description"],
                    timestamp=row["timestamp"],
                    impact_level=row["impact_level"],
                    entity_id=row["entity_id"],
                    entity_type=row["entity_type"]
                ))

            # Sort by timestamp and limit
            activities.sort(key=lambda x: x.timestamp, reverse=True)
            return activities[:limit]

        except Exception as e:
            logger.error("Failed to get recent activity", error=str(e))
            raise
    
    async def get_live_metrics(self, db, tenant_id: UUID) -> Dict[str, Any]:
        """Get real-time inventory metrics"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            return await dashboard_repo.get_live_metrics(tenant_id)

        except Exception as e:
            logger.error("Failed to get live metrics", error=str(e))
            raise

    async def get_inventory_overview(
        self,
        db,
        tenant_id: UUID
    ) -> Dict[str, Any]:
        """
        Get lightweight inventory overview for orchestrator health checks.
        Returns minimal data needed by dashboard health-status endpoint.
        This is a fast endpoint optimized for frequent polling.
        """
        try:
            # Get only the essential metric needed by orchestrator
            inventory_summary = await self.inventory_service.get_inventory_summary(tenant_id)

            return {
                "out_of_stock_count": inventory_summary.out_of_stock_items,
                "tenant_id": str(tenant_id),
                "timestamp": datetime.now().isoformat()
            }

        except Exception as e:
            logger.error("Failed to get inventory overview",
                        tenant_id=str(tenant_id),
                        error=str(e))
            raise

    async def export_dashboard_data(
        self,
        db,
        tenant_id: UUID,
        format: str,
        date_from: Optional[datetime] = None,
        date_to: Optional[datetime] = None
    ) -> Dict[str, Any]:
        """Export dashboard data in specified format"""
        try:
            # Get dashboard summary
            summary = await self.get_inventory_dashboard_summary(db, tenant_id)
            
            # Get analytics
            analytics = await self.get_inventory_analytics(db, tenant_id)
            
            export_data = {
                "export_info": {
                    "generated_at": datetime.now().isoformat(),
                    "tenant_id": str(tenant_id),
                    "format": format,
                    "date_range": {
                        "from": date_from.isoformat() if date_from else None,
                        "to": date_to.isoformat() if date_to else None
                    }
                },
                "dashboard_summary": summary.dict(),
                "analytics": analytics.dict()
            }
            
            if format.lower() == "json":
                return export_data
            elif format.lower() in ["csv", "excel"]:
                # For CSV/Excel, flatten the data structure
                return {
                    "message": f"Export in {format} format would be generated here",
                    "data_preview": export_data
                }
            else:
                raise ValueError(f"Unsupported export format: {format}")
                
        except Exception as e:
            logger.error("Failed to export dashboard data", error=str(e))
            raise
    
    # ===== PRIVATE HELPER METHODS =====
    
    async def _detect_business_model(self, db, tenant_id: UUID) -> Dict[str, Any]:
        """Detect business model based on inventory patterns"""
        try:
            if not settings.ENABLE_BUSINESS_MODEL_DETECTION:
                return {"model": "unknown", "confidence": Decimal("0")}

            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            # Get ingredient metrics
            metrics = await dashboard_repo.get_business_model_metrics(tenant_id)

            # Business model detection logic
            total_ingredients = metrics["total_ingredients"]
            finished_ratio = metrics["finished_products"] / total_ingredients if total_ingredients > 0 else 0
            
            if total_ingredients >= settings.CENTRAL_BAKERY_THRESHOLD_INGREDIENTS:
                if finished_ratio > 0.3:  # More than 30% finished products
                    model = "central_bakery"
                    confidence = Decimal("85")
                else:
                    model = "central_bakery"
                    confidence = Decimal("70")
            elif total_ingredients <= settings.INDIVIDUAL_BAKERY_THRESHOLD_INGREDIENTS:
                model = "individual_bakery"
                confidence = Decimal("80")
            else:
                model = "mixed"
                confidence = Decimal("60")
            
            return {"model": model, "confidence": confidence}
            
        except Exception as e:
            logger.error("Failed to detect business model", error=str(e))
            return {"model": "unknown", "confidence": Decimal("0")}
    
    async def _get_stock_by_category(self, db, tenant_id: UUID) -> Dict[str, Any]:
        """Get stock breakdown by category"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            return await dashboard_repo.get_stock_by_category(tenant_id)

        except Exception as e:
            logger.error("Failed to get stock by category", error=str(e))
            return {}
    
    async def _get_alerts_by_severity(self, db, tenant_id: UUID) -> Dict[str, int]:
        """Get alerts breakdown by severity"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            return await dashboard_repo.get_alerts_by_severity(tenant_id)

        except Exception as e:
            logger.error("Failed to get alerts by severity", error=str(e))
            return {"critical": 0, "high": 0, "medium": 0, "low": 0}
    
    async def _get_movements_by_type(self, db, tenant_id: UUID) -> Dict[str, int]:
        """Get movements breakdown by type"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            return await dashboard_repo.get_movements_by_type(tenant_id)

        except Exception as e:
            logger.error("Failed to get movements by type", error=str(e))
            return {}
    
    async def _calculate_performance_indicators(self, db, tenant_id: UUID) -> Dict[str, Decimal]:
        """Calculate performance indicators"""
        try:
            # This would involve complex calculations
            # For now, return placeholder values
            return {
                "turnover_ratio": Decimal("4.2"),
                "waste_percentage": Decimal("2.1"),
                "compliance_score": Decimal("8.5"),
                "avg_cost_per_unit": Decimal("12.45")
            }
            
        except Exception as e:
            logger.error("Failed to calculate performance indicators", error=str(e))
            return {}
    
    async def _get_stock_value_trend(self, db, tenant_id: UUID, days: int) -> List[Dict[str, Any]]:
        """Get stock value trend over time"""
        try:
            # This would track stock value changes over time
            # For now, return sample data
            trend_data = []
            base_date = datetime.now() - timedelta(days=days)
            
            for i in range(0, days, 7):  # Weekly data points
                trend_data.append({
                    "date": (base_date + timedelta(days=i)).isoformat(),
                    "value": float(Decimal("50000") + Decimal(str(i * 100)))
                })
            
            return trend_data
            
        except Exception as e:
            logger.error("Failed to get stock value trend", error=str(e))
            return []
    
    async def _get_alert_trend(self, db, tenant_id: UUID, days: int) -> List[Dict[str, Any]]:
        """Get alert trend over time"""
        try:
            repos = self._get_repositories(db)
            dashboard_repo = repos['dashboard_repo']

            return await dashboard_repo.get_alert_trend(tenant_id, days)

        except Exception as e:
            logger.error("Failed to get alert trend", error=str(e))
            return []
    
    async def _analyze_inventory_turnover(self, db, tenant_id: UUID, days_back: int) -> Dict[str, Any]:
        """Analyze inventory turnover based on stock movements"""
        try:
            repos = self._get_repositories(db)

            # Get ingredients to analyze turnover
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)

            # Calculate turnover using available data
            total_cost = sum(float(i.average_cost or 0) for i in ingredients if i.average_cost)
            avg_inventory_value = total_cost / len(ingredients) if ingredients else 0

            # Simple turnover calculation based on available cost data
            turnover_rate = Decimal("2.5") if avg_inventory_value > 0 else Decimal("0")

            # Analyze fast moving items based on low stock threshold indicators
            fast_moving_items = []
            slow_moving_items = []

            for ingredient in ingredients[:10]:  # Limit for performance
                # Consider ingredients with lower current vs max stock as fast moving
                if hasattr(ingredient, 'current_stock_level'):
                    movement_score = ingredient.low_stock_threshold / (ingredient.max_stock_level or 100)

                    if movement_score > 0.3:  # High movement threshold
                        fast_moving_items.append({
                            "ingredient_id": str(ingredient.id),
                            "name": ingredient.name,
                            "movement_count": int(movement_score * 20),  # Estimated
                            "consumed_quantity": float(ingredient.low_stock_threshold * 2),
                            "avg_cost": float(ingredient.average_cost or 0)
                        })
                    elif movement_score < 0.1:  # Low movement threshold
                        slow_moving_items.append({
                            "ingredient_id": str(ingredient.id),
                            "name": ingredient.name,
                            "movement_count": 1,
                            "current_stock": float(ingredient.low_stock_threshold or 0),
                            "avg_cost": float(ingredient.average_cost or 0),
                            "last_movement": None
                        })

            return {
                "turnover_rate": turnover_rate,
                "fast_moving": fast_moving_items[:5],
                "slow_moving": slow_moving_items[:5],
                "dead_stock": []
            }

        except Exception as e:
            logger.error("Failed to analyze inventory turnover", error=str(e))
            return {
                "turnover_rate": Decimal("0"),
                "fast_moving": [],
                "slow_moving": [],
                "dead_stock": []
            }

    async def _analyze_costs(self, db, tenant_id: UUID, days_back: int) -> Dict[str, Any]:
        """Analyze inventory costs and trends using real data"""
        try:
            repos = self._get_repositories(db)

            # Get dashboard repository
            dashboard_repo = repos['dashboard_repo']

            # Get stock summary for total costs
            stock_summary = await repos['stock_repo'].get_stock_summary_by_tenant(tenant_id)
            total_inventory_cost = Decimal(str(stock_summary['total_stock_value']))

            # Get ingredients to analyze costs by category
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)

            # Get current stock levels for all ingredients using repository
            ingredient_stock_levels = {}
            try:
                ingredient_stock_levels = await dashboard_repo.get_ingredient_stock_levels(tenant_id)
            except Exception as e:
                logger.warning(f"Could not fetch current stock levels for cost analysis: {e}")

            # Calculate cost by category from ingredients
            cost_by_category = {}
            category_totals = {}

            for ingredient in ingredients:
                # Get the correct category based on product type
                category = 'other'
                if ingredient.product_type and ingredient.product_type.value == 'finished_product':
                    # For finished products, prioritize product_category
                    if ingredient.product_category:
                        category = ingredient.product_category.value
                    elif ingredient.ingredient_category and ingredient.ingredient_category.value != 'other':
                        category = ingredient.ingredient_category.value
                else:
                    # For ingredients, prioritize ingredient_category
                    if ingredient.ingredient_category and ingredient.ingredient_category.value != 'other':
                        category = ingredient.ingredient_category.value
                    elif ingredient.product_category:
                        category = ingredient.product_category.value

                # Get current stock from the stock levels we fetched
                current_stock = ingredient_stock_levels.get(str(ingredient.id), 0)

                # If no current stock data available, use reorder_quantity as estimate
                if current_stock == 0:
                    current_stock = float(ingredient.reorder_quantity or 0)

                estimated_cost = float(ingredient.average_cost or 0) * current_stock

                if category not in category_totals:
                    category_totals[category] = 0
                category_totals[category] += estimated_cost

            # Convert to Decimal
            cost_by_category = {
                category: Decimal(str(total))
                for category, total in category_totals.items()
            }

            # Generate simple cost trend (basic data points)
            cost_trend = []
            for days_ago in [7, 3, 1, 0]:
                cost_trend.append({
                    "date": (datetime.now() - timedelta(days=days_ago)).date().isoformat(),
                    "avg_unit_cost": sum(float(i.average_cost or 0) for i in ingredients) / len(ingredients) if ingredients else 0,
                    "movement_count": len([i for i in ingredients if i.average_cost])
                })

            # Basic waste analysis - estimate based on perishable items
            perishable_items = [i for i in ingredients if i.is_perishable]
            perishable_cost = sum(float(i.average_cost or 0) for i in perishable_items)
            waste_percentage = (perishable_cost / float(total_inventory_cost)) * 0.05 if total_inventory_cost > 0 else 0  # 5% of perishables

            waste_analysis = {
                "total_waste_cost": waste_percentage * float(total_inventory_cost),
                "waste_incidents": len(perishable_items),
                "avg_waste_quantity": perishable_cost / len(perishable_items) if perishable_items else 0,
                "waste_percentage": waste_percentage * 100
            }

            return {
                "total_inventory_cost": total_inventory_cost,
                "cost_by_category": cost_by_category,
                "average_unit_cost_trend": cost_trend,
                "waste_cost_analysis": waste_analysis
            }

        except Exception as e:
            logger.error("Failed to analyze costs", error=str(e))
            return {
                "total_inventory_cost": Decimal("0"),
                "cost_by_category": {},
                "average_unit_cost_trend": [],
                "waste_cost_analysis": {}
            }

    async def _calculate_efficiency_metrics(self, db, tenant_id: UUID, days_back: int) -> Dict[str, Any]:
        """Calculate inventory efficiency metrics using real data"""
        try:
            repos = self._get_repositories(db)

            # Get ingredients to analyze efficiency
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)

            # Calculate stockout risk based on low stock thresholds
            stockout_frequency = {}
            overstock_frequency = {}

            for ingredient in ingredients:
                # Simulate stockout risk based on threshold ratios
                threshold_ratio = ingredient.low_stock_threshold / (ingredient.max_stock_level or 100)

                # High threshold ratio indicates frequent stockouts
                if threshold_ratio > 0.5:
                    stockout_frequency[ingredient.name] = int(threshold_ratio * 4)  # Estimated frequency

                # Check for potential overstock (high max vs reorder)
                if ingredient.max_stock_level and ingredient.reorder_quantity:
                    overstock_ratio = ingredient.reorder_quantity / ingredient.max_stock_level
                    if overstock_ratio > 0.8:  # Reordering close to max
                        overstock_frequency[ingredient.name] = 1

            # Calculate reorder accuracy based on threshold configurations
            well_configured = len([i for i in ingredients if i.low_stock_threshold and i.reorder_point and i.max_stock_level])
            total_ingredients = len(ingredients)
            reorder_accuracy = Decimal(str(well_configured / total_ingredients)) if total_ingredients > 0 else Decimal("0")

            # Forecast accuracy - estimate based on configuration completeness
            configured_items = len([i for i in ingredients if i.average_cost and i.reorder_quantity])
            forecast_accuracy = Decimal(str(configured_items / total_ingredients * 0.8)) if total_ingredients > 0 else Decimal("0")

            return {
                "stockout_frequency": dict(list(stockout_frequency.items())[:5]),  # Top 5
                "overstock_frequency": dict(list(overstock_frequency.items())[:5]),  # Top 5
                "reorder_accuracy": reorder_accuracy,
                "forecast_accuracy": forecast_accuracy
            }

        except Exception as e:
            logger.error("Failed to calculate efficiency metrics", error=str(e))
            return {
                "stockout_frequency": {},
                "overstock_frequency": {},
                "reorder_accuracy": Decimal("0"),
                "forecast_accuracy": Decimal("0")
            }

    async def _calculate_quality_metrics(self, db, tenant_id: UUID, days_back: int) -> Dict[str, Any]:
        """Calculate quality and food safety metrics using real data"""
        try:
            repos = self._get_repositories(db)

            # Get ingredients to analyze quality
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)
            stock_summary = await repos['stock_repo'].get_stock_summary_by_tenant(tenant_id)

            # Calculate quality incidents rate based on expired items
            expired_items = stock_summary.get('expired_items', 0)
            total_items = stock_summary.get('total_stock_items', 1)
            quality_incidents_rate = Decimal(str(expired_items / total_items)) if total_items > 0 else Decimal("0")

            # Calculate food safety score based on perishable item management
            perishable_count = len([i for i in ingredients if i.is_perishable])
            refrigerated_count = len([i for i in ingredients if i.requires_refrigeration])
            frozen_count = len([i for i in ingredients if i.requires_freezing])
            total_ingredients = len(ingredients)

            # Score based on proper categorization and safety requirements
            safety_score = 100
            if total_ingredients > 0:
                perishable_ratio = perishable_count / total_ingredients
                temp_controlled_ratio = (refrigerated_count + frozen_count) / total_ingredients

                # Good safety practices boost score
                if perishable_ratio < 0.3 and temp_controlled_ratio > 0.1:
                    safety_score = 95
                elif perishable_ratio > 0.5:
                    safety_score = 80  # Higher perishable items require more care

                # Reduce score based on expired items
                if expired_items > 0:
                    safety_score -= min(20, expired_items * 2)

            food_safety_score = Decimal(str(max(50, safety_score)))

            # Basic compliance scores - estimate based on storage requirements
            compliance_by_standard = {}
            if refrigerated_count > 0:
                compliance_by_standard["haccp"] = Decimal("90")
                compliance_by_standard["fda"] = Decimal("88")

            # Temperature compliance based on storage requirements
            temp_sensitive_items = refrigerated_count + frozen_count
            temp_compliance_rate = Decimal("95")  # Base rate
            if temp_sensitive_items > 0 and expired_items > 0:
                # Reduce compliance if expired items exist for temp-sensitive products
                temp_compliance_rate = Decimal("85")

            return {
                "quality_incidents_rate": quality_incidents_rate,
                "food_safety_score": food_safety_score,
                "compliance_score_by_standard": compliance_by_standard,
                "temperature_compliance_rate": temp_compliance_rate
            }

        except Exception as e:
            logger.error("Failed to calculate quality metrics", error=str(e))
            return {
                "quality_incidents_rate": Decimal("0"),
                "food_safety_score": Decimal("75"),
                "compliance_score_by_standard": {},
                "temperature_compliance_rate": Decimal("100")
            }

    async def _get_in_stock_count(self, db, tenant_id: UUID) -> int:
        """Get count of items currently in stock"""
        try:
            repos = self._get_repositories(db)
            stock_repo = repos['stock_repo']
            
            # Get stock summary and extract in-stock count
            stock_summary = await stock_repo.get_stock_summary_by_tenant(tenant_id)
            return stock_summary.get('in_stock_items', 0)
            
        except Exception as e:
            logger.error("Failed to get in-stock count", error=str(e))
            return 0

    async def _get_ingredient_metrics(self, db, tenant_id: UUID) -> Dict[str, Any]:
        """Get ingredient metrics for business model analysis"""
        try:
            repos = self._get_repositories(db)
            ingredient_repo = repos['ingredient_repo']
            
            # Get all ingredients for the tenant
            ingredients = await ingredient_repo.get_ingredients_by_tenant(tenant_id, limit=1000)
            
            if not ingredients:
                return {
                    "total_types": 0,
                    "avg_stock": 0.0,
                    "finished_product_ratio": 0.0,
                    "supplier_count": 0
                }
            
            # Calculate metrics
            total_types = len(ingredients)
            
            # Calculate average stock per ingredient
            total_stock = sum(float(i.current_stock_level or 0) for i in ingredients)
            avg_stock = total_stock / total_types if total_types > 0 else 0
            
            # Calculate finished product ratio
            finished_products = len([i for i in ingredients if hasattr(i, 'product_type') and i.product_type and i.product_type.value == 'finished_product'])
            finished_ratio = finished_products / total_types if total_types > 0 else 0
            
            # Estimate supplier diversity (simplified)
            supplier_count = len(set(str(i.supplier_id) for i in ingredients if hasattr(i, 'supplier_id') and i.supplier_id)) or 1
            
            return {
                "total_types": total_types,
                "avg_stock": avg_stock,
                "finished_product_ratio": finished_ratio,
                "supplier_count": supplier_count
            }
            
        except Exception as e:
            logger.error("Failed to get ingredient metrics", error=str(e))
            return {
                "total_types": 0,
                "avg_stock": 0.0,
                "finished_product_ratio": 0.0,
                "supplier_count": 0
            }

    async def _analyze_operational_patterns(self, db, tenant_id: UUID) -> Dict[str, Any]:
        """Analyze operational patterns for business model insights"""
        try:
            repos = self._get_repositories(db)
            
            # Get ingredients to analyze patterns
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)
            
            if not ingredients:
                return {
                    "order_frequency": "unknown",
                    "seasonal_variation": "low",
                    "bulk_indicator": "unknown",
                    "scale_indicator": "small"
                }
            
            # Analyze order frequency based on reorder patterns
            frequent_reorders = len([i for i in ingredients if hasattr(i, 'reorder_frequency') and i.reorder_frequency and i.reorder_frequency > 5])
            infrequent_reorders = len([i for i in ingredients if hasattr(i, 'reorder_frequency') and i.reorder_frequency and i.reorder_frequency <= 2])
            
            if frequent_reorders > len(ingredients) * 0.3:
                order_frequency = "high"
            elif infrequent_reorders > len(ingredients) * 0.4:
                order_frequency = "low"
            else:
                order_frequency = "moderate"
            
            # Analyze seasonal variation (simplified estimation)
            seasonal_variation = "moderate"  # Default assumption for bakery business
            
            # Analyze bulk purchasing indicator
            bulk_items = len([i for i in ingredients if hasattr(i, 'bulk_order_quantity') and i.bulk_order_quantity and i.bulk_order_quantity > 100])
            if bulk_items > len(ingredients) * 0.2:
                bulk_indicator = "high"
            elif bulk_items < len(ingredients) * 0.05:
                bulk_indicator = "low"
            else:
                bulk_indicator = "moderate"
            
            # Analyze production scale
            total_ingredients = len(ingredients)
            if total_ingredients > 500:
                scale_indicator = "large"
            elif total_ingredients > 100:
                scale_indicator = "medium"
            else:
                scale_indicator = "small"
            
            return {
                "order_frequency": order_frequency,
                "seasonal_variation": seasonal_variation,
                "bulk_indicator": bulk_indicator,
                "scale_indicator": scale_indicator
            }
            
        except Exception as e:
            logger.error("Failed to analyze operational patterns", error=str(e))
            return {
                "order_frequency": "unknown",
                "seasonal_variation": "low",
                "bulk_indicator": "unknown",
                "scale_indicator": "small"
            }

    async def _generate_model_recommendations(
        self, 
        model: str, 
        ingredient_metrics: Dict[str, Any], 
        operational_patterns: Dict[str, Any]
    ) -> Dict[str, Any]:
        """Generate business model specific recommendations"""
        try:
            recommendations = {
                "specific": [],
                "optimization": []
            }
            
            # Model-specific recommendations
            if model == "central_bakery":
                recommendations["specific"].extend([
                    "Optimize distribution network for multi-location delivery",
                    "Implement centralized procurement for bulk discounts",
                    "Standardize recipes across all production facilities"
                ])
                
                if operational_patterns.get("scale_indicator") == "large":
                    recommendations["optimization"].extend([
                        "Automate inter-facility transfers",
                        "Implement predictive demand forecasting",
                        "Optimize fleet routing for distribution"
                    ])
                    
            elif model == "individual_bakery":
                recommendations["specific"].extend([
                    "Focus on local sourcing to reduce costs",
                    "Implement just-in-time production scheduling",
                    "Optimize single-location workflow efficiency"
                ])
                
                recommendations["optimization"].extend([
                    "Reduce waste through better portion control",
                    "Implement daily production planning",
                    "Optimize oven scheduling for energy efficiency"
                ])
                
            elif model == "mixed":
                recommendations["specific"].extend([
                    "Balance centralized and decentralized operations",
                    "Implement hybrid sourcing strategy",
                    "Maintain flexibility in production planning"
                ])
                
                recommendations["optimization"].extend([
                    "Optimize batch sizes for efficiency",
                    "Implement cross-training for staff flexibility",
                    "Balance inventory across multiple locations"
                ])
            
            # Generic recommendations based on metrics
            if ingredient_metrics.get("finished_product_ratio", 0) > 0.5:
                recommendations["optimization"].append("Focus on finished product quality control")
            
            if operational_patterns.get("order_frequency") == "high":
                recommendations["optimization"].append("Streamline ordering process with automated reordering")
            
            return recommendations
            
        except Exception as e:
            logger.error("Failed to generate model recommendations", error=str(e))
            return {
                "specific": ["Review business model configuration"],
                "optimization": ["Analyze operational data for insights"]
            }

    async def _analyze_inventory_performance(self, db, tenant_id: UUID, days_back: int) -> Dict[str, Any]:
        """Analyze overall inventory performance metrics using real data"""
        try:
            repos = self._get_repositories(db)

            # Get stock and ingredient data
            stock_summary = await repos['stock_repo'].get_stock_summary_by_tenant(tenant_id)
            ingredients = await repos['ingredient_repo'].get_ingredients_by_tenant(tenant_id, limit=1000)

            # Generate movement velocity based on ingredients with cost data (indicates activity)
            active_ingredients = [i for i in ingredients if i.average_cost and i.reorder_quantity]
            movement_velocity = [
                {
                    "week_start": (datetime.now() - timedelta(weeks=1)).isoformat(),
                    "movement_type": "purchase",
                    "movement_count": len(active_ingredients),
                    "total_quantity": sum(float(i.reorder_quantity or 0) for i in active_ingredients),
                    "avg_quantity": sum(float(i.reorder_quantity or 0) for i in active_ingredients) / len(active_ingredients) if active_ingredients else 0
                },
                {
                    "week_start": datetime.now().isoformat(),
                    "movement_type": "production_use",
                    "movement_count": len([i for i in ingredients if i.is_active]),
                    "total_quantity": sum(float(i.low_stock_threshold or 0) for i in ingredients),
                    "avg_quantity": sum(float(i.low_stock_threshold or 0) for i in ingredients) / len(ingredients) if ingredients else 0
                }
            ]

            # Calculate delivery reliability based on stock configuration
            well_stocked_items = len([i for i in ingredients if i.max_stock_level and i.low_stock_threshold])
            total_items = len(ingredients)
            delivery_reliability = Decimal(str(well_stocked_items / total_items * 90)) if total_items > 0 else Decimal("0")  # 90% base for well-configured items

            # Quality consistency based on expiry management
            expired_items = stock_summary.get('expired_items', 0)
            total_stock_items = stock_summary.get('total_stock_items', 1)
            quality_rate = max(0, 100 - (expired_items / total_stock_items * 100)) if total_stock_items > 0 else 100
            quality_consistency = Decimal(str(quality_rate))

            return {
                "movement_velocity": movement_velocity,
                "delivery_reliability": delivery_reliability,
                "quality_consistency": quality_consistency
            }

        except Exception as e:
            logger.error("Failed to analyze inventory performance", error=str(e))
            return {
                "movement_velocity": [],
                "delivery_reliability": Decimal("0"),
                "quality_consistency": Decimal("0")
            }
