"""
Reasoning Types for JTBD Dashboard

Defines standard reasoning data structures for Purchase Orders and Production Batches.
Backend generates structured data, frontend translates using i18n.

IMPORTANT: All text displayed to users is translated in the frontend.
Backend only stores type codes and parameters.
"""

from enum import Enum
from typing import Dict, Any, Optional, List
from pydantic import BaseModel, Field


# ============================================================
# Reasoning Types
# ============================================================

class PurchaseOrderReasoningType(str, Enum):
    """Types of reasoning for why a purchase order was created"""
    LOW_STOCK_DETECTION = "low_stock_detection"
    FORECAST_DEMAND = "forecast_demand"
    SAFETY_STOCK_REPLENISHMENT = "safety_stock_replenishment"
    SUPPLIER_CONTRACT = "supplier_contract"
    SEASONAL_DEMAND = "seasonal_demand"
    PRODUCTION_REQUIREMENT = "production_requirement"
    MANUAL_REQUEST = "manual_request"


class ProductionBatchReasoningType(str, Enum):
    """Types of reasoning for why a production batch was created"""
    FORECAST_DEMAND = "forecast_demand"
    CUSTOMER_ORDER = "customer_order"
    STOCK_REPLENISHMENT = "stock_replenishment"
    SEASONAL_PREPARATION = "seasonal_preparation"
    PROMOTION_EVENT = "promotion_event"
    URGENT_ORDER = "urgent_order"
    REGULAR_SCHEDULE = "regular_schedule"


class ConsequenceSeverity(str, Enum):
    """Severity level of consequences if action is not taken"""
    CRITICAL = "critical"  # Immediate business impact
    HIGH = "high"          # Significant impact within 48h
    MEDIUM = "medium"      # Moderate impact within week
    LOW = "low"            # Minor impact


class PredictionFactorType(str, Enum):
    """Types of factors that contribute to demand prediction"""
    HISTORICAL_PATTERN = "historical_pattern"    # Historical sales/demand patterns
    WEATHER_SUNNY = "weather_sunny"              # Sunny weather impact
    WEATHER_RAINY = "weather_rainy"              # Rainy weather impact
    WEATHER_COLD = "weather_cold"                # Cold weather impact
    WEATHER_HOT = "weather_hot"                  # Hot weather impact
    WEEKEND_BOOST = "weekend_boost"              # Weekend demand increase
    WEEKDAY_PATTERN = "weekday_pattern"          # Day-of-week pattern
    LOCAL_EVENT = "local_event"                  # Local event impact
    HOLIDAY = "holiday"                          # Holiday impact
    INVENTORY_LEVEL = "inventory_level"          # Current inventory consideration
    TREND_SEASONAL = "trend_seasonal"            # Seasonal trend
    PROMOTION_ACTIVE = "promotion_active"        # Active promotion

class PredictionFactor(BaseModel):
    """Individual factor contributing to demand prediction"""
    factor: PredictionFactorType = Field(..., description="Type of prediction factor")
    weight: float = Field(..., description="Weight of this factor (0-1)", ge=0, le=1)
    contribution: float = Field(..., description="Absolute contribution to demand")
    description: Optional[str] = Field(None, description="Human-readable description")
    weather_data: Optional[Dict[str, Any]] = Field(None, description="Weather-specific data")
    inventory_data: Optional[Dict[str, Any]] = Field(None, description="Inventory-specific data")
    historical_data: Optional[Dict[str, Any]] = Field(None, description="Historical pattern data")
    event_data: Optional[Dict[str, Any]] = Field(None, description="Event-specific data")
    confidence: Optional[float] = Field(None, description="Confidence score for this factor", ge=0, le=1)


# ============================================================
# Reasoning Data Models
# ============================================================

