# services/production/app/schemas/equipment.py
"""
Equipment schemas for Production Service
"""

from pydantic import BaseModel, Field, ConfigDict
from typing import Optional, List
from datetime import datetime
from uuid import UUID

from app.models.production import EquipmentType, EquipmentStatus, IoTProtocol, IoTConnectionStatus


class IoTConnectionConfig(BaseModel):
    """Schema for IoT connection configuration"""
    protocol: str = Field(..., description="IoT protocol (rest_api, opc_ua, mqtt, modbus, custom)")
    endpoint: str = Field(..., description="Connection endpoint (URL or IP address)")
    port: Optional[int] = Field(None, description="Connection port")
    username: Optional[str] = Field(None, description="Username for authentication")
    password: Optional[str] = Field(None, description="Password for authentication")
    api_key: Optional[str] = Field(None, description="API key for authentication")
    token: Optional[str] = Field(None, description="Authentication token")
    additional_config: Optional[dict] = Field(None, description="Additional protocol-specific configuration")

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "protocol": "rest_api",
                "endpoint": "https://connectedcooking.com/api/v1",
                "port": 443,
                "api_key": "your-api-key-here",
                "additional_config": {"poll_interval": 30}
            }
        }
    )


class EquipmentCreate(BaseModel):
    """Schema for creating new equipment"""
    name: str = Field(..., min_length=1, max_length=255, description="Equipment name")
    type: EquipmentType = Field(..., description="Equipment type")
    model: Optional[str] = Field(None, max_length=100, description="Equipment model")
    serial_number: Optional[str] = Field(None, max_length=100, description="Serial number")
    location: Optional[str] = Field(None, max_length=255, description="Physical location")
    manufacturer: Optional[str] = Field(None, max_length=100, description="Manufacturer")
    firmware_version: Optional[str] = Field(None, max_length=50, description="Firmware version")
    status: EquipmentStatus = Field(default=EquipmentStatus.OPERATIONAL, description="Equipment status")

    # Installation and maintenance
    install_date: Optional[datetime] = Field(None, description="Installation date")
    last_maintenance_date: Optional[datetime] = Field(None, description="Last maintenance date")
    next_maintenance_date: Optional[datetime] = Field(None, description="Next scheduled maintenance date")
    maintenance_interval_days: Optional[int] = Field(None, ge=1, description="Maintenance interval in days")

    # Performance metrics
    efficiency_percentage: Optional[float] = Field(None, ge=0, le=100, description="Current efficiency percentage")
    uptime_percentage: Optional[float] = Field(None, ge=0, le=100, description="Overall uptime percentage")
    energy_usage_kwh: Optional[float] = Field(None, ge=0, description="Current energy usage in kWh")

    # Specifications
    power_kw: Optional[float] = Field(None, ge=0, description="Power consumption in kilowatts")
    capacity: Optional[float] = Field(None, ge=0, description="Equipment capacity")
    weight_kg: Optional[float] = Field(None, ge=0, description="Weight in kilograms")

    # Temperature monitoring
    current_temperature: Optional[float] = Field(None, description="Current temperature")
    target_temperature: Optional[float] = Field(None, description="Target temperature")

    # IoT Connectivity
    iot_enabled: bool = Field(default=False, description="Enable IoT connectivity")
    iot_protocol: Optional[str] = Field(None, description="IoT protocol")
    iot_endpoint: Optional[str] = Field(None, description="IoT endpoint URL or IP")
    iot_port: Optional[int] = Field(None, description="IoT connection port")
    iot_config: Optional[dict] = Field(None, description="IoT configuration")

    # Real-time monitoring
    supports_realtime: bool = Field(default=False, description="Supports real-time monitoring")
    poll_interval_seconds: Optional[int] = Field(None, ge=1, description="Polling interval in seconds")

    # Sensor capabilities
    temperature_zones: Optional[int] = Field(None, ge=1, description="Number of temperature zones")
    supports_humidity: bool = Field(default=False, description="Supports humidity monitoring")
    supports_energy_monitoring: bool = Field(default=False, description="Supports energy monitoring")
    supports_remote_control: bool = Field(default=False, description="Supports remote control")

    # Notes
    notes: Optional[str] = Field(None, description="Additional notes")

    # Support contact information
    support_contact: Optional[dict] = Field(
        None, 
        description="Support contact information for equipment maintenance",
        json_schema_extra={
            "example": {
                "email": "support@ovenfactory.com",
                "phone": "+1-800-555-1234",
                "company": "OvenTech Support",
                "contract_number": "SUP-2023-001",
                "response_time_sla": 24
            }
        }
    )

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "name": "Horno Principal #1",
                "type": "oven",
                "model": "Miwe Condo CO 4.1212",
                "serial_number": "MCO-2021-001",
                "location": "Área de Horneado - Zona A",
                "status": "operational",
                "install_date": "2021-03-15T00:00:00Z",
                "maintenance_interval_days": 90,
                "efficiency_percentage": 92.0,
                "uptime_percentage": 98.5,
                "power_kw": 45.0,
                "capacity": 24.0
            }
        }
    )


