# ================================================================
# services/orders/app/schemas/order_schemas.py
# ================================================================
"""
Order-related Pydantic schemas for Orders Service
"""

from datetime import datetime, date
from decimal import Decimal
from typing import Optional, List, Dict, Any
from uuid import UUID
from pydantic import BaseModel, Field, validator

from app.models.enums import (
    CustomerType, DeliveryMethod, PaymentTerms, PaymentMethod, PaymentStatus,
    CustomerSegment, PriorityLevel, OrderType, OrderStatus, OrderSource,
    SalesChannel, BusinessModel, DeliveryStatus
)


# ===== Customer Schemas =====

class CustomerBase(BaseModel):
    name: str = Field(..., min_length=1, max_length=200)
    business_name: Optional[str] = Field(None, max_length=200)
    customer_type: CustomerType = Field(default=CustomerType.INDIVIDUAL)
    email: Optional[str] = Field(None, max_length=255)
    phone: Optional[str] = Field(None, max_length=50)
    address_line1: Optional[str] = Field(None, max_length=255)
    address_line2: Optional[str] = Field(None, max_length=255)
    city: Optional[str] = Field(None, max_length=100)
    state: Optional[str] = Field(None, max_length=100)
    postal_code: Optional[str] = Field(None, max_length=20)
    country: str = Field(default="US", max_length=100)
    is_active: bool = Field(default=True)
    preferred_delivery_method: DeliveryMethod = Field(default=DeliveryMethod.DELIVERY)
    payment_terms: PaymentTerms = Field(default=PaymentTerms.IMMEDIATE)
    credit_limit: Optional[Decimal] = Field(None, ge=0)
    discount_percentage: Decimal = Field(default=Decimal("0.00"), ge=0, le=100)
    customer_segment: CustomerSegment = Field(default=CustomerSegment.REGULAR)
    priority_level: PriorityLevel = Field(default=PriorityLevel.NORMAL)
    special_instructions: Optional[str] = None
    delivery_preferences: Optional[Dict[str, Any]] = None
    product_preferences: Optional[Dict[str, Any]] = None

    class Config:
        from_attributes = True
        use_enum_values = True


class CustomerCreate(CustomerBase):
    customer_code: str = Field(..., min_length=1, max_length=50)


class CustomerUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=200)
    business_name: Optional[str] = Field(None, max_length=200)
    customer_type: Optional[CustomerType] = None
    email: Optional[str] = Field(None, max_length=255)
    phone: Optional[str] = Field(None, max_length=50)
    address_line1: Optional[str] = Field(None, max_length=255)
    address_line2: Optional[str] = Field(None, max_length=255)
    city: Optional[str] = Field(None, max_length=100)
    state: Optional[str] = Field(None, max_length=100)
    postal_code: Optional[str] = Field(None, max_length=20)
    country: Optional[str] = Field(None, max_length=100)
    is_active: Optional[bool] = None
    preferred_delivery_method: Optional[DeliveryMethod] = None
    payment_terms: Optional[PaymentTerms] = None
    credit_limit: Optional[Decimal] = Field(None, ge=0)
    discount_percentage: Optional[Decimal] = Field(None, ge=0, le=100)
    customer_segment: Optional[CustomerSegment] = None
    priority_level: Optional[PriorityLevel] = None
    special_instructions: Optional[str] = None
    delivery_preferences: Optional[Dict[str, Any]] = None
    product_preferences: Optional[Dict[str, Any]] = None

    class Config:
        from_attributes = True
        use_enum_values = True


class CustomerResponse(CustomerBase):
    id: UUID
    tenant_id: UUID
    customer_code: str
    total_orders: int
    total_spent: Decimal
    average_order_value: Decimal
    last_order_date: Optional[datetime]
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ===== Order Item Schemas =====

class OrderItemBase(BaseModel):
    product_id: UUID
    product_name: str = Field(..., min_length=1, max_length=200)
    product_sku: Optional[str] = Field(None, max_length=100)
    product_category: Optional[str] = Field(None, max_length=100)
    quantity: Decimal = Field(..., gt=0)
    unit_of_measure: str = Field(default="each", max_length=50)
    weight: Optional[Decimal] = Field(None, ge=0)
    unit_price: Decimal = Field(..., ge=0)
    line_discount: Decimal = Field(default=Decimal("0.00"), ge=0)
    product_specifications: Optional[Dict[str, Any]] = None
    customization_details: Optional[str] = None
    special_instructions: Optional[str] = None
    recipe_id: Optional[UUID] = None


class OrderItemCreate(OrderItemBase):
    pass


class OrderItemUpdate(BaseModel):
    quantity: Optional[Decimal] = Field(None, gt=0)
    unit_price: Optional[Decimal] = Field(None, ge=0)
    line_discount: Optional[Decimal] = Field(None, ge=0)
    product_specifications: Optional[Dict[str, Any]] = None
    customization_details: Optional[str] = None
    special_instructions: Optional[str] = None


