# ================================================================
# services/inventory/app/schemas/food_safety.py
# ================================================================
"""
Food safety schemas for Inventory Service
"""

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


# ===== Food Safety Compliance Schemas =====

class FoodSafetyComplianceBase(BaseModel):
    ingredient_id: UUID
    standard: str
    compliance_status: str = Field(default="pending_review")
    certification_number: Optional[str] = None
    certifying_body: Optional[str] = None
    certification_date: Optional[datetime] = None
    expiration_date: Optional[datetime] = None
    requirements: Optional[Dict[str, Any]] = None
    compliance_notes: Optional[str] = None
    documentation_url: Optional[str] = None
    last_audit_date: Optional[datetime] = None
    next_audit_date: Optional[datetime] = None
    auditor_name: Optional[str] = None
    audit_score: Optional[float] = Field(None, ge=0, le=100)
    risk_level: str = Field(default="medium")
    risk_factors: Optional[List[str]] = None
    mitigation_measures: Optional[List[str]] = None
    requires_monitoring: bool = Field(default=True)
    monitoring_frequency_days: Optional[int] = Field(None, gt=0)


class FoodSafetyComplianceCreate(FoodSafetyComplianceBase):
    tenant_id: UUID


class FoodSafetyComplianceUpdate(BaseModel):
    compliance_status: Optional[str] = None
    certification_number: Optional[str] = None
    certifying_body: Optional[str] = None
    certification_date: Optional[datetime] = None
    expiration_date: Optional[datetime] = None
    requirements: Optional[Dict[str, Any]] = None
    compliance_notes: Optional[str] = None
    documentation_url: Optional[str] = None
    last_audit_date: Optional[datetime] = None
    next_audit_date: Optional[datetime] = None
    auditor_name: Optional[str] = None
    audit_score: Optional[float] = Field(None, ge=0, le=100)
    risk_level: Optional[str] = None
    risk_factors: Optional[List[str]] = None
    mitigation_measures: Optional[List[str]] = None
    requires_monitoring: Optional[bool] = None
    monitoring_frequency_days: Optional[int] = Field(None, gt=0)


class FoodSafetyComplianceResponse(FoodSafetyComplianceBase):
    id: UUID
    tenant_id: UUID
    is_active: bool
    created_at: datetime
    updated_at: datetime
    created_by: Optional[UUID] = None
    updated_by: Optional[UUID] = None

    class Config:
        from_attributes = True


# ===== Temperature Monitoring Schemas =====

class TemperatureLogBase(BaseModel):
    storage_location: str = Field(..., min_length=1, max_length=100)
    warehouse_zone: Optional[str] = Field(None, max_length=50)
    equipment_id: Optional[str] = Field(None, max_length=100)
    temperature_celsius: float
    humidity_percentage: Optional[float] = Field(None, ge=0, le=100)
    target_temperature_min: Optional[float] = None
    target_temperature_max: Optional[float] = None
    measurement_method: str = Field(default="manual")
    device_id: Optional[str] = Field(None, max_length=100)
    calibration_date: Optional[datetime] = None


class TemperatureLogCreate(TemperatureLogBase):
    tenant_id: UUID


class TemperatureLogResponse(TemperatureLogBase):
    id: UUID
    tenant_id: UUID
    is_within_range: bool
    alert_triggered: bool
    deviation_minutes: Optional[int] = None
    recorded_at: datetime
    created_at: datetime
    recorded_by: Optional[UUID] = None

    class Config:
        from_attributes = True


# ===== Food Safety Alert Schemas =====

class FoodSafetyAlertBase(BaseModel):
    alert_type: str
    severity: str = Field(default="medium")
    risk_level: str = Field(default="medium")
    source_entity_type: str
    source_entity_id: UUID
    ingredient_id: Optional[UUID] = None
    stock_id: Optional[UUID] = None
    title: str = Field(..., min_length=1, max_length=200)
    description: str = Field(..., min_length=1)
    detailed_message: Optional[str] = None
    regulatory_requirement: Optional[str] = Field(None, max_length=100)
    compliance_standard: Optional[str] = None
    regulatory_action_required: bool = Field(default=False)
    trigger_condition: Optional[str] = Field(None, max_length=200)
    threshold_value: Optional[Decimal] = None
    actual_value: Optional[Decimal] = None
    alert_data: Optional[Dict[str, Any]] = None
    environmental_factors: Optional[Dict[str, Any]] = None
    affected_products: Optional[List[UUID]] = None
    public_health_risk: bool = Field(default=False)
    business_impact: Optional[str] = None
    estimated_loss: Optional[Decimal] = Field(None, ge=0)


class FoodSafetyAlertCreate(FoodSafetyAlertBase):
    tenant_id: UUID
    alert_code: str = Field(..., min_length=1, max_length=50)