class EquipmentUpdate(BaseModel):
    """Schema for updating equipment"""
    name: Optional[str] = Field(None, min_length=1, max_length=255)
    type: Optional[EquipmentType] = None
    model: Optional[str] = Field(None, max_length=100)
    serial_number: Optional[str] = Field(None, max_length=100)
    location: Optional[str] = Field(None, max_length=255)
    manufacturer: Optional[str] = Field(None, max_length=100)
    firmware_version: Optional[str] = Field(None, max_length=50)
    status: Optional[EquipmentStatus] = None

    # Installation and maintenance
    install_date: Optional[datetime] = None
    last_maintenance_date: Optional[datetime] = None
    next_maintenance_date: Optional[datetime] = None
    maintenance_interval_days: Optional[int] = Field(None, ge=1)

    # Performance metrics
    efficiency_percentage: Optional[float] = Field(None, ge=0, le=100)
    uptime_percentage: Optional[float] = Field(None, ge=0, le=100)
    energy_usage_kwh: Optional[float] = Field(None, ge=0)

    # Specifications
    power_kw: Optional[float] = Field(None, ge=0)
    capacity: Optional[float] = Field(None, ge=0)
    weight_kg: Optional[float] = Field(None, ge=0)

    # Temperature monitoring
    current_temperature: Optional[float] = None
    target_temperature: Optional[float] = None

    # IoT Connectivity
    iot_enabled: Optional[bool] = None
    iot_protocol: Optional[str] = None
    iot_endpoint: Optional[str] = None
    iot_port: Optional[int] = None
    iot_config: Optional[dict] = None

    # Real-time monitoring
    supports_realtime: Optional[bool] = None
    poll_interval_seconds: Optional[int] = Field(None, ge=1)

    # Sensor capabilities
    temperature_zones: Optional[int] = Field(None, ge=1)
    supports_humidity: Optional[bool] = None
    supports_energy_monitoring: Optional[bool] = None
    supports_remote_control: Optional[bool] = None

    # Notes
    notes: Optional[str] = None

    # Support contact information
    support_contact: Optional[dict] = None

    # Status flag
    is_active: Optional[bool] = None

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "status": "maintenance",
                "last_maintenance_date": "2024-01-15T00:00:00Z",
                "next_maintenance_date": "2024-04-15T00:00:00Z",
                "efficiency_percentage": 88.0
            }
        }
    )


