# ================================================================
# services/suppliers/app/schemas/performance.py
# ================================================================
"""
Performance Tracking and Alert Schemas for Suppliers Service
"""

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

from app.models.performance import (
    AlertSeverity, AlertType, AlertStatus, PerformanceMetricType, 
    PerformancePeriod
)


# ===== Base Schemas =====

class PerformanceMetricBase(BaseModel):
    """Base schema for performance metrics"""
    metric_type: PerformanceMetricType
    period: PerformancePeriod
    period_start: datetime
    period_end: datetime
    metric_value: float = Field(ge=0, le=100)
    target_value: Optional[float] = None
    total_orders: int = Field(ge=0, default=0)
    total_deliveries: int = Field(ge=0, default=0)
    on_time_deliveries: int = Field(ge=0, default=0)
    late_deliveries: int = Field(ge=0, default=0)
    quality_issues: int = Field(ge=0, default=0)
    total_amount: Decimal = Field(ge=0, default=0)
    notes: Optional[str] = None


class PerformanceMetricCreate(PerformanceMetricBase):
    """Schema for creating performance metrics"""
    supplier_id: UUID
    metrics_data: Optional[Dict[str, Any]] = None
    external_factors: Optional[Dict[str, Any]] = None


class PerformanceMetricUpdate(BaseModel):
    """Schema for updating performance metrics"""
    metric_value: Optional[float] = Field(None, ge=0, le=100)
    target_value: Optional[float] = None
    notes: Optional[str] = None
    metrics_data: Optional[Dict[str, Any]] = None
    external_factors: Optional[Dict[str, Any]] = None


class PerformanceMetric(PerformanceMetricBase):
    """Complete performance metric schema"""
    id: UUID
    tenant_id: UUID
    supplier_id: UUID
    previous_value: Optional[float] = None
    trend_direction: Optional[str] = None
    trend_percentage: Optional[float] = None
    metrics_data: Optional[Dict[str, Any]] = None
    external_factors: Optional[Dict[str, Any]] = None
    calculated_at: datetime
    
    class Config:
        orm_mode = True


# ===== Alert Schemas =====

class AlertBase(BaseModel):
    """Base schema for alerts"""
    alert_type: AlertType
    severity: AlertSeverity
    title: str = Field(max_length=255)
    message: str
    description: Optional[str] = None
    trigger_value: Optional[float] = None
    threshold_value: Optional[float] = None
    metric_type: Optional[PerformanceMetricType] = None
    recommended_actions: Optional[List[Dict[str, Any]]] = None
    auto_resolve: bool = False


class AlertCreate(AlertBase):
    """Schema for creating alerts"""
    supplier_id: UUID
    purchase_order_id: Optional[UUID] = None
    delivery_id: Optional[UUID] = None
    performance_metric_id: Optional[UUID] = None
    priority_score: int = Field(ge=1, le=100, default=50)
    business_impact: Optional[str] = None
    tags: Optional[List[str]] = None


class AlertUpdate(BaseModel):
    """Schema for updating alerts"""
    status: Optional[AlertStatus] = None
    actions_taken: Optional[List[Dict[str, Any]]] = None
    resolution_notes: Optional[str] = None
    escalated: Optional[bool] = None


class Alert(AlertBase):
    """Complete alert schema"""
    id: UUID
    tenant_id: UUID
    supplier_id: UUID
    status: AlertStatus
    purchase_order_id: Optional[UUID] = None
    delivery_id: Optional[UUID] = None
    performance_metric_id: Optional[UUID] = None
    triggered_at: datetime
    acknowledged_at: Optional[datetime] = None
    acknowledged_by: Optional[UUID] = None
    resolved_at: Optional[datetime] = None
    resolved_by: Optional[UUID] = None
    actions_taken: Optional[List[Dict[str, Any]]] = None
    resolution_notes: Optional[str] = None
    escalated: bool = False
    escalated_at: Optional[datetime] = None
    notification_sent: bool = False
    priority_score: int
    business_impact: Optional[str] = None
    tags: Optional[List[str]] = None
    created_at: datetime
    
    class Config:
        orm_mode = True


# ===== Scorecard Schemas =====

