# services/suppliers/app/models/suppliers.py
"""
Supplier management models for Suppliers Service
Comprehensive supplier management and vendor relationships
NOTE: Purchase orders, deliveries, and invoices have been moved to Procurement Service
"""

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
import uuid
import enum
from datetime import datetime, timezone
from typing import Dict, Any, Optional, List
from decimal import Decimal

from shared.database.base import Base


class SupplierType(enum.Enum):
    """Types of suppliers"""
    ingredients = "ingredients"  # Raw materials supplier
    packaging = "packaging"     # Packaging materials
    equipment = "equipment"     # Bakery equipment
    services = "services"       # Service providers
    utilities = "utilities"     # Utilities (gas, electricity)
    multi = "multi"            # Multi-category supplier


class SupplierStatus(enum.Enum):
    """Supplier lifecycle status"""
    active = "active"
    inactive = "inactive"
    pending_approval = "pending_approval"
    suspended = "suspended"
    blacklisted = "blacklisted"


class PaymentTerms(enum.Enum):
    """Payment terms with suppliers"""
    cod = "cod"
    net_15 = "net_15"
    net_30 = "net_30"
    net_45 = "net_45"
    net_60 = "net_60"
    prepaid = "prepaid"
    credit_terms = "credit_terms"


class QualityRating(enum.Enum):
    """Quality rating scale for supplier reviews"""
    excellent = 5
    good = 4
    average = 3
    poor = 2
    very_poor = 1


# ============================================================================
# DEPRECATED ENUMS - Kept for backward compatibility only
# These enums are defined here to prevent import errors, but the actual
# tables and functionality have moved to the Procurement Service
# ============================================================================

class PurchaseOrderStatus(enum.Enum):
    """DEPRECATED: Moved to Procurement Service"""
    draft = "draft"
    pending_approval = "pending_approval"
    approved = "approved"
    sent_to_supplier = "sent_to_supplier"
    confirmed = "confirmed"
    partially_received = "partially_received"
    completed = "completed"
    cancelled = "cancelled"
    disputed = "disputed"


class DeliveryStatus(enum.Enum):
    """DEPRECATED: Moved to Procurement Service"""
    scheduled = "scheduled"
    in_transit = "in_transit"
    out_for_delivery = "out_for_delivery"
    delivered = "delivered"
    partially_delivered = "partially_delivered"
    failed_delivery = "failed_delivery"
    returned = "returned"


class DeliveryRating(enum.Enum):
    """DEPRECATED: Moved to Procurement Service"""
    excellent = 5
    good = 4
    average = 3
    poor = 2
    very_poor = 1


class InvoiceStatus(enum.Enum):
    """DEPRECATED: Moved to Procurement Service"""
    pending = "pending"
    approved = "approved"
    paid = "paid"
    overdue = "overdue"
    disputed = "disputed"
    cancelled = "cancelled"