class PurchaseOrderReasoningData(BaseModel):
    """
    Structured reasoning data for purchase orders

    Example:
    {
        "type": "low_stock_detection",
        "parameters": {
            "supplier_name": "Harinas del Norte",
            "product_names": ["Flour Type 55", "Flour Type 45"],
            "current_stock_kg": 45.5,
            "required_stock_kg": 200,
            "days_until_stockout": 3,
            "threshold_percentage": 20
        },
        "consequence": {
            "type": "stockout_risk",
            "severity": "high",
            "impact_days": 3,
            "affected_products": ["Baguette", "Croissant"],
            "estimated_lost_orders": 15
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "forecast_confidence": 0.85,
            "ai_assisted": true
        }
    }
    """
    type: PurchaseOrderReasoningType = Field(..., description="Type of reasoning")
    parameters: Dict[str, Any] = Field(..., description="Parameters for i18n interpolation")
    consequence: Optional[Dict[str, Any]] = Field(None, description="What happens if not approved")
    metadata: Optional[Dict[str, Any]] = Field(None, description="Additional context")


class ProductionBatchReasoningData(BaseModel):
    """
    Structured reasoning data for production batches

    Example:
    {
        "type": "forecast_demand",
        "parameters": {
            "product_name": "Croissant",
            "predicted_demand": 500,
            "current_stock": 120,
            "production_needed": 380,
            "target_date": "2025-11-08",
            "confidence_score": 0.87
        },
        "urgency": {
            "level": "normal",
            "ready_by_time": "08:00",
            "customer_commitment": false
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "forecast_id": "uuid-here",
            "ai_assisted": true
        }
    }
    """
    type: ProductionBatchReasoningType = Field(..., description="Type of reasoning")
    parameters: Dict[str, Any] = Field(..., description="Parameters for i18n interpolation")
    urgency: Optional[Dict[str, Any]] = Field(None, description="Urgency information")
    metadata: Optional[Dict[str, Any]] = Field(None, description="Additional context")


# ============================================================
# Helper Functions
# ============================================================