class ScorecardBase(BaseModel):
    """Base schema for supplier scorecards"""
    scorecard_name: str = Field(max_length=255)
    period: PerformancePeriod
    period_start: datetime
    period_end: datetime
    overall_score: float = Field(ge=0, le=100)
    quality_score: float = Field(ge=0, le=100)
    delivery_score: float = Field(ge=0, le=100)
    cost_score: float = Field(ge=0, le=100)
    service_score: float = Field(ge=0, le=100)
    on_time_delivery_rate: float = Field(ge=0, le=100)
    quality_rejection_rate: float = Field(ge=0, le=100)
    order_accuracy_rate: float = Field(ge=0, le=100)
    response_time_hours: float = Field(ge=0)
    cost_variance_percentage: float
    total_orders_processed: int = Field(ge=0, default=0)
    total_amount_processed: Decimal = Field(ge=0, default=0)
    average_order_value: Decimal = Field(ge=0, default=0)
    cost_savings_achieved: Decimal = Field(default=0)


class ScorecardCreate(ScorecardBase):
    """Schema for creating scorecards"""
    supplier_id: UUID
    strengths: Optional[List[str]] = None
    improvement_areas: Optional[List[str]] = None
    recommended_actions: Optional[List[Dict[str, Any]]] = None
    notes: Optional[str] = None


class ScorecardUpdate(BaseModel):
    """Schema for updating scorecards"""
    overall_score: Optional[float] = Field(None, ge=0, le=100)
    quality_score: Optional[float] = Field(None, ge=0, le=100)
    delivery_score: Optional[float] = Field(None, ge=0, le=100)
    cost_score: Optional[float] = Field(None, ge=0, le=100)
    service_score: Optional[float] = Field(None, ge=0, le=100)
    strengths: Optional[List[str]] = None
    improvement_areas: Optional[List[str]] = None
    recommended_actions: Optional[List[Dict[str, Any]]] = None
    notes: Optional[str] = None
    is_final: Optional[bool] = None


class Scorecard(ScorecardBase):
    """Complete scorecard schema"""
    id: UUID
    tenant_id: UUID
    supplier_id: UUID
    overall_rank: Optional[int] = None
    category_rank: Optional[int] = None
    total_suppliers_evaluated: Optional[int] = None
    score_trend: Optional[str] = None
    score_change_percentage: Optional[float] = None
    strengths: Optional[List[str]] = None
    improvement_areas: Optional[List[str]] = None
    recommended_actions: Optional[List[Dict[str, Any]]] = None
    is_final: bool = False
    approved_by: Optional[UUID] = None
    approved_at: Optional[datetime] = None
    notes: Optional[str] = None
    attachments: Optional[List[Dict[str, Any]]] = None
    generated_at: datetime
    generated_by: UUID
    
    class Config:
        orm_mode = True


# ===== Dashboard Schemas =====

class PerformanceDashboardSummary(BaseModel):
    """Performance dashboard summary schema"""
    total_suppliers: int
    active_suppliers: int
    suppliers_above_threshold: int
    suppliers_below_threshold: int
    average_overall_score: float
    average_delivery_rate: float
    average_quality_rate: float
    total_active_alerts: int
    critical_alerts: int
    high_priority_alerts: int
    recent_scorecards_generated: int
    cost_savings_this_month: Decimal
    
    # Performance trends
    performance_trend: str  # improving, declining, stable
    delivery_trend: str
    quality_trend: str
    
    # Business model insights
    detected_business_model: str  # individual_bakery, central_bakery, hybrid
    model_confidence: float
    business_model_metrics: Dict[str, Any]


class SupplierPerformanceInsights(BaseModel):
    """Supplier performance insights schema"""
    supplier_id: UUID
    supplier_name: str
    current_overall_score: float
    previous_score: Optional[float] = None
    score_change_percentage: Optional[float] = None
    performance_rank: Optional[int] = None
    
    # Key performance indicators
    delivery_performance: float
    quality_performance: float
    cost_performance: float
    service_performance: float
    
    # Recent metrics
    orders_last_30_days: int
    average_delivery_time: float
    quality_issues_count: int
    cost_variance: float
    
    # Alert summary
    active_alerts: int
    resolved_alerts_last_30_days: int
    alert_trend: str
    
    # Performance categorization
    performance_category: str  # excellent, good, acceptable, needs_improvement, poor
    risk_level: str           # low, medium, high, critical
    
    # Recommendations
    top_strengths: List[str]
    improvement_priorities: List[str]
    recommended_actions: List[Dict[str, Any]]


