from pydantic import BaseModel, Field
from pydantic_settings import BaseSettings
import yaml
from pathlib import Path

class TimeoutConfig(BaseModel):
    length_minutes: int = Field(1, ge=0, description="Length of the calibration timeout in minutes")
    min_calibrations: int = Field(1, ge=0, le=3, description="Number of devices to calibrate before the timeout countdown starts. Zero means timer starts alongside arm movements")
    wrap_up_seconds: int = Field(15, ge=0, description="Maximum time alotted to wrap-up phase after timeout countdown ends")

class DelaysConfig(BaseModel):
    mcu_seconds: int = Field(2, ge=0, description="Delay after device connect before accessing the MCU")
    lighthouse_seconds: int = Field(4, ge=0, description="Added delay after mcu_seconds before accessing the lighthouse device")
    begin_motion_seconds: int = Field(0, ge=0, description="Delay before starting the motion path loop")
    lhcalib_interval: int = Field(3, ge=0, description="Time between lhcalib calls during calibration")

class Settings(BaseSettings):
    basestation_count: int = Field(3, ge=1, le=4, description="Number of basestations in the calibration area")
    clear_device_monitor_history: bool = Field(True, description="Whether to reset history of processed devices at end of run")
    total_sensor_hits: int = Field(800, ge=100, le=4000, description="Number of total sensor hits required during calibration. Secondary requirement to hits_per_sensor")
    hits_per_sensor: int = Field(200, ge=25, le=1000, description="Number of total sensor hits required during calibration. Secondary requirement to hits_per_sensor")

    timeout: TimeoutConfig
    delays: DelaysConfig
        
    @classmethod
    def from_yaml(cls, yaml_path="calibot_config.yaml"):
        """Load settings from YAML file"""
        config_path = Path(yaml_path)
        if not config_path.exists():
            raise FileNotFoundError(f"Config file not found: {yaml_path}")
            
        with open(config_path, 'r') as f:
            yaml_data = yaml.safe_load(f)
        
        # Create instance with YAML data and env overrides
        return cls(**yaml_data)
    
    # Reload config into the current class instance. Return true if there is a change in any field.
    def reload(self, yaml_path="calibot_config.yaml"):
        new_config = Settings.from_yaml(yaml_path)
        changed = False
        for field in self.__fields__:
            if getattr(self, field) != getattr(new_config, field):
                changed = True
                setattr(self, field, getattr(new_config, field))
        return changed


# Load settings when module is imported
config = Settings.from_yaml()