# ================================================================
# services/procurement/app/schemas/purchase_order_schemas.py
# ================================================================
"""
Purchase Order Schemas - Request/response models for purchase orders
Migrated from Suppliers Service with procurement-specific additions
"""

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


# ================================================================
# BASE SCHEMAS
# ================================================================

class PurchaseOrderBase(BaseModel):
    """Base schema for purchase order entities"""
    model_config = ConfigDict(from_attributes=True, str_strip_whitespace=True)


# ================================================================
# PURCHASE ORDER ITEM SCHEMAS
# ================================================================

class PurchaseOrderItemCreate(PurchaseOrderBase):
    """Schema for creating purchase order items"""
    inventory_product_id: uuid.UUID  # Changed from ingredient_id to match model
    ordered_quantity: Decimal = Field(..., gt=0)
    unit_price: Decimal = Field(..., gt=0)
    unit_of_measure: str = Field(..., max_length=50)
    quality_requirements: Optional[str] = None
    item_notes: Optional[str] = None


class PurchaseOrderItemUpdate(PurchaseOrderBase):
    """Schema for updating purchase order items"""
    ordered_quantity: Optional[Decimal] = Field(None, gt=0)
    unit_price: Optional[Decimal] = Field(None, gt=0)
    quality_requirements: Optional[str] = None
    item_notes: Optional[str] = None


class PurchaseOrderItemResponse(PurchaseOrderBase):
    """Schema for purchase order item responses"""
    id: uuid.UUID
    tenant_id: uuid.UUID
    purchase_order_id: uuid.UUID
    inventory_product_id: uuid.UUID  # Changed from ingredient_id to match model
    product_name: Optional[str] = None
    ordered_quantity: Decimal
    received_quantity: Decimal
    unit_price: Decimal
    unit_of_measure: str
    line_total: Decimal
    quality_requirements: Optional[str] = None
    item_notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime


# ================================================================
# PURCHASE ORDER SCHEMAS
# ================================================================

class PurchaseOrderCreate(PurchaseOrderBase):
    """Schema for creating purchase orders"""
    supplier_id: uuid.UUID
    required_delivery_date: datetime  # Use datetime with timezone
    priority: str = Field(default="normal", pattern="^(low|normal|high|critical)$")

    # Financial information
    tax_amount: Decimal = Field(default=Decimal("0"), ge=0)
    shipping_cost: Decimal = Field(default=Decimal("0"), ge=0)
    discount_amount: Decimal = Field(default=Decimal("0"), ge=0)
    subtotal: Decimal = Field(..., ge=0)

    # Additional information
    notes: Optional[str] = None

    # NEW: Procurement-specific fields
    procurement_plan_id: Optional[uuid.UUID] = None

    # Items
    items: List[PurchaseOrderItemCreate] = Field(..., min_length=1)


class PurchaseOrderUpdate(PurchaseOrderBase):
    """Schema for updating purchase orders"""
    required_delivery_date: Optional[datetime] = None  # Use datetime with timezone
    priority: Optional[str] = Field(None, pattern="^(low|normal|high|critical)$")

    # Financial information
    tax_amount: Optional[Decimal] = Field(None, ge=0)
    shipping_cost: Optional[Decimal] = Field(None, ge=0)
    discount_amount: Optional[Decimal] = Field(None, ge=0)

    # Additional information
    notes: Optional[str] = None


class PurchaseOrderApproval(PurchaseOrderBase):
    """Schema for purchase order approval/rejection"""
    action: str = Field(..., pattern="^(approve|reject)$")
    notes: Optional[str] = None
    approved_by: Optional[uuid.UUID] = None


class SupplierSummary(PurchaseOrderBase):
    """Schema for supplier summary - matches the structure returned by suppliers service"""
    id: str
    name: str
    supplier_code: Optional[str] = None
    email: Optional[str] = None
    phone: Optional[str] = None
    contact_person: Optional[str] = None
    address_line1: Optional[str] = None
    city: Optional[str] = None
    country: Optional[str] = None
    supplier_type: Optional[str] = None
    status: Optional[str] = None
    mobile: Optional[str] = None
    website: Optional[str] = None
    payment_terms: Optional[str] = None
    standard_lead_time: Optional[int] = None
    quality_rating: Optional[float] = None
    delivery_rating: Optional[float] = None
    total_orders: Optional[int] = None
    total_amount: Optional[float] = None