class EquipmentResponse(BaseModel):
    """Schema for equipment response"""
    id: UUID
    tenant_id: UUID
    name: str
    type: EquipmentType
    model: Optional[str] = None
    serial_number: Optional[str] = None
    location: Optional[str] = None
    manufacturer: Optional[str] = None
    firmware_version: Optional[str] = None
    status: EquipmentStatus

    # Installation and maintenance
    install_date: Optional[datetime] = None
    last_maintenance_date: Optional[datetime] = None
    next_maintenance_date: Optional[datetime] = None
    maintenance_interval_days: Optional[int] = None

    # Performance metrics
    efficiency_percentage: Optional[float] = None
    uptime_percentage: Optional[float] = None
    energy_usage_kwh: Optional[float] = None

    # Specifications
    power_kw: Optional[float] = None
    capacity: Optional[float] = None
    weight_kg: Optional[float] = None

    # Temperature monitoring
    current_temperature: Optional[float] = None
    target_temperature: Optional[float] = None

    # IoT Connectivity
    iot_enabled: bool = False
    iot_protocol: Optional[str] = None
    iot_endpoint: Optional[str] = None
    iot_port: Optional[int] = None
    iot_connection_status: Optional[str] = None
    iot_last_connected: Optional[datetime] = None
    iot_config: Optional[dict] = None

    # Real-time monitoring
    supports_realtime: bool = False
    poll_interval_seconds: Optional[int] = None

    # Sensor capabilities
    temperature_zones: Optional[int] = None
    supports_humidity: bool = False
    supports_energy_monitoring: bool = False
    supports_remote_control: bool = False

    # Status
    is_active: bool
    notes: Optional[str] = None

    # Support contact information
    support_contact: Optional[dict] = None

    # Timestamps
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class EquipmentListResponse(BaseModel):
    """Schema for paginated equipment list response"""
    equipment: List[EquipmentResponse]
    total_count: int
    page: int
    page_size: int

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "equipment": [],
                "total_count": 10,
                "page": 1,
                "page_size": 50
            }
        }
    )


class EquipmentDeletionSummary(BaseModel):
    """Schema for equipment deletion summary"""
    can_delete: bool = Field(..., description="Whether the equipment can be deleted")
    warnings: List[str] = Field(default_factory=list, description="List of warnings about deletion")
    production_batches_count: int = Field(default=0, description="Number of production batches using this equipment")
    maintenance_records_count: int = Field(default=0, description="Number of maintenance records")
    temperature_logs_count: int = Field(default=0, description="Number of temperature logs")
    equipment_name: Optional[str] = Field(None, description="Equipment name")
    equipment_type: Optional[str] = Field(None, description="Equipment type")
    equipment_location: Optional[str] = Field(None, description="Equipment location")

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "can_delete": True,
                "warnings": ["3 production batch(es) are using this equipment"],
                "production_batches_count": 3,
                "maintenance_records_count": 5,
                "temperature_logs_count": 120,
                "equipment_name": "Horno Principal #1",
                "equipment_type": "oven",
                "equipment_location": "Área de Horneado"
            }
        }
    )


# ================================================================
# IoT-SPECIFIC SCHEMAS
# ================================================================

class EquipmentSensorReadingResponse(BaseModel):
    """Schema for equipment sensor reading response"""
    id: UUID
    tenant_id: UUID
    equipment_id: UUID
    batch_id: Optional[UUID] = None
    reading_time: datetime

    # Temperature readings
    temperature: Optional[float] = None
    temperature_zones: Optional[dict] = None
    target_temperature: Optional[float] = None

    # Humidity
    humidity: Optional[float] = None
    target_humidity: Optional[float] = None

    # Energy monitoring
    energy_consumption_kwh: Optional[float] = None
    power_current_kw: Optional[float] = None

    # Equipment status
    operational_status: Optional[str] = None
    cycle_stage: Optional[str] = None
    cycle_progress_percentage: Optional[float] = None
    time_remaining_minutes: Optional[int] = None

    # Process parameters
    motor_speed_rpm: Optional[float] = None
    door_status: Optional[str] = None
    steam_level: Optional[float] = None

    # Quality indicators
    product_weight_kg: Optional[float] = None
    moisture_content: Optional[float] = None

    # Additional sensor data
    additional_sensors: Optional[dict] = None

    # Data quality
    data_quality_score: Optional[float] = None
    is_anomaly: bool = False

    created_at: datetime

    model_config = ConfigDict(from_attributes=True)


class EquipmentConnectionTestResponse(BaseModel):
    """Schema for IoT connection test response"""
    success: bool = Field(..., description="Whether connection test succeeded")
    status: str = Field(..., description="Connection status")
    message: str = Field(..., description="Detailed message")
    response_time_ms: Optional[int] = Field(None, description="Response time in milliseconds")
    protocol_tested: str = Field(..., description="Protocol that was tested")
    endpoint_tested: str = Field(..., description="Endpoint that was tested")
    error_details: Optional[str] = Field(None, description="Error details if connection failed")
    supported_features: Optional[List[str]] = Field(None, description="List of supported IoT features")

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "success": True,
                "status": "connected",
                "message": "Successfully connected to equipment",
                "response_time_ms": 145,
                "protocol_tested": "rest_api",
                "endpoint_tested": "https://connectedcooking.com/api/v1",
                "supported_features": ["temperature", "humidity", "energy_monitoring"]
            }
        }
    )


class RealTimeDataResponse(BaseModel):
    """Schema for real-time equipment data response"""
    equipment_id: UUID
    equipment_name: str
    timestamp: datetime
    connection_status: str

    # Current readings
    temperature: Optional[float] = None
    temperature_zones: Optional[dict] = None
    humidity: Optional[float] = None
    energy_consumption_kwh: Optional[float] = None
    power_current_kw: Optional[float] = None

    # Status
    operational_status: Optional[str] = None
    cycle_stage: Optional[str] = None
    cycle_progress_percentage: Optional[float] = None
    time_remaining_minutes: Optional[int] = None

    # Active batch
    active_batch_id: Optional[UUID] = None
    active_batch_name: Optional[str] = None

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "equipment_id": "123e4567-e89b-12d3-a456-426614174000",
                "equipment_name": "Horno Principal #1",
                "timestamp": "2025-01-12T10:30:00Z",
                "connection_status": "connected",
                "temperature": 185.5,
                "temperature_zones": {"zone1": 180, "zone2": 190, "zone3": 185},
                "humidity": 65.0,
                "operational_status": "running",
                "cycle_stage": "baking",
                "cycle_progress_percentage": 45.0,
                "time_remaining_minutes": 12
            }
        }
    )


class EquipmentIoTAlertResponse(BaseModel):
    """Schema for IoT alert response"""
    id: UUID
    tenant_id: UUID
    equipment_id: UUID
    batch_id: Optional[UUID] = None

    # Alert information
    alert_type: str
    severity: str
    alert_time: datetime

    # Alert details
    title: str
    message: str

    # Threshold information
    threshold_value: Optional[float] = None
    actual_value: Optional[float] = None
    deviation_percentage: Optional[float] = None

    # Status
    is_active: bool
    is_acknowledged: bool
    acknowledged_by: Optional[UUID] = None
    acknowledged_at: Optional[datetime] = None

    is_resolved: bool
    resolved_by: Optional[UUID] = None
    resolved_at: Optional[datetime] = None
    resolution_notes: Optional[str] = None

    # Automated response
    auto_resolved: bool
    corrective_action_taken: Optional[str] = None

    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class EquipmentSensorHistoryResponse(BaseModel):
    """Schema for sensor reading history response"""
    equipment_id: UUID
    equipment_name: str
    start_time: datetime
    end_time: datetime
    total_readings: int
    readings: List[EquipmentSensorReadingResponse]

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "equipment_id": "123e4567-e89b-12d3-a456-426614174000",
                "equipment_name": "Horno Principal #1",
                "start_time": "2025-01-12T08:00:00Z",
                "end_time": "2025-01-12T12:00:00Z",
                "total_readings": 48,
                "readings": []
            }
        }
    )
