# services/sales/app/schemas/sales.py
"""
Sales Service Pydantic Schemas
"""

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


class SalesDataBase(BaseModel):
    """Base sales data schema"""
    # Product reference - REQUIRED reference to inventory service
    inventory_product_id: UUID = Field(..., description="Reference to inventory service product")
    
    quantity_sold: int = Field(..., gt=0, description="Quantity sold")
    unit_price: Optional[Decimal] = Field(None, ge=0, description="Unit price")
    revenue: Decimal = Field(..., gt=0, description="Total revenue")
    cost_of_goods: Optional[Decimal] = Field(None, ge=0, description="Cost of goods sold")
    discount_applied: Optional[Decimal] = Field(0, ge=0, le=100, description="Discount percentage")
    
    location_id: Optional[str] = Field(None, max_length=100, description="Location identifier")
    sales_channel: Optional[str] = Field("in_store", description="Sales channel")
    source: str = Field("manual", description="Data source")
    
    notes: Optional[str] = Field(None, description="Additional notes")
    weather_condition: Optional[str] = Field(None, max_length=50, description="Weather condition")
    is_holiday: bool = Field(False, description="Holiday flag")
    is_weekend: bool = Field(False, description="Weekend flag")

    @validator('sales_channel')
    def validate_sales_channel(cls, v):
        allowed_channels = ['in_store', 'online', 'delivery', 'wholesale']
        if v not in allowed_channels:
            raise ValueError(f'Sales channel must be one of: {allowed_channels}')
        return v

    @validator('source')
    def validate_source(cls, v):
        allowed_sources = ['manual', 'pos', 'online', 'import', 'api', 'csv', 'demo_clone']
        if v not in allowed_sources:
            raise ValueError(f'Source must be one of: {allowed_sources}')
        return v


class SalesDataCreate(SalesDataBase):
    """Schema for creating sales data"""
    tenant_id: Optional[UUID] = Field(None, description="Tenant ID (set automatically)")
    date: datetime = Field(..., description="Sale date and time")


class SalesDataUpdate(BaseModel):
    """Schema for updating sales data"""
    # Note: product_name and product_category fields removed - use inventory service for product management
    # product_name: Optional[str] = Field(None, min_length=1, max_length=255)  # DEPRECATED
    # product_category: Optional[str] = Field(None, max_length=100)  # DEPRECATED  
    # product_sku: Optional[str] = Field(None, max_length=100)  # DEPRECATED - use inventory service
    
    quantity_sold: Optional[int] = Field(None, gt=0)
    unit_price: Optional[Decimal] = Field(None, ge=0)
    revenue: Optional[Decimal] = Field(None, gt=0)
    cost_of_goods: Optional[Decimal] = Field(None, ge=0)
    discount_applied: Optional[Decimal] = Field(None, ge=0, le=100)
    
    location_id: Optional[str] = Field(None, max_length=100)
    sales_channel: Optional[str] = None
    
    notes: Optional[str] = None
    weather_condition: Optional[str] = Field(None, max_length=50)
    is_holiday: Optional[bool] = None
    is_weekend: Optional[bool] = None
    
    validation_notes: Optional[str] = None
    is_validated: Optional[bool] = None


class SalesDataResponse(SalesDataBase):
    """Schema for sales data responses"""
    id: UUID
    tenant_id: UUID
    date: datetime
    
    is_validated: bool = False
    validation_notes: Optional[str] = None
    
    created_at: datetime
    updated_at: datetime
    created_by: Optional[UUID] = None
    
    profit_margin: Optional[float] = Field(None, description="Calculated profit margin")

    class Config:
        from_attributes = True


class SalesDataQuery(BaseModel):
    """Schema for sales data queries"""
    start_date: Optional[datetime] = None
    end_date: Optional[datetime] = None
    # Note: product_name and product_category filtering now requires inventory service integration
    # product_name: Optional[str] = None  # DEPRECATED - use inventory_product_id or join with inventory service
    # product_category: Optional[str] = None  # DEPRECATED - use inventory service categories
    inventory_product_id: Optional[UUID] = None  # Filter by specific inventory product ID
    location_id: Optional[str] = None
    sales_channel: Optional[str] = None
    source: Optional[str] = None
    is_validated: Optional[bool] = None
    
    limit: int = Field(50, ge=1, le=1000, description="Number of records to return")
    offset: int = Field(0, ge=0, description="Number of records to skip")
    
    order_by: str = Field("date", description="Field to order by")
    order_direction: str = Field("desc", description="Order direction")

    @validator('order_direction')
    def validate_order_direction(cls, v):
        if v.lower() not in ['asc', 'desc']:
            raise ValueError('Order direction must be "asc" or "desc"')
        return v.lower()


# Product schemas removed - using inventory service as single source of truth
# Product data is accessed via inventory service client


# Analytics schemas
class SalesAnalytics(BaseModel):
    """Sales analytics response"""
    total_revenue: Decimal
    total_quantity: int
    total_transactions: int
    average_transaction_value: Decimal
    top_products: List[dict]
    sales_by_channel: dict
    sales_by_day: List[dict]


class ProductSalesAnalytics(BaseModel):
    """Product-specific sales analytics"""
    inventory_product_id: UUID  # Reference to inventory service product
    # Note: product_name can be fetched from inventory service using inventory_product_id
    total_revenue: Decimal
    total_quantity: int
    total_transactions: int
    average_price: Decimal
    growth_rate: Optional[float] = None