"""
Database models for replenishment planning.
"""

from sqlalchemy import Column, String, Integer, Numeric, Date, Boolean, ForeignKey, Text, TIMESTAMP, JSON
from sqlalchemy.dialects.postgresql import UUID, JSONB
from sqlalchemy.orm import relationship
import uuid
from datetime import datetime

from shared.database import Base


class ReplenishmentPlan(Base):
    """Replenishment plan master record"""
    __tablename__ = "replenishment_plans"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)

    # Planning metadata
    planning_date = Column(Date, nullable=False)
    projection_horizon_days = Column(Integer, nullable=False, default=7)

    # References
    forecast_id = Column(UUID(as_uuid=True), nullable=True)
    production_schedule_id = Column(UUID(as_uuid=True), nullable=True)

    # Summary statistics
    total_items = Column(Integer, nullable=False, default=0)
    urgent_items = Column(Integer, nullable=False, default=0)
    high_risk_items = Column(Integer, nullable=False, default=0)
    total_estimated_cost = Column(Numeric(12, 2), nullable=False, default=0)

    # Status
    status = Column(String(50), nullable=False, default='draft')  # draft, approved, executed

    # Timestamps
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, default=datetime.utcnow)
    updated_at = Column(TIMESTAMP(timezone=True), nullable=True, onupdate=datetime.utcnow)
    executed_at = Column(TIMESTAMP(timezone=True), nullable=True)

    # Relationships
    items = relationship("ReplenishmentPlanItem", back_populates="plan", cascade="all, delete-orphan")


class ReplenishmentPlanItem(Base):
    """Individual item in a replenishment plan"""
    __tablename__ = "replenishment_plan_items"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    replenishment_plan_id = Column(UUID(as_uuid=True), ForeignKey("replenishment_plans.id"), nullable=False, index=True)

    # Ingredient info
    ingredient_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    ingredient_name = Column(String(200), nullable=False)
    unit_of_measure = Column(String(20), nullable=False)

    # Quantities
    base_quantity = Column(Numeric(12, 3), nullable=False)
    safety_stock_quantity = Column(Numeric(12, 3), nullable=False, default=0)
    shelf_life_adjusted_quantity = Column(Numeric(12, 3), nullable=False)
    final_order_quantity = Column(Numeric(12, 3), nullable=False)

    # Dates
    order_date = Column(Date, nullable=False, index=True)
    delivery_date = Column(Date, nullable=False)
    required_by_date = Column(Date, nullable=False)

    # Planning metadata
    lead_time_days = Column(Integer, nullable=False)
    is_urgent = Column(Boolean, nullable=False, default=False, index=True)
    urgency_reason = Column(Text, nullable=True)
    waste_risk = Column(String(20), nullable=False, default='low')  # low, medium, high
    stockout_risk = Column(String(20), nullable=False, default='low')  # low, medium, high, critical

    # Supplier
    supplier_id = Column(UUID(as_uuid=True), nullable=True)

    # Calculation details (stored as JSONB)
    safety_stock_calculation = Column(JSONB, nullable=True)
    shelf_life_adjustment = Column(JSONB, nullable=True)
    inventory_projection = Column(JSONB, nullable=True)

    # Timestamps
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, default=datetime.utcnow)

    # Relationships
    plan = relationship("ReplenishmentPlan", back_populates="items")


class InventoryProjection(Base):
    """Daily inventory projection"""
    __tablename__ = "inventory_projections"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)

    # Ingredient
    ingredient_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    ingredient_name = Column(String(200), nullable=False)

    # Projection date
    projection_date = Column(Date, nullable=False, index=True)

    # Stock levels
    starting_stock = Column(Numeric(12, 3), nullable=False)
    forecasted_consumption = Column(Numeric(12, 3), nullable=False, default=0)
    scheduled_receipts = Column(Numeric(12, 3), nullable=False, default=0)
    projected_ending_stock = Column(Numeric(12, 3), nullable=False)

    # Flags
    is_stockout = Column(Boolean, nullable=False, default=False, index=True)
    coverage_gap = Column(Numeric(12, 3), nullable=False, default=0)  # Negative if stockout

    # Reference to replenishment plan
    replenishment_plan_id = Column(UUID(as_uuid=True), nullable=True)

    # Timestamps
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, default=datetime.utcnow)

    __table_args__ = (
        # Unique constraint: one projection per ingredient per date per tenant
        {'schema': None}
    )


class SupplierAllocation(Base):
    """Supplier allocation for a requirement"""
    __tablename__ = "supplier_allocations"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)

    # References
    replenishment_plan_item_id = Column(UUID(as_uuid=True), ForeignKey("replenishment_plan_items.id"), nullable=True, index=True)
    requirement_id = Column(UUID(as_uuid=True), nullable=True, index=True)  # Reference to procurement_requirements

    # Supplier
    supplier_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    supplier_name = Column(String(200), nullable=False)

    # Allocation
    allocation_type = Column(String(20), nullable=False)  # primary, backup, diversification
    allocated_quantity = Column(Numeric(12, 3), nullable=False)
    allocation_percentage = Column(Numeric(5, 4), nullable=False)  # 0.0000 - 1.0000

    # Pricing
    unit_price = Column(Numeric(12, 2), nullable=False)
    total_cost = Column(Numeric(12, 2), nullable=False)

    # Lead time
    lead_time_days = Column(Integer, nullable=False)

    # Scoring
    supplier_score = Column(Numeric(5, 2), nullable=False)
    score_breakdown = Column(JSONB, nullable=True)

    # Reasoning
    allocation_reason = Column(Text, nullable=True)

    # Timestamps
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, default=datetime.utcnow)


class SupplierSelectionHistory(Base):
    """Historical record of supplier selections for analytics"""
    __tablename__ = "supplier_selection_history"

    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)

    # Selection details
    ingredient_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    ingredient_name = Column(String(200), nullable=False)
    selected_supplier_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    selected_supplier_name = Column(String(200), nullable=False)

    # Order details
    selection_date = Column(Date, nullable=False, index=True)
    quantity = Column(Numeric(12, 3), nullable=False)
    unit_price = Column(Numeric(12, 2), nullable=False)
    total_cost = Column(Numeric(12, 2), nullable=False)

    # Metrics
    lead_time_days = Column(Integer, nullable=False)
    quality_score = Column(Numeric(5, 2), nullable=True)
    delivery_performance = Column(Numeric(5, 2), nullable=True)

    # Selection strategy
    selection_strategy = Column(String(50), nullable=False)  # single_source, dual_source, multi_source
    was_primary_choice = Column(Boolean, nullable=False, default=True)

    # Timestamps
    created_at = Column(TIMESTAMP(timezone=True), nullable=False, default=datetime.utcnow)