def create_po_reasoning_low_stock(
    supplier_name: str,
    product_names: list,  # Kept for backward compatibility
    current_stock: float = None,  # Kept for backward compatibility
    required_stock: float = None,  # Kept for backward compatibility
    days_until_stockout: int = None,  # Kept for backward compatibility
    threshold_percentage: int = 20,
    affected_products: Optional[list] = None,
    estimated_lost_orders: Optional[int] = None,
    # New enhanced parameters
    product_details: Optional[list] = None,
    supplier_lead_time_days: Optional[int] = None,
    order_urgency: Optional[str] = None,
    affected_production_batches: Optional[list] = None,
    estimated_production_loss_eur: Optional[float] = None
) -> Dict[str, Any]:
    """
    Create reasoning data for low stock detection with supply chain intelligence

    Supports two modes:
    1. Legacy mode: Uses product_names, current_stock, days_until_stockout (simple)
    2. Enhanced mode: Uses product_details with per-product depletion analysis

    Args:
        supplier_name: Name of the supplier
        product_names: List of product names (legacy, for backward compatibility)
        current_stock: Current stock level (legacy)
        required_stock: Required stock level (legacy)
        days_until_stockout: Days until stock runs out (legacy)
        threshold_percentage: Stock threshold percentage
        affected_products: Products that will be affected (legacy)
        estimated_lost_orders: Estimated number of lost orders (legacy)
        product_details: List of dicts with per-product analysis (NEW):
            [
                {
                    "product_name": str,
                    "current_stock_kg": float,
                    "daily_consumption_kg": float,
                    "days_until_depletion": float,
                    "reorder_point_kg": float,
                    "safety_stock_days": int,
                    "criticality": str  # "critical", "urgent", "important", "normal"
                },
                ...
            ]
        supplier_lead_time_days: Supplier delivery lead time in days (NEW)
        order_urgency: Overall order urgency: "critical", "urgent", "important", "normal" (NEW)
        affected_production_batches: List of batch numbers that will be impacted (NEW)
        estimated_production_loss_eur: Estimated financial loss if not ordered (NEW)

    Returns:
        Reasoning data dictionary with enhanced supply chain intelligence
    """
    # Determine mode based on parameters
    enhanced_mode = product_details is not None

    if enhanced_mode:
        # Enhanced mode: Use detailed per-product analysis
        # Extract critical products for summary
        critical_products = [
            p for p in product_details
            if p.get("criticality") in ["critical", "urgent"]
        ]

        # Find most critical depletion time
        min_depletion_days = min(
            [p.get("days_until_depletion", 999) for p in product_details],
            default=7
        )
        min_depletion_hours = round(min_depletion_days * 24, 1)

        # Calculate safety margin with supplier lead time
        safety_margin_days = None
        if supplier_lead_time_days is not None:
            safety_margin_days = min_depletion_days - supplier_lead_time_days

        # All product names for backward compatibility
        all_product_names = [p.get("product_name", "Product") for p in product_details]

        parameters = {
            "supplier_name": supplier_name,
            "supplier_lead_time_days": supplier_lead_time_days or 2,
            "product_details": product_details,
            "product_names": all_product_names,  # For i18n join operations
            "product_count": len(product_details),
            "critical_products": [p.get("product_name") for p in critical_products],
            "critical_product_count": len(critical_products),
            "min_depletion_days": round(min_depletion_days, 2),
            "min_depletion_hours": min_depletion_hours,
            "safety_margin_days": round(safety_margin_days, 2) if safety_margin_days is not None else None,
            "order_urgency": order_urgency or "normal",
            "affected_batches": affected_production_batches or [],
            "affected_batches_count": len(affected_production_batches) if affected_production_batches else 0,
            "potential_loss_eur": round(estimated_production_loss_eur, 2) if estimated_production_loss_eur else 0,
            "threshold_percentage": threshold_percentage
        }

        # Enhanced consequence calculation
        severity = ConsequenceSeverity.CRITICAL.value if order_urgency == "critical" else \
                   ConsequenceSeverity.HIGH.value if order_urgency in ["urgent", "important"] else \
                   ConsequenceSeverity.MEDIUM.value

        consequence = {
            "type": "stockout_risk_detailed",
            "severity": severity,
            "impact_days": round(min_depletion_days, 2),
            "affected_production_batches": affected_production_batches or [],
            "estimated_production_loss_eur": round(estimated_production_loss_eur, 2) if estimated_production_loss_eur else 0,
            "critical_items": [p.get("product_name") for p in critical_products]
        }

    else:
        # Legacy mode: Use simple parameters (backward compatibility)
        parameters = {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "current_stock": current_stock,
            "required_stock": required_stock,
            "days_until_stockout": days_until_stockout,
            "threshold_percentage": threshold_percentage,
            "stock_percentage": round((current_stock / required_stock * 100), 1) if (required_stock and required_stock > 0) else 0
        }

        consequence = {
            "type": "stockout_risk",
            "severity": ConsequenceSeverity.HIGH.value if days_until_stockout and days_until_stockout <= 2 else ConsequenceSeverity.MEDIUM.value,
            "impact_days": days_until_stockout or 7,
            "affected_products": affected_products or [],
            "estimated_lost_orders": estimated_lost_orders or 0
        }

    return {
        "type": PurchaseOrderReasoningType.LOW_STOCK_DETECTION.value,
        "parameters": parameters,
        "consequence": consequence,
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "ai_assisted": True,
            "enhanced_mode": enhanced_mode
        }
    }


def create_po_reasoning_forecast_demand(
    supplier_name: str,
    product_names: list,
    forecast_period_days: int,
    total_demand: float,
    forecast_confidence: float = 0.85
) -> Dict[str, Any]:
    """Create reasoning data for forecast-based demand"""
    return {
        "type": PurchaseOrderReasoningType.FORECAST_DEMAND.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "forecast_period_days": forecast_period_days,
            "total_demand": total_demand,
            "forecast_confidence": round(forecast_confidence * 100, 1)
        },
        "consequence": {
            "type": "insufficient_supply",
            "severity": ConsequenceSeverity.MEDIUM.value,
            "impact_days": forecast_period_days
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "forecast_confidence": forecast_confidence,
            "ai_assisted": True
        }
    }