class OrderItemResponse(OrderItemBase):
    id: UUID
    order_id: UUID
    line_total: Decimal
    status: str
    created_at: datetime
    updated_at: datetime

    class Config:
        from_attributes = True


# ===== Order Schemas =====

class OrderBase(BaseModel):
    customer_id: UUID
    order_type: OrderType = Field(default=OrderType.STANDARD)
    priority: PriorityLevel = Field(default=PriorityLevel.NORMAL)
    requested_delivery_date: datetime
    delivery_method: DeliveryMethod = Field(default=DeliveryMethod.DELIVERY)
    delivery_address: Optional[Dict[str, Any]] = None
    delivery_instructions: Optional[str] = None
    delivery_window_start: Optional[datetime] = None
    delivery_window_end: Optional[datetime] = None
    discount_percentage: Decimal = Field(default=Decimal("0.00"), ge=0, le=100)
    delivery_fee: Decimal = Field(default=Decimal("0.00"), ge=0)
    payment_method: Optional[PaymentMethod] = None
    payment_terms: PaymentTerms = Field(default=PaymentTerms.IMMEDIATE)
    special_instructions: Optional[str] = None
    custom_requirements: Optional[Dict[str, Any]] = None
    allergen_warnings: Optional[Dict[str, Any]] = None
    order_source: OrderSource = Field(default=OrderSource.MANUAL)
    sales_channel: SalesChannel = Field(default=SalesChannel.DIRECT)
    order_origin: Optional[str] = Field(None, max_length=100)
    communication_preferences: Optional[Dict[str, Any]] = None

    class Config:
        from_attributes = True
        use_enum_values = True


class OrderCreate(OrderBase):
    tenant_id: UUID
    items: List[OrderItemCreate] = Field(..., min_items=1)


class OrderUpdate(BaseModel):
    status: Optional[OrderStatus] = None
    priority: Optional[PriorityLevel] = None
    requested_delivery_date: Optional[datetime] = None
    confirmed_delivery_date: Optional[datetime] = None
    delivery_method: Optional[DeliveryMethod] = None
    delivery_address: Optional[Dict[str, Any]] = None
    delivery_instructions: Optional[str] = None
    delivery_window_start: Optional[datetime] = None
    delivery_window_end: Optional[datetime] = None
    payment_method: Optional[PaymentMethod] = None
    payment_status: Optional[PaymentStatus] = None
    special_instructions: Optional[str] = None
    custom_requirements: Optional[Dict[str, Any]] = None
    allergen_warnings: Optional[Dict[str, Any]] = None

    class Config:
        from_attributes = True
        use_enum_values = True


class OrderResponse(OrderBase):
    id: UUID
    tenant_id: UUID
    order_number: str
    status: str
    order_date: datetime
    confirmed_delivery_date: Optional[datetime]
    actual_delivery_date: Optional[datetime]
    subtotal: Decimal
    discount_amount: Decimal
    tax_amount: Decimal
    total_amount: Decimal
    payment_status: str
    business_model: Optional[str]
    estimated_business_model: Optional[str]
    production_batch_id: Optional[UUID]
    quality_score: Optional[Decimal]
    customer_rating: Optional[int]
    created_at: datetime
    updated_at: datetime
    items: List[OrderItemResponse] = []

    class Config:
        from_attributes = True


# ===== Dashboard and Analytics Schemas =====

class OrdersDashboardSummary(BaseModel):
    """Summary data for orders dashboard"""
    # Current period metrics
    total_orders_today: int
    total_orders_this_week: int
    total_orders_this_month: int
    
    # Revenue metrics
    revenue_today: Decimal
    revenue_this_week: Decimal
    revenue_this_month: Decimal
    
    # Order status breakdown
    pending_orders: int
    confirmed_orders: int
    in_production_orders: int
    ready_orders: int
    delivered_orders: int
    
    # Customer metrics
    total_customers: int
    new_customers_this_month: int
    repeat_customers_rate: Decimal
    
    # Performance metrics
    average_order_value: Decimal
    order_fulfillment_rate: Decimal
    on_time_delivery_rate: Decimal
    
    # Business model detection
    business_model: Optional[str]
    business_model_confidence: Optional[Decimal]
    
    # Recent activity
    recent_orders: List[OrderResponse]
    high_priority_orders: List[OrderResponse]


class DemandRequirements(BaseModel):
    """Demand requirements for production planning"""
    date: date
    tenant_id: UUID
    
    # Product demand breakdown
    product_demands: List[Dict[str, Any]]
    
    # Aggregate metrics
    total_orders: int
    total_quantity: Decimal
    total_value: Decimal
    
    # Business context
    business_model: Optional[str]
    rush_orders_count: int
    special_requirements: List[str]
    
    # Timing requirements
    earliest_delivery: datetime
    latest_delivery: datetime
    average_lead_time_hours: int
