"""Type definitions for {{ module_name }}.

This module contains all Pydantic models, settings, and type definitions
for the {{ module_name }} instrument module.

Generated by: madsci new module --template module/instrument
Template version: {{ template_version }}
"""

from typing import Literal, Optional

from madsci.node_module import RestNodeConfig
from pydantic import BaseModel, Field


class {{ module_name | pascal_case }}NodeConfig(RestNodeConfig):
    """Configuration for the {{ module_name | pascal_case }} node.

    This class defines all configuration options for the instrument node.
    Values can be set via environment variables, config files, or programmatically.
    """

    # Server configuration
    node_url: str = Field(
        default="http://localhost:{{ port }}/",
        description="URL where the node REST API is served",
    )

    # Interface configuration
    interface_type: Literal["real", "fake"] = Field(
        default="real",
        description="Which interface to use (real or fake)",
    )

    # Instrument configuration
    device_number: int = Field(
        default=0,
        description="Device number for multi-device setups",
    )

    wait_time: float = Field(
        default=2.0,
        description="Time to wait while running an action, in seconds (simulates hardware timing)",
    )

    measurement_units: str = Field(
        default="counts",
        description="Default units for measurements",
    )


class {{ module_name | pascal_case }}InterfaceConfig(BaseModel):
    """Configuration for the {{ module_name | pascal_case }} hardware interface.

    This class defines settings specific to the hardware interface,
    such as connection parameters and measurement settings.
    """

    connection_timeout: float = Field(
        default=10.0,
        description="Timeout for establishing connection to the instrument, in seconds",
    )

    retry_count: int = Field(
        default=3,
        description="Number of retries for failed operations",
    )

    integration_time: float = Field(
        default=1.0,
        description="Default integration/acquisition time in seconds",
    )


class {{ module_name | pascal_case }}Reading(BaseModel):
    """A single reading from the {{ module_name }} instrument.

    Use this model to define the structure of measurement readings.
    """

    value: float = Field(description="The measured value")
    units: str = Field(default="counts", description="Measurement units")
    timestamp: Optional[float] = Field(
        default=None,
        description="Time the reading was taken (Unix timestamp)",
    )
    channel: Optional[str] = Field(
        default=None,
        description="Measurement channel or sensor identifier",
    )


class {{ module_name | pascal_case }}CalibrationData(BaseModel):
    """Calibration data for the {{ module_name }} instrument."""

    calibrated: bool = Field(default=False, description="Whether the instrument is calibrated")
    calibration_timestamp: Optional[float] = Field(
        default=None,
        description="When calibration was last performed",
    )
    calibration_parameters: dict = Field(
        default_factory=dict,
        description="Instrument-specific calibration parameters",
    )


class {{ module_name | pascal_case }}Result(BaseModel):
    """Result from a {{ module_name }} instrument operation.

    Use this model to define the structure of results from instrument operations.
    """

    success: bool = Field(description="Whether the operation succeeded")
    data: Optional[dict] = Field(
        default=None,
        description="Result data from the operation",
    )
    error_message: Optional[str] = Field(
        default=None,
        description="Error message if operation failed",
    )