def create_po_reasoning_supplier_contract(
    supplier_name: str,
    product_names: list,
    contract_terms: str = "monthly",
    contract_quantity: float = 0
) -> Dict[str, Any]:
    """Create reasoning data for supplier contract fulfillment"""
    return {
        "type": PurchaseOrderReasoningType.SUPPLIER_CONTRACT.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "contract_terms": contract_terms,
            "contract_quantity": contract_quantity
        },
        "consequence": {
            "type": "contract_breach",
            "severity": ConsequenceSeverity.HIGH.value,
            "impact": "contract_penalties"
        },
        "metadata": {
            "trigger_source": "contract_schedule",
            "ai_assisted": False
        }
    }


def create_po_reasoning_safety_stock(
    supplier_name: str,
    product_names: list,
    current_safety_stock: float,
    target_safety_stock: float,
    reorder_point: float
) -> Dict[str, Any]:
    """Create reasoning data for safety stock replenishment"""
    return {
        "type": PurchaseOrderReasoningType.SAFETY_STOCK_REPLENISHMENT.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "current_safety_stock": round(current_safety_stock, 1),
            "target_safety_stock": round(target_safety_stock, 1),
            "reorder_point": round(reorder_point, 1)
        },
        "consequence": {
            "type": "stockout_risk",
            "severity": ConsequenceSeverity.MEDIUM.value,
            "impact": "reduced_buffer"
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "ai_assisted": True
        }
    }


def create_po_reasoning_seasonal_demand(
    supplier_name: str,
    product_names: list,
    season: str,
    expected_demand_increase_pct: float
) -> Dict[str, Any]:
    """Create reasoning data for seasonal demand preparation"""
    return {
        "type": PurchaseOrderReasoningType.SEASONAL_DEMAND.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "season": season,
            "expected_demand_increase_pct": round(expected_demand_increase_pct, 1)
        },
        "consequence": {
            "type": "missed_opportunity",
            "severity": ConsequenceSeverity.MEDIUM.value,
            "impact": "lost_seasonal_sales"
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "ai_assisted": True
        }
    }


def create_po_reasoning_production_requirement(
    supplier_name: str,
    product_names: list,
    production_batches: int,
    required_by_date: str
) -> Dict[str, Any]:
    """Create reasoning data for production requirement"""
    return {
        "type": PurchaseOrderReasoningType.PRODUCTION_REQUIREMENT.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "production_batches": production_batches,
            "required_by_date": required_by_date
        },
        "consequence": {
            "type": "production_delay",
            "severity": ConsequenceSeverity.HIGH.value,
            "impact": "blocked_production"
        },
        "metadata": {
            "trigger_source": "production_schedule",
            "ai_assisted": True
        }
    }


def create_po_reasoning_manual_request(
    supplier_name: str,
    product_names: list,
    requested_by: str,
    reason: str = "manual_order"
) -> Dict[str, Any]:
    """Create reasoning data for manual purchase request"""
    return {
        "type": PurchaseOrderReasoningType.MANUAL_REQUEST.value,
        "parameters": {
            "supplier_name": supplier_name,
            "product_names": product_names,
            "product_count": len(product_names),
            "requested_by": requested_by,
            "reason": reason
        },
        "consequence": None,
        "metadata": {
            "trigger_source": "manual",
            "ai_assisted": False
        }
    }