class FoodSafetyAlertUpdate(BaseModel):
    status: Optional[str] = None
    alert_state: Optional[str] = None
    immediate_actions_taken: Optional[List[str]] = None
    investigation_notes: Optional[str] = None
    resolution_action: Optional[str] = Field(None, max_length=200)
    resolution_notes: Optional[str] = None
    corrective_actions: Optional[List[str]] = None
    preventive_measures: Optional[List[str]] = None
    assigned_to: Optional[UUID] = None
    assigned_role: Optional[str] = Field(None, max_length=50)
    escalated_to: Optional[UUID] = None
    escalation_deadline: Optional[datetime] = None
    documentation: Optional[Dict[str, Any]] = None


class FoodSafetyAlertResponse(FoodSafetyAlertBase):
    id: UUID
    tenant_id: UUID
    alert_code: str
    status: str
    alert_state: str
    immediate_actions_taken: Optional[List[str]] = None
    investigation_notes: Optional[str] = None
    resolution_action: Optional[str] = None
    resolution_notes: Optional[str] = None
    corrective_actions: Optional[List[str]] = None
    preventive_measures: Optional[List[str]] = None
    first_occurred_at: datetime
    last_occurred_at: datetime
    acknowledged_at: Optional[datetime] = None
    resolved_at: Optional[datetime] = None
    escalation_deadline: Optional[datetime] = None
    occurrence_count: int
    is_recurring: bool
    recurrence_pattern: Optional[str] = None
    assigned_to: Optional[UUID] = None
    assigned_role: Optional[str] = None
    escalated_to: Optional[UUID] = None
    escalation_level: int
    notification_sent: bool
    notification_methods: Optional[List[str]] = None
    notification_recipients: Optional[List[str]] = None
    regulatory_notification_required: bool
    regulatory_notification_sent: bool
    documentation: Optional[Dict[str, Any]] = None
    audit_trail: Optional[List[Dict[str, Any]]] = None
    external_reference: Optional[str] = None
    detection_time: Optional[datetime] = None
    response_time_minutes: Optional[int] = None
    resolution_time_minutes: Optional[int] = None
    alert_accuracy: Optional[bool] = None
    false_positive: bool
    feedback_notes: Optional[str] = None
    created_at: datetime
    updated_at: datetime
    created_by: Optional[UUID] = None
    updated_by: Optional[UUID] = None

    class Config:
        from_attributes = True


# ===== Bulk Operations Schemas =====

class BulkTemperatureLogCreate(BaseModel):
    """Schema for bulk temperature logging"""
    tenant_id: UUID
    readings: List[TemperatureLogBase] = Field(..., min_items=1, max_items=100)


class BulkComplianceUpdate(BaseModel):
    """Schema for bulk compliance updates"""
    tenant_id: UUID
    updates: List[Dict[str, Any]] = Field(..., min_items=1, max_items=50)


# ===== Filter and Query Schemas =====

class FoodSafetyFilter(BaseModel):
    """Filtering options for food safety data"""
    compliance_standards: Optional[List[str]] = None
    compliance_statuses: Optional[List[str]] = None
    risk_levels: Optional[List[str]] = None
    alert_types: Optional[List[str]] = None
    severities: Optional[List[str]] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    assigned_to: Optional[UUID] = None
    include_resolved: bool = False
    regulatory_action_required: Optional[bool] = None


class TemperatureMonitoringFilter(BaseModel):
    """Filtering options for temperature monitoring"""
    storage_locations: Optional[List[str]] = None
    equipment_ids: Optional[List[str]] = None
    date_from: Optional[datetime] = None
    date_to: Optional[datetime] = None
    violations_only: bool = False
    alerts_only: bool = False


# ===== Analytics Schemas =====

class FoodSafetyMetrics(BaseModel):
    """Food safety performance metrics"""
    compliance_rate: Decimal = Field(..., ge=0, le=100)
    temperature_compliance_rate: Decimal = Field(..., ge=0, le=100)
    alert_response_time_avg: Optional[Decimal] = None
    alert_resolution_time_avg: Optional[Decimal] = None
    recurring_issues_count: int
    regulatory_violations: int
    certification_coverage: Decimal = Field(..., ge=0, le=100)
    audit_score_avg: Optional[Decimal] = Field(None, ge=0, le=100)
    risk_score: Decimal = Field(..., ge=0, le=10)


class TemperatureAnalytics(BaseModel):
    """Temperature monitoring analytics"""
    total_readings: int
    violations_count: int
    violation_rate: Decimal = Field(..., ge=0, le=100)
    average_temperature: Decimal
    temperature_range: Dict[str, Decimal]
    longest_violation_hours: Optional[int] = None
    equipment_performance: List[Dict[str, Any]]
    location_performance: List[Dict[str, Any]]


# ===== Notification Schemas =====

class AlertNotificationPreferences(BaseModel):
    """User preferences for alert notifications"""
    email_enabled: bool = True
    sms_enabled: bool = False
    whatsapp_enabled: bool = False
    dashboard_enabled: bool = True
    severity_threshold: str = Field(default="medium")  # Only notify for this severity and above
    alert_types: Optional[List[str]] = None  # Specific alert types to receive
    quiet_hours_start: Optional[str] = Field(None, pattern=r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")
    quiet_hours_end: Optional[str] = Field(None, pattern=r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$")
    weekend_notifications: bool = True