"""
Distribution models for the bakery management platform
"""

import uuid
import enum
from datetime import datetime, timezone
from decimal import Decimal
from sqlalchemy import Column, String, DateTime, Float, Integer, Text, Index, Boolean, Numeric, ForeignKey, Enum as SQLEnum
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func

from shared.database.base import Base


class DeliveryRouteStatus(enum.Enum):
    """Status of delivery routes"""
    planned = "planned"
    in_progress = "in_progress"
    completed = "completed"
    cancelled = "cancelled"


class ShipmentStatus(enum.Enum):
    """Status of individual shipments"""
    pending = "pending"
    packed = "packed"
    in_transit = "in_transit"
    delivered = "delivered"
    failed = "failed"


class DeliveryScheduleFrequency(enum.Enum):
    """Frequency of recurring delivery schedules"""
    daily = "daily"
    weekly = "weekly"
    biweekly = "biweekly"
    monthly = "monthly"


class DeliveryRoute(Base):
    """Optimized multi-stop routes for distribution"""
    __tablename__ = "delivery_routes"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    
    # Route identification
    route_number = Column(String(50), nullable=False, unique=True, index=True)
    route_date = Column(DateTime(timezone=True), nullable=False, index=True)  # Date when route is executed
    
    # Vehicle and driver assignment
    vehicle_id = Column(String(100), nullable=True)  # Reference to fleet management
    driver_id = Column(UUID(as_uuid=True), nullable=True, index=True)  # Reference to driver
    
    # Optimization metadata
    total_distance_km = Column(Float, nullable=True)
    estimated_duration_minutes = Column(Integer, nullable=True)
    
    # VRP Optimization metrics (Phase 2 enhancement)
    vrp_optimization_savings = Column(JSONB, nullable=True)  # {"distance_saved_km": 12.5, "time_saved_minutes": 25, "fuel_saved_liters": 8.2, "co2_saved_kg": 15.4, "cost_saved_eur": 12.50}
    vrp_algorithm_version = Column(String(50), nullable=True)  # Version of VRP algorithm used
    vrp_optimization_timestamp = Column(DateTime(timezone=True), nullable=True)  # When optimization was performed
    vrp_constraints_satisfied = Column(Boolean, nullable=True)  # Whether all constraints were satisfied
    vrp_objective_value = Column(Float, nullable=True)  # Objective function value from optimization
    
    # Route details
    route_sequence = Column(JSONB, nullable=True)  # Ordered array of stops with timing: [{"stop_number": 1, "location_id": "...", "estimated_arrival": "...", "actual_arrival": "..."}]
    notes = Column(Text, nullable=True)
    
    # Status
    status = Column(SQLEnum(DeliveryRouteStatus), nullable=False, default=DeliveryRouteStatus.planned, index=True)
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    created_by = Column(UUID(as_uuid=True), nullable=False)
    updated_by = Column(UUID(as_uuid=True), nullable=False)

    # Relationships
    shipments = relationship("Shipment", back_populates="route", cascade="all, delete-orphan")

    # Indexes
    __table_args__ = (
        Index('ix_delivery_routes_tenant_date', 'tenant_id', 'route_date'),
        Index('ix_delivery_routes_status', 'status'),
        Index('ix_delivery_routes_date_tenant_status', 'route_date', 'tenant_id', 'status'),
    )


class Shipment(Base):
    """Individual deliveries to child tenants"""
    __tablename__ = "shipments"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    
    # Links to hierarchy and procurement
    parent_tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)  # Source tenant (central production)
    child_tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)  # Destination tenant (retail outlet)
    purchase_order_id = Column(UUID(as_uuid=True), nullable=True, index=True)  # Associated internal purchase order
    delivery_route_id = Column(UUID(as_uuid=True), ForeignKey('delivery_routes.id', ondelete='SET NULL'), nullable=True, index=True)  # Assigned route
    
    # Shipment details
    shipment_number = Column(String(50), nullable=False, unique=True, index=True)
    shipment_date = Column(DateTime(timezone=True), nullable=False, index=True)
    
    # Tracking information
    current_location_lat = Column(Float, nullable=True)
    current_location_lng = Column(Float, nullable=True)
    last_tracked_at = Column(DateTime(timezone=True), nullable=True)
    status = Column(SQLEnum(ShipmentStatus), nullable=False, default=ShipmentStatus.pending, index=True)
    actual_delivery_time = Column(DateTime(timezone=True), nullable=True)
    
    # Proof of delivery
    signature = Column(Text, nullable=True)  # Digital signature base64 encoded
    photo_url = Column(String(500), nullable=True)  # URL to delivery confirmation photo
    received_by_name = Column(String(200), nullable=True)
    delivery_notes = Column(Text, nullable=True)
    
    # Weight/volume tracking
    total_weight_kg = Column(Float, nullable=True)
    total_volume_m3 = Column(Float, nullable=True)
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    created_by = Column(UUID(as_uuid=True), nullable=False)
    updated_by = Column(UUID(as_uuid=True), nullable=False)

    # Relationships
    route = relationship("DeliveryRoute", back_populates="shipments")

    # Indexes
    __table_args__ = (
        Index('ix_shipments_tenant_status', 'tenant_id', 'status'),
        Index('ix_shipments_parent_child', 'parent_tenant_id', 'child_tenant_id'),
        Index('ix_shipments_date_tenant', 'shipment_date', 'tenant_id'),
    )


class DeliverySchedule(Base):
    """Recurring delivery patterns"""
    __tablename__ = "delivery_schedules"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    
    # Schedule identification
    name = Column(String(200), nullable=False)
    
    # Delivery pattern
    delivery_days = Column(String(200), nullable=False)  # Format: "Mon,Wed,Fri" or "Mon-Fri"
    delivery_time = Column(String(20), nullable=False)  # Format: "HH:MM" or "HH:MM-HH:MM"
    frequency = Column(SQLEnum(DeliveryScheduleFrequency), nullable=False, default=DeliveryScheduleFrequency.weekly)
    
    # Auto-generation settings
    auto_generate_orders = Column(Boolean, nullable=False, default=False)
    lead_time_days = Column(Integer, nullable=False, default=1)  # How many days in advance to generate
    
    # Target tenants for this schedule
    target_parent_tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    target_child_tenant_ids = Column(JSONB, nullable=False)  # List of child tenant IDs involved in this route
    
    # Configuration
    is_active = Column(Boolean, nullable=False, default=True)
    notes = Column(Text, nullable=True)
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    created_by = Column(UUID(as_uuid=True), nullable=False)
    updated_by = Column(UUID(as_uuid=True), nullable=False)

    # Indexes
    __table_args__ = (
        Index('ix_delivery_schedules_tenant_active', 'tenant_id', 'is_active'),
        Index('ix_delivery_schedules_parent_tenant', 'target_parent_tenant_id'),
    )