class Supplier(Base):
    """Master supplier information"""
    __tablename__ = "suppliers"
    
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    
    # Basic supplier information
    name = Column(String(255), nullable=False, index=True)
    supplier_code = Column(String(50), nullable=True, index=True)  # Internal reference code
    tax_id = Column(String(50), nullable=True)  # VAT/Tax ID
    registration_number = Column(String(100), nullable=True)  # Business registration number
    
    # Supplier classification
    supplier_type = Column(SQLEnum(SupplierType), nullable=False, index=True)
    status = Column(SQLEnum(SupplierStatus), nullable=False, default=SupplierStatus.pending_approval, index=True)
    
    # Contact information
    contact_person = Column(String(200), nullable=True)
    email = Column(String(254), nullable=True)
    phone = Column(String(30), nullable=True)
    mobile = Column(String(30), nullable=True)
    website = Column(String(255), nullable=True)
    
    # Address information
    address_line1 = Column(String(255), nullable=True)
    address_line2 = Column(String(255), nullable=True)
    city = Column(String(100), nullable=True)
    state_province = Column(String(100), nullable=True)
    postal_code = Column(String(20), nullable=True)
    country = Column(String(100), nullable=True)
    
    # Business terms
    payment_terms = Column(SQLEnum(PaymentTerms), nullable=False, default=PaymentTerms.net_30)
    credit_limit = Column(Numeric(12, 2), nullable=True)
    currency = Column(String(3), nullable=False, default="EUR")  # ISO currency code
    
    # Lead times (in days)
    standard_lead_time = Column(Integer, nullable=False, default=3)
    minimum_order_amount = Column(Numeric(10, 2), nullable=True)
    delivery_area = Column(String(255), nullable=True)
    
    # Quality and performance metrics
    quality_rating = Column(Float, nullable=True, default=0.0)  # Average quality rating (1-5)
    delivery_rating = Column(Float, nullable=True, default=0.0)  # Average delivery rating (1-5)
    total_orders = Column(Integer, nullable=False, default=0)
    total_amount = Column(Numeric(12, 2), nullable=False, default=0.0)

    # Trust and auto-approval metrics
    trust_score = Column(Float, nullable=False, default=0.0)  # Calculated trust score (0.0-1.0)
    is_preferred_supplier = Column(Boolean, nullable=False, default=False)  # Preferred supplier status
    auto_approve_enabled = Column(Boolean, nullable=False, default=False)  # Enable auto-approval for this supplier
    total_pos_count = Column(Integer, nullable=False, default=0)  # Total purchase orders created
    approved_pos_count = Column(Integer, nullable=False, default=0)  # Total POs approved
    on_time_delivery_rate = Column(Float, nullable=False, default=0.0)  # Percentage of on-time deliveries
    fulfillment_rate = Column(Float, nullable=False, default=0.0)  # Percentage of orders fully fulfilled
    last_performance_update = Column(DateTime(timezone=True), nullable=True)  # Last time metrics were calculated

    # Onboarding and approval
    approved_by = Column(UUID(as_uuid=True), nullable=True)  # User who approved
    approved_at = Column(DateTime(timezone=True), nullable=True)
    rejection_reason = Column(Text, nullable=True)
    
    # Additional information
    notes = Column(Text, nullable=True)
    certifications = Column(JSONB, nullable=True)  # Quality certifications, licenses
    business_hours = Column(JSONB, nullable=True)  # Operating hours by day
    specializations = Column(JSONB, nullable=True)  # Product categories, special services
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
    updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
    created_by = Column(UUID(as_uuid=True), nullable=False)
    updated_by = Column(UUID(as_uuid=True), nullable=False)
    
    # Relationships
    price_lists = relationship("SupplierPriceList", back_populates="supplier", cascade="all, delete-orphan")
    quality_reviews = relationship("SupplierQualityReview", back_populates="supplier", cascade="all, delete-orphan")
    
    # Indexes
    __table_args__ = (
        Index('ix_suppliers_tenant_name', 'tenant_id', 'name'),
        Index('ix_suppliers_tenant_status', 'tenant_id', 'status'),
        Index('ix_suppliers_tenant_type', 'tenant_id', 'supplier_type'),
        Index('ix_suppliers_quality_rating', 'quality_rating'),
    )