class PerformanceAnalytics(BaseModel):
    """Advanced performance analytics schema"""
    period_start: datetime
    period_end: datetime
    total_suppliers_analyzed: int
    
    # Performance distribution
    performance_distribution: Dict[str, int]  # excellent, good, etc.
    score_ranges: Dict[str, List[float]]      # min, max, avg per range
    
    # Trend analysis
    overall_trend: Dict[str, float]           # month-over-month changes
    delivery_trends: Dict[str, float]
    quality_trends: Dict[str, float]
    cost_trends: Dict[str, float]
    
    # Comparative analysis
    top_performers: List[SupplierPerformanceInsights]
    underperformers: List[SupplierPerformanceInsights]
    most_improved: List[SupplierPerformanceInsights]
    biggest_declines: List[SupplierPerformanceInsights]
    
    # Risk analysis
    high_risk_suppliers: List[Dict[str, Any]]
    contract_renewals_due: List[Dict[str, Any]]
    certification_expiries: List[Dict[str, Any]]
    
    # Financial impact
    total_procurement_value: Decimal
    cost_savings_achieved: Decimal
    cost_avoidance: Decimal
    financial_risk_exposure: Decimal


class AlertSummary(BaseModel):
    """Alert summary schema"""
    alert_type: AlertType
    severity: AlertSeverity
    count: int
    avg_resolution_time_hours: Optional[float] = None
    oldest_alert_age_hours: Optional[float] = None
    trend_percentage: Optional[float] = None


class DashboardFilter(BaseModel):
    """Dashboard filter schema"""
    supplier_ids: Optional[List[UUID]] = None
    supplier_categories: Optional[List[str]] = None
    performance_categories: Optional[List[str]] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    include_inactive: bool = False


class AlertFilter(BaseModel):
    """Alert filter schema"""
    alert_types: Optional[List[AlertType]] = None
    severities: Optional[List[AlertSeverity]] = None
    statuses: Optional[List[AlertStatus]] = None
    supplier_ids: Optional[List[UUID]] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    metric_types: Optional[List[PerformanceMetricType]] = None


# ===== Business Model Detection =====

class BusinessModelInsights(BaseModel):
    """Business model detection and insights schema"""
    detected_model: str  # individual_bakery, central_bakery, hybrid
    confidence_score: float
    model_characteristics: Dict[str, Any]
    
    # Model-specific metrics
    supplier_diversity_score: float
    procurement_volume_patterns: Dict[str, Any]
    delivery_frequency_patterns: Dict[str, Any]
    order_size_patterns: Dict[str, Any]
    
    # Recommendations
    optimization_opportunities: List[Dict[str, Any]]
    recommended_supplier_mix: Dict[str, Any]
    cost_optimization_potential: Decimal
    risk_mitigation_suggestions: List[str]
    
    # Benchmarking
    industry_comparison: Dict[str, float]
    peer_comparison: Optional[Dict[str, float]] = None


# ===== Export and Reporting =====

class PerformanceReportRequest(BaseModel):
    """Performance report generation request"""
    report_type: str  # scorecard, analytics, alerts, comprehensive
    format: str = Field(pattern="^(pdf|excel|csv|json)$")
    period: PerformancePeriod
    date_from: datetime
    date_to: datetime
    supplier_ids: Optional[List[UUID]] = None
    include_charts: bool = True
    include_recommendations: bool = True
    include_benchmarks: bool = True
    custom_metrics: Optional[List[str]] = None


class ExportDataResponse(BaseModel):
    """Export data response schema"""
    export_id: UUID
    format: str
    file_url: Optional[str] = None
    file_size_bytes: Optional[int] = None
    generated_at: datetime
    expires_at: datetime
    status: str  # generating, ready, expired, failed
    error_message: Optional[str] = None