def create_batch_reasoning_forecast_demand(
    product_name: str,
    predicted_demand: float,
    current_stock: float = None,
    production_needed: float = None,
    target_date: str = None,
    historical_average: float = None,
    variance_percent: float = None,
    variance_reason: str = None,
    confidence_score: float = 0.85,
    factors: Optional[List[Dict[str, Any]]] = None,
    urgency_level: str = "normal",
    ready_by_time: str = "08:00",
    forecast_id: Optional[str] = None,
    target_sales: float = None,
    weather_impact: Dict[str, Any] = None
) -> Dict[str, Any]:
    """
    Create unified reasoning data for forecast-based production with optional enhanced factors

    This function consolidates both basic and enhanced forecast demand reasoning.

    Args:
        product_name: Name of the product
        predicted_demand: Predicted demand quantity
        current_stock: Current stock level (optional for basic reasoning)
        production_needed: Needed production quantity (optional for basic reasoning)
        target_date: Target date for production (optional for basic reasoning)
        historical_average: Historical average demand (for enhanced reasoning)
        variance_percent: Percentage variance from historical average (for enhanced reasoning)
        variance_reason: Reason for variance (for enhanced reasoning)
        confidence_score: Confidence score (0-1)
        factors: List of factors contributing to the prediction (for enhanced reasoning)
        urgency_level: Urgency level ("normal", "medium", "high", "urgent")
        ready_by_time: Time when batch should be ready
        forecast_id: UUID of the forecast for traceability
        target_sales: Target sales figures
        weather_impact: Detailed weather impact data

    Returns:
        Reasoning data with appropriate level of detail based on provided parameters
    """
    # Build parameters dict
    params = {
        "product_name": product_name,
        "predicted_demand": round(predicted_demand, 1),
    }

    # Add basic reasoning parameters if provided
    if current_stock is not None:
        params["current_stock"] = round(current_stock, 1)
    if production_needed is not None:
        params["production_needed"] = round(production_needed, 1)
    if target_date is not None:
        params["target_date"] = target_date
    if target_sales is not None:
        params["target_sales"] = round(target_sales, 1)
    if weather_impact is not None:
        params["weather_impact"] = weather_impact

    # Add enhanced reasoning parameters if provided
    if historical_average is not None:
        params["historical_average"] = round(historical_average, 1)
    if variance_percent is not None:
        params["variance_percent"] = round(variance_percent, 1)
    if variance_reason is not None:
        params["variance_reason"] = variance_reason
    if factors:
        # Ensure factors is a list
        factors_list = factors or []
        # Convert factors to proper format if they're not already PredictionFactor objects
        formatted_factors = []
        for factor in factors_list:
            if isinstance(factor, dict):
                # Already in dict format
                formatted_factors.append(factor)
            else:
                # Convert PredictionFactor to dict
                formatted_factors.append({
                    "factor": factor.factor.value if hasattr(factor, 'factor') else str(factor.factor),
                    "weight": factor.weight,
                    "contribution": factor.contribution,
                    "description": factor.description,
                    "weather_data": factor.weather_data,
                    "inventory_data": factor.inventory_data,
                    "historical_data": factor.historical_data,
                    "event_data": factor.event_data,
                    "confidence": factor.confidence
                })
        params["factors"] = formatted_factors

    return {
        "type": ProductionBatchReasoningType.FORECAST_DEMAND.value,
        "parameters": params,
        "urgency": {
            "level": urgency_level,
            "ready_by_time": ready_by_time,
            "customer_commitment": False
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "confidence_score": confidence_score,
            "ai_assisted": True,
            "enhanced_reasoning": any([
                historical_average is not None,
                variance_percent is not None,
                variance_reason is not None,
                factors is not None and len(factors) > 0,
                weather_impact is not None
            ])
        }
    }


def create_batch_reasoning_customer_order(
    product_name: str,
    customer_name: str,
    order_quantity: float,
    delivery_date: str,
    order_number: str
) -> Dict[str, Any]:
    """Create reasoning data for customer order fulfillment"""
    return {
        "type": ProductionBatchReasoningType.CUSTOMER_ORDER.value,
        "parameters": {
            "product_name": product_name,
            "customer_name": customer_name,
            "order_quantity": round(order_quantity, 1),
            "delivery_date": delivery_date,
            "order_number": order_number
        },
        "urgency": {
            "level": "high",
            "ready_by_time": "07:00",
            "customer_commitment": True
        },
        "metadata": {
            "trigger_source": "customer_order",
            "ai_assisted": False
        }
    }


def create_batch_reasoning_regular_schedule(
    product_name: str,
    scheduled_quantity: float,
    production_schedule: str = "daily"
) -> Dict[str, Any]:
    """Create reasoning data for regular scheduled production"""
    return {
        "type": ProductionBatchReasoningType.REGULAR_SCHEDULE.value,
        "parameters": {
            "product_name": product_name,
            "scheduled_quantity": round(scheduled_quantity, 1),
            "production_schedule": production_schedule
        },
        "urgency": {
            "level": "normal",
            "ready_by_time": "08:00",
            "customer_commitment": False
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "ai_assisted": False
        }
    }


