from datetime import datetime
from typing import List, Optional
from uuid import UUID

from pydantic import Field

from src.database.schema import CommonParams
from src.database.service import CommonParameters
from src.models import DefultBase, Pagination
from src.aeros_equipment.schema import MasterEquipment, EquipmentWithCustomParameters

# Pydantic models for request/response validation
class SimulationInput(DefultBase):
    SchematicName: str = Field("- TJB - Unit 3 -", max_length=100)
    SimSeed: int = 1
    SimDuration: int = 3
    DurationUnit: str = Field("UYear", max_length=20)
    SimNumRun: int = 1
    SimulationName: str = Field("DefaultSimulation", max_length=100, pattern=r"^[a-zA-Z0-9_\-\s]+$")
    CustomInput: dict = {}
    IsDefault:bool = False
    Konkin_offset: Optional[int] = 0
    OffSet: Optional[int] = 0
    MaintenanceOutages:  Optional[int] = 0
    PlannedOutages:  Optional[int] = 0
    OverhaulInterval:  Optional[int] = Field(0)
    OverhaulDuration:  Optional[int] = Field(1200)
    AhmJobId: Optional[str] = Field(None, max_length=50)

class SimulationNode(DefultBase):
    id: UUID
    node_type: Optional[str] = Field(None, max_length=50)
    node_id: Optional[int]
    node_name: Optional[str] = Field(None, max_length=100)
    structure_name: Optional[str] = Field(None, max_length=100)
    schematic_name: Optional[str] = Field(None, max_length=100)
    schematic_id: Optional[UUID]
    model_image: Optional[list] = Field(None)
    equipment:Optional[MasterEquipment] = None

class SimulationCalc(DefultBase):
    id: UUID
    total_downtime: float
    total_uptime: float
    num_events: float
    production: float
    production_std: float
    ideal_production: float
    availability: float
    efficiency: float
    effective_loss: float
    num_cm: float
    cm_waiting_time: float
    total_cm_downtime: float
    num_pm: float
    total_pm_downtime: float
    num_ip: float
    total_ip_downtime: float
    num_oh: float
    total_oh_downtime: float
    t_wait_for_crew: float
    t_wait_for_spare: float
    duration_at_full: float
    duration_above_hh: float
    duration_above_h: float
    duration_below_l: float
    duration_below_ll: float
    duration_at_empty: float
    stg_input: float
    eaf: float
    eaf_konkin: Optional[float]
    efor: Optional[float]
    derating_hours: Optional[float]
    aeros_node: SimulationNode
    contribution: Optional[float] = 0
    criticality: Optional[float]
    contribution_factor: Optional[float]
    sof: Optional[float]

class SimulationPlot(DefultBase):
    id: UUID
    max_flow_rate: float
    storage_capacity: float
    point_availabilities: list
    point_flowrates: list
    timestamp_outs: list
    aeros_node: SimulationNode



class SimulationNodeWithResult(SimulationNode):
    calc_results: List[SimulationCalc]


class SimulationCalcResult(DefultBase):
    id: UUID
    calc_results: List[SimulationCalc]


class SimulationPlotResult(DefultBase):
    id: UUID
    plot_results: List[SimulationPlot]

class SimulationData(DefultBase):
    id: UUID
    simulation_name: str = Field(..., max_length=100) 
    status: str = Field(..., max_length=20)
    schematic_name: str = Field(..., max_length=100)
    created_at: datetime
    started_at: datetime
    duration: Optional[int]= 0
    offset:Optional[int] = 0

class SimulationRankingParameters(EquipmentWithCustomParameters):
    availability:float


class SimulationPagination(Pagination):
    items: List[SimulationData] = []


class AhmMetricInput(DefultBase):
    target_simulation_id: str = Field(..., max_length=50)
    baseline_simulation_id: Optional[str] = Field(None, max_length=50)
    
class YearlySimulationInput(DefultBase):
    year: int
    
    
class SimulationQueryModel(CommonParams):
    status: Optional[str] = Field(None, max_length=20)
    
    
class SimulationCalcResultQuery(DefultBase):
    schematic_name: Optional[str] = Field(None, max_length=100)
    node_type: Optional[str] = Field(None, alias="nodetype", max_length=50)