from typing import Optional

from pydantic import BaseModel


class DeviceInfo(BaseModel):
    """
    Information about the device associated with the entity.

    Attributes:
        identifiers (list[str]): A list of IDs that uniquely identify the device.
        name (Optional[str]): The name of the device.
        model (Optional[str]): The model of the device.
        manufacturer (Optional[str]): The manufacturer of the device.
        sw_version (Optional[str]): The software version of the device.
    """

    identifiers: list[str]
    name: Optional[str] = None
    model: Optional[str] = None
    manufacturer: Optional[str] = None
    sw_version: Optional[str] = None


class DiscoveryEntity(BaseModel):
    """
    Represents an entity for Home Assistant MQTT Discovery.

    Attributes:
        name (Optional[str]): The name of the entity.
        unique_id (str): A unique identifier for the entity.
        object_id (Optional[str]): Used to generate the entity ID in Home Assistant.
        device_class (Optional[str]): The class of the device (e.g., 'temperature').
        state_topic (str): The MQTT topic where the entity's state is published.
        unit_of_measurement (Optional[str]): The unit of measurement (e.g., '°C').
        device (Optional[DeviceInfo]): Information about the device the entity belongs to.
        icon (Optional[str]): The icon to display in the frontend.
        value_template (Optional[str]): Template to extract the value from the payload.
        payload_on (Optional[str]): The payload that represents the 'on' state.
        payload_off (Optional[str]): The payload that represents the 'off' state.
    """

    name: Optional[str] = None
    unique_id: str
    object_id: Optional[str] = None
    device_class: Optional[str] = None
    state_topic: str
    unit_of_measurement: Optional[str] = None
    device: Optional[DeviceInfo] = None
    icon: Optional[str] = None
    value_template: Optional[str] = None
    payload_on: Optional[str] = None
    payload_off: Optional[str] = None
    # Add other common fields as needed

    def get_topic(self, prefix: str = "homeassistant", component: str = "sensor") -> str:
        """
        Generates the discovery topic.
        Format: <discovery_prefix>/<component>/[<node_id>/]<object_id>/config
        """
        # Using unique_id as object_id for simplicity if not provided,
        # but topic construction usually relies on object_id.
        oid = self.object_id or self.unique_id
        return f"{prefix}/{component}/{oid}/config"