def create_batch_reasoning_stock_replenishment(
    product_name: str,
    current_stock: float,
    minimum_stock: float,
    replenishment_quantity: float
) -> Dict[str, Any]:
    """Create reasoning data for stock replenishment production"""
    return {
        "type": ProductionBatchReasoningType.STOCK_REPLENISHMENT.value,
        "parameters": {
            "product_name": product_name,
            "current_stock": round(current_stock, 1),
            "minimum_stock": round(minimum_stock, 1),
            "replenishment_quantity": round(replenishment_quantity, 1)
        },
        "urgency": {
            "level": "medium",
            "ready_by_time": "07:30",
            "customer_commitment": False
        },
        "metadata": {
            "trigger_source": "inventory_alert",
            "ai_assisted": True
        }
    }


def create_batch_reasoning_seasonal_preparation(
    product_name: str,
    season: str,
    expected_demand: float,
    preparation_quantity: float
) -> Dict[str, Any]:
    """Create reasoning data for seasonal preparation production"""
    return {
        "type": ProductionBatchReasoningType.SEASONAL_PREPARATION.value,
        "parameters": {
            "product_name": product_name,
            "season": season,
            "expected_demand": round(expected_demand, 1),
            "preparation_quantity": round(preparation_quantity, 1)
        },
        "urgency": {
            "level": "normal",
            "ready_by_time": "08:00",
            "customer_commitment": False
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "ai_assisted": True
        }
    }


def create_batch_reasoning_promotion_event(
    product_name: str,
    event_name: str,
    event_date: str,
    promotional_quantity: float
) -> Dict[str, Any]:
    """Create reasoning data for promotional event production"""
    return {
        "type": ProductionBatchReasoningType.PROMOTION_EVENT.value,
        "parameters": {
            "product_name": product_name,
            "event_name": event_name,
            "event_date": event_date,
            "promotional_quantity": round(promotional_quantity, 1)
        },
        "urgency": {
            "level": "high",
            "ready_by_time": "06:00",
            "customer_commitment": True
        },
        "metadata": {
            "trigger_source": "manual",
            "ai_assisted": False
        }
    }


def create_batch_reasoning_urgent_order(
    product_name: str,
    customer_name: str,
    urgent_quantity: float,
    required_by_time: str,
    reason: str = "urgent_request"
) -> Dict[str, Any]:
    """Create reasoning data for urgent order production"""
    return {
        "type": ProductionBatchReasoningType.URGENT_ORDER.value,
        "parameters": {
            "product_name": product_name,
            "customer_name": customer_name,
            "urgent_quantity": round(urgent_quantity, 1),
            "required_by_time": required_by_time,
            "reason": reason
        },
        "urgency": {
            "level": "urgent",
            "ready_by_time": required_by_time,
            "customer_commitment": True
        },
        "metadata": {
            "trigger_source": "urgent_order",
            "ai_assisted": False
        }
    }