class SupplierPriceList(Base):
    """Product pricing from suppliers"""
    __tablename__ = "supplier_price_lists"
    
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    tenant_id = Column(UUID(as_uuid=True), nullable=False, index=True)
    supplier_id = Column(UUID(as_uuid=True), ForeignKey('suppliers.id'), nullable=False, index=True)
    
    # Product identification (references inventory service)
    inventory_product_id = Column(UUID(as_uuid=True), nullable=False, index=True)  # Reference to inventory products
    product_code = Column(String(100), nullable=True)  # Supplier's product code
    
    # Pricing information
    unit_price = Column(Numeric(10, 4), nullable=False)
    unit_of_measure = Column(String(20), nullable=False)  # kg, g, l, ml, units, etc.
    minimum_order_quantity = Column(Integer, nullable=True, default=1)
    price_per_unit = Column(Numeric(10, 4), nullable=False)  # Calculated field
    
    # Pricing tiers (volume discounts)
    tier_pricing = Column(JSONB, nullable=True)  # [{quantity: 100, price: 2.50}, ...]
    
    # Validity and terms
    effective_date = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc))
    expiry_date = Column(DateTime(timezone=True), nullable=True)
    is_active = Column(Boolean, nullable=False, default=True)
    
    # Additional product details
    brand = Column(String(100), nullable=True)
    packaging_size = Column(String(50), nullable=True)
    origin_country = Column(String(100), nullable=True)
    shelf_life_days = Column(Integer, nullable=True)
    storage_requirements = Column(Text, nullable=True)
    
    # Quality specifications
    quality_specs = Column(JSONB, nullable=True)  # Quality parameters, certifications
    allergens = Column(JSONB, nullable=True)  # Allergen information
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
    updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc))
    created_by = Column(UUID(as_uuid=True), nullable=False)
    updated_by = Column(UUID(as_uuid=True), nullable=False)
    
    # Relationships
    supplier = relationship("Supplier", back_populates="price_lists")

    # Indexes
    __table_args__ = (
        Index('ix_price_lists_tenant_supplier', 'tenant_id', 'supplier_id'),
        Index('ix_price_lists_inventory_product', 'inventory_product_id'),
        Index('ix_price_lists_active', 'is_active'),
        Index('ix_price_lists_effective_date', 'effective_date'),
    )


class SupplierQualityReview(Base):
    """Quality and performance reviews for suppliers"""
    __tablename__ = "supplier_quality_reviews"

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

    # Review details
    review_date = Column(DateTime(timezone=True), nullable=False, default=lambda: datetime.now(timezone.utc))
    review_type = Column(String(50), nullable=False)  # monthly, annual, incident

    # Ratings (1-5 scale)
    quality_rating = Column(SQLEnum(QualityRating), nullable=False)
    delivery_rating = Column(Integer, nullable=False)  # 1-5 scale
    communication_rating = Column(Integer, nullable=False)  # 1-5
    overall_rating = Column(Float, nullable=False)  # Calculated average
    
    # Detailed feedback
    quality_comments = Column(Text, nullable=True)
    delivery_comments = Column(Text, nullable=True)
    communication_comments = Column(Text, nullable=True)
    improvement_suggestions = Column(Text, nullable=True)
    
    # Issues and corrective actions
    quality_issues = Column(JSONB, nullable=True)  # Documented issues
    corrective_actions = Column(Text, nullable=True)
    follow_up_required = Column(Boolean, nullable=False, default=False)
    follow_up_date = Column(DateTime(timezone=True), nullable=True)
    
    # Review status
    is_final = Column(Boolean, nullable=False, default=True)
    approved_by = Column(UUID(as_uuid=True), nullable=True)
    
    # Audit fields
    created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc))
    reviewed_by = Column(UUID(as_uuid=True), nullable=False)
    
    # Relationships
    supplier = relationship("Supplier", back_populates="quality_reviews")
    
    # Indexes
    __table_args__ = (
        Index('ix_quality_reviews_tenant_supplier', 'tenant_id', 'supplier_id'),
        Index('ix_quality_reviews_date', 'review_date'),
        Index('ix_quality_reviews_overall_rating', 'overall_rating'),
    )

# ============================================================================
# DEPRECATED MODELS - Stub definitions for backward compatibility
# These models are defined here ONLY to prevent import errors
# The actual tables exist in the Procurement Service database, NOT here
# __table__ = None prevents SQLAlchemy from creating these tables
# ============================================================================

class PurchaseOrder:
    """DEPRECATED STUB: Actual implementation in Procurement Service"""
    __table__ = None  # Prevent table creation
    pass


class PurchaseOrderItem:
    """DEPRECATED STUB: Actual implementation in Procurement Service"""
    __table__ = None  # Prevent table creation
    pass


class Delivery:
    """DEPRECATED STUB: Actual implementation in Procurement Service"""
    __table__ = None  # Prevent table creation
    pass


class DeliveryItem:
    """DEPRECATED STUB: Actual implementation in Procurement Service"""
    __table__ = None  # Prevent table creation
    pass


class SupplierInvoice:
    """DEPRECATED STUB: Actual implementation in Procurement Service"""
    __table__ = None  # Prevent table creation
    pass