class PurchaseOrderResponse(PurchaseOrderBase):
    """Schema for purchase order responses"""
    id: uuid.UUID
    tenant_id: uuid.UUID
    supplier_id: uuid.UUID
    supplier_name: Optional[str] = None
    po_number: str
    status: str
    priority: str

    order_date: datetime
    required_delivery_date: Optional[datetime] = None  # Use datetime with timezone
    estimated_delivery_date: Optional[datetime] = None  # Use datetime with timezone
    actual_delivery_date: Optional[datetime] = None  # Use datetime with timezone

    # Financial information
    subtotal: Decimal
    tax_amount: Decimal
    shipping_cost: Decimal
    discount_amount: Decimal
    total_amount: Decimal
    currency: str

    # Approval workflow
    approved_by: Optional[uuid.UUID] = None
    approved_at: Optional[datetime] = None
    rejection_reason: Optional[str] = None

    # NEW: Procurement-specific fields
    procurement_plan_id: Optional[uuid.UUID] = None
    auto_approved: bool = False
    auto_approval_rule_id: Optional[uuid.UUID] = None

    # Additional information
    notes: Optional[str] = None

    # AI/ML reasoning for procurement decisions (JTBD dashboard support)
    reasoning_data: Optional[Dict[str, Any]] = None

    # Audit fields
    created_at: datetime
    updated_at: datetime
    created_by: Optional[uuid.UUID] = None
    updated_by: Optional[uuid.UUID] = None

    # Related data
    items: List[PurchaseOrderItemResponse] = []


class PurchaseOrderWithSupplierResponse(PurchaseOrderResponse):
    """Schema for purchase order responses with supplier information"""
    supplier: Optional[SupplierSummary] = None


class PurchaseOrderSummary(PurchaseOrderBase):
    """Schema for purchase order summary (list view)"""
    id: uuid.UUID
    po_number: str
    supplier_id: uuid.UUID
    supplier_name: Optional[str] = None
    status: str
    priority: str
    order_date: datetime
    required_delivery_date: datetime  # Use datetime with timezone
    total_amount: Decimal
    currency: str
    auto_approved: bool = False
    created_at: datetime


# ================================================================
# DELIVERY SCHEMAS
# ================================================================

class DeliveryItemCreate(PurchaseOrderBase):
    """Schema for creating delivery items"""
    purchase_order_item_id: uuid.UUID
    inventory_product_id: uuid.UUID  # Changed from ingredient_id to match model
    ordered_quantity: Decimal = Field(..., gt=0)
    delivered_quantity: Decimal = Field(..., ge=0)
    accepted_quantity: Decimal = Field(..., ge=0)
    rejected_quantity: Decimal = Field(default=Decimal("0"), ge=0)

    # Quality information
    batch_lot_number: Optional[str] = Field(None, max_length=100)
    expiry_date: Optional[datetime] = None  # Use datetime with timezone
    quality_grade: Optional[str] = Field(None, max_length=20)

    # Issues and notes
    quality_issues: Optional[str] = None
    rejection_reason: Optional[str] = None
    item_notes: Optional[str] = None


class DeliveryItemResponse(PurchaseOrderBase):
    """Schema for delivery item responses"""
    id: uuid.UUID
    tenant_id: uuid.UUID
    delivery_id: uuid.UUID
    purchase_order_item_id: uuid.UUID
    inventory_product_id: uuid.UUID  # Changed from ingredient_id to match model
    ingredient_name: Optional[str] = None
    ordered_quantity: Decimal
    delivered_quantity: Decimal
    accepted_quantity: Decimal
    rejected_quantity: Decimal
    batch_lot_number: Optional[str] = None
    expiry_date: Optional[datetime] = None  # Use datetime with timezone
    quality_grade: Optional[str] = None
    quality_issues: Optional[str] = None
    rejection_reason: Optional[str] = None
    item_notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime


class DeliveryCreate(PurchaseOrderBase):
    """Schema for creating deliveries"""
    purchase_order_id: uuid.UUID
    supplier_id: uuid.UUID
    supplier_delivery_note: Optional[str] = Field(None, max_length=100)
    scheduled_date: Optional[datetime] = None  # Use datetime with timezone
    estimated_arrival: Optional[datetime] = None

    # Delivery details
    carrier_name: Optional[str] = Field(None, max_length=200)
    tracking_number: Optional[str] = Field(None, max_length=100)

    # Additional information
    notes: Optional[str] = None

    # Items
    items: List[DeliveryItemCreate] = Field(..., min_length=1)


class DeliveryUpdate(PurchaseOrderBase):
    """Schema for updating deliveries"""
    supplier_delivery_note: Optional[str] = Field(None, max_length=100)
    scheduled_date: Optional[datetime] = None  # Use datetime with timezone
    estimated_arrival: Optional[datetime] = None
    actual_arrival: Optional[datetime] = None

    # Delivery details
    carrier_name: Optional[str] = Field(None, max_length=200)
    tracking_number: Optional[str] = Field(None, max_length=100)

    # Quality inspection
    inspection_passed: Optional[bool] = None
    inspection_notes: Optional[str] = None
    quality_issues: Optional[Dict[str, Any]] = None

    # Additional information
    notes: Optional[str] = None


class DeliveryResponse(PurchaseOrderBase):
    """Schema for delivery responses"""
    id: uuid.UUID
    tenant_id: uuid.UUID
    purchase_order_id: uuid.UUID
    supplier_id: uuid.UUID
    supplier_name: Optional[str] = None
    delivery_number: str
    supplier_delivery_note: Optional[str] = None
    status: str

    # Timing
    scheduled_date: Optional[datetime] = None  # Use datetime with timezone
    estimated_arrival: Optional[datetime] = None
    actual_arrival: Optional[datetime] = None
    completed_at: Optional[datetime] = None

    # Delivery details
    carrier_name: Optional[str] = None
    tracking_number: Optional[str] = None

    # Quality inspection
    inspection_passed: Optional[bool] = None
    inspection_notes: Optional[str] = None
    quality_issues: Optional[Dict[str, Any]] = None

    # Receipt information
    received_by: Optional[uuid.UUID] = None
    received_at: Optional[datetime] = None

    # Additional information
    notes: Optional[str] = None

    # Audit fields
    created_at: datetime
    updated_at: datetime
    created_by: uuid.UUID

    # Related data
    items: List[DeliveryItemResponse] = []


# ================================================================
# INVOICE SCHEMAS
# ================================================================

class SupplierInvoiceCreate(PurchaseOrderBase):
    """Schema for creating supplier invoices"""
    purchase_order_id: uuid.UUID
    supplier_id: uuid.UUID
    invoice_number: str = Field(..., max_length=100)
    invoice_date: datetime  # Use datetime with timezone
    due_date: datetime  # Use datetime with timezone

    # Financial information
    subtotal: Decimal = Field(..., ge=0)
    tax_amount: Decimal = Field(default=Decimal("0"), ge=0)
    shipping_cost: Decimal = Field(default=Decimal("0"), ge=0)
    discount_amount: Decimal = Field(default=Decimal("0"), ge=0)

    # Additional information
    notes: Optional[str] = None
    payment_reference: Optional[str] = Field(None, max_length=100)


class SupplierInvoiceUpdate(PurchaseOrderBase):
    """Schema for updating supplier invoices"""
    due_date: Optional[datetime] = None  # Use datetime with timezone
    payment_reference: Optional[str] = Field(None, max_length=100)
    notes: Optional[str] = None


class SupplierInvoiceResponse(PurchaseOrderBase):
    """Schema for supplier invoice responses"""
    id: uuid.UUID
    tenant_id: uuid.UUID
    purchase_order_id: uuid.UUID
    supplier_id: uuid.UUID
    supplier_name: Optional[str] = None
    invoice_number: str
    status: str
    invoice_date: datetime  # Use datetime with timezone
    due_date: datetime  # Use datetime with timezone

    # Financial information
    subtotal: Decimal
    tax_amount: Decimal
    shipping_cost: Decimal
    discount_amount: Decimal
    total_amount: Decimal
    currency: str

    # Payment tracking
    paid_amount: Decimal
    remaining_amount: Decimal
    payment_date: Optional[datetime] = None  # Use datetime with timezone
    payment_reference: Optional[str] = None

    # Additional information
    notes: Optional[str] = None

    # Audit fields
    created_at: datetime
    updated_at: datetime
    created_by: uuid.UUID
    updated_by: uuid.UUID