def create_production_batch_reasoning(
    product_name: str,
    predicted_demand: float,
    current_stock: float = None,
    production_needed: float = None,
    target_date: str = None,
    historical_average: float = None,
    variance_percent: float = None,
    variance_reason: str = None,
    confidence_score: float = 0.85,
    factors: Optional[List[Dict[str, Any]]] = None,
    urgency_level: str = "normal",
    ready_by_time: str = "08:00",
    forecast_id: Optional[str] = None,
    target_sales: float = None,
    weather_impact: Dict[str, Any] = None,
    base_demand: float = None,
    weather_data: Dict[str, Any] = None,
    weather_adjustment_factor: float = None,
    production_type: str = "forecast_demand"  # Add this to allow different production reasoning types
) -> Dict[str, Any]:
    """
    Create unified reasoning data for production batches that combines both forecast demand and weather influence

    This function consolidates both basic and enhanced forecast demand reasoning as well as weather-influenced production reasoning.

    Args:
        product_name: Name of the product
        predicted_demand: Predicted demand quantity
        current_stock: Current stock level (optional for basic reasoning)
        production_needed: Needed production quantity (optional for basic reasoning)
        target_date: Target date for production (optional for basic reasoning)
        historical_average: Historical average demand (for enhanced reasoning)
        variance_percent: Percentage variance from historical average (for enhanced reasoning)
        variance_reason: Reason for variance (for enhanced reasoning)
        confidence_score: Confidence score (0-1)
        factors: List of factors contributing to the prediction (for enhanced reasoning)
        urgency_level: Urgency level ("normal", "medium", "high", "urgent")
        ready_by_time: Time when batch should be ready
        forecast_id: UUID of the forecast for traceability
        target_sales: Target sales figures
        weather_impact: Detailed weather impact data
        base_demand: Base demand without weather influence (for weather-influenced reasoning)
        weather_data: Weather information affecting production, with keys:
            - temperature: Current/future temperature
            - condition: Weather condition (sunny, rainy, snowy, etc.)
            - humidity: Humidity level
            - impact_factor: Multiplier for weather impact on demand
        weather_adjustment_factor: Factor by which weather adjusted the demand
        production_type: Type of production reasoning ("forecast_demand", "weather_influenced", "forecast_and_weather", etc.)

    Returns:
        Reasoning data with appropriate level of detail based on provided parameters
    """
    # Build parameters dict
    params = {
        "product_name": product_name,
        "predicted_demand": round(predicted_demand, 1),
    }

    # Add basic reasoning parameters if provided
    if current_stock is not None:
        params["current_stock"] = round(current_stock, 1)
    if production_needed is not None:
        params["production_needed"] = round(production_needed, 1)
    if target_date is not None:
        params["target_date"] = target_date
    if target_sales is not None:
        params["target_sales"] = round(target_sales, 1)

    # Add weather-related data if provided
    if weather_data is not None:
        # Calculate weather impact details
        weather_impact_factor = weather_adjustment_factor or weather_data.get('impact_factor', 1.0)
        temperature = weather_data.get('temperature', 'N/A')
        condition = weather_data.get('condition', 'unknown')
        humidity = weather_data.get('humidity', 'N/A')

        # Calculate weather-adjusted base demand if not provided
        if base_demand is None:
            base_demand = predicted_demand / weather_impact_factor if weather_impact_factor != 0 else predicted_demand

        params["base_demand"] = round(base_demand, 1)
        params["weather_adjustment_factor"] = round(weather_impact_factor, 2)
        params["weather_data"] = weather_data
        params["weather_condition"] = condition
        params["temperature"] = temperature
        params["humidity"] = humidity

    elif weather_impact is not None:
        # Handle legacy weather_impact parameter
        params["weather_impact"] = weather_impact

    # Add enhanced reasoning parameters if provided
    if historical_average is not None:
        params["historical_average"] = round(historical_average, 1)
    if variance_percent is not None:
        params["variance_percent"] = round(variance_percent, 1)
    if variance_reason is not None:
        params["variance_reason"] = variance_reason
    if factors:
        # Ensure factors is a list
        factors_list = factors or []
        # Convert factors to proper format if they're not already PredictionFactor objects
        formatted_factors = []
        for factor in factors_list:
            if isinstance(factor, dict):
                # Already in dict format
                formatted_factors.append(factor)
            else:
                # Convert PredictionFactor to dict
                formatted_factors.append({
                    "factor": factor.factor.value if hasattr(factor, 'factor') else str(factor.factor),
                    "weight": factor.weight,
                    "contribution": factor.contribution,
                    "description": factor.description,
                    "weather_data": factor.weather_data,
                    "inventory_data": factor.inventory_data,
                    "historical_data": factor.historical_data,
                    "event_data": factor.event_data,
                    "confidence": factor.confidence
                })
        params["factors"] = formatted_factors

    # Determine the production type and set accordingly
    actual_type = ProductionBatchReasoningType.FORECAST_DEMAND.value

    # Create metadata
    metadata = {
        "trigger_source": "orchestrator_auto",
        "confidence_score": confidence_score,
        "ai_assisted": True,
        "enhanced_reasoning": any([
            historical_average is not None,
            variance_percent is not None,
            variance_reason is not None,
            factors is not None and len(factors) > 0,
            weather_impact is not None,
            weather_data is not None
        ])
    }

    # Add weather-specific metadata if applicable
    if weather_data is not None or weather_impact is not None:
        metadata["weather_influenced"] = True

    return {
        "type": actual_type,
        "parameters": params,
        "urgency": {
            "level": urgency_level,
            "ready_by_time": ready_by_time,
            "customer_commitment": False
        },
        "metadata": metadata
    }


def create_batch_reasoning_weather_influenced(
    product_name: str,
    predicted_demand: float,
    weather_data: Dict[str, Any],
    base_demand: float = None,
    current_stock: float = None,
    production_needed: float = None,
    target_date: str = None,
    confidence_score: float = 0.85,
    factors: Optional[List[Dict[str, Any]]] = None,
    urgency_level: str = "normal",
    ready_by_time: str = "08:00",
    forecast_id: Optional[str] = None
) -> Dict[str, Any]:
    """
    Create reasoning data for production batches influenced by weather factors

    This function specifically handles weather-influenced production reasoning,
    which is important for bakery operations where weather significantly impacts demand.

    Args:
        product_name: Name of the product
        predicted_demand: Predicted demand quantity considering weather impact
        weather_data: Weather information affecting production, with keys:
            - temperature: Current/future temperature
            - condition: Weather condition (sunny, rainy, snowy, etc.)
            - humidity: Humidity level
            - impact_factor: Multiplier for weather impact on demand
        base_demand: Base demand without weather influence (optional)
        current_stock: Current stock level
        production_needed: Needed production quantity
        target_date: Target date for production
        confidence_score: Confidence score (0-1)
        factors: Additional prediction factors
        urgency_level: Urgency level ("normal", "medium", "high", "urgent")
        ready_by_time: Time when batch should be ready
        forecast_id: UUID of the forecast for traceability

    Returns:
        Reasoning data with detailed weather influence information
    """
    # Calculate weather impact details
    weather_impact_factor = weather_data.get('impact_factor', 1.0)
    temperature = weather_data.get('temperature', 'N/A')
    condition = weather_data.get('condition', 'unknown')
    humidity = weather_data.get('humidity', 'N/A')

    # Calculate weather-adjusted base demand
    if base_demand is None:
        base_demand = predicted_demand / weather_impact_factor

    # Build parameters
    params = {
        "product_name": product_name,
        "predicted_demand": round(predicted_demand, 1),
        "base_demand": round(base_demand, 1),
        "weather_adjustment_factor": round(weather_impact_factor, 2),
        "weather_data": weather_data,
        "weather_condition": condition,
        "temperature": temperature,
        "humidity": humidity
    }

    # Add optional basic reasoning parameters
    if current_stock is not None:
        params["current_stock"] = round(current_stock, 1)
    if production_needed is not None:
        params["production_needed"] = round(production_needed, 1)
    if target_date is not None:
        params["target_date"] = target_date

    # Add enhanced reasoning parameters if provided
    if factors:
        # Ensure factors is a list
        factors_list = factors or []
        # Convert factors to proper format if they're not already PredictionFactor objects
        formatted_factors = []
        for factor in factors_list:
            if isinstance(factor, dict):
                # Already in dict format
                formatted_factors.append(factor)
            else:
                # Convert PredictionFactor to dict
                formatted_factors.append({
                    "factor": factor.factor.value if hasattr(factor, 'factor') else str(factor.factor),
                    "weight": factor.weight,
                    "contribution": factor.contribution,
                    "description": factor.description,
                    "weather_data": factor.weather_data,
                    "inventory_data": factor.inventory_data,
                    "historical_data": factor.historical_data,
                    "event_data": factor.event_data,
                    "confidence": factor.confidence
                })
        params["factors"] = formatted_factors

    return {
        "type": ProductionBatchReasoningType.FORECAST_DEMAND.value,
        "parameters": params,
        "urgency": {
            "level": urgency_level,
            "ready_by_time": ready_by_time,
            "customer_commitment": False
        },
        "metadata": {
            "trigger_source": "orchestrator_auto",
            "confidence_score": confidence_score,
            "ai_assisted": True,
            "enhanced_reasoning": True,
            "weather_influenced": True
        }
    }

