"""Pydantic schemas for the Expose API (M5-T12).

Three endpoints:
  GET  /api/expose           — catalog + toggle state + MQTT/Discovery status
  PUT  /api/expose           — set toggles (map key → bool)
  POST /api/expose/republish — trigger discovery re-publish
"""

from __future__ import annotations

from pydantic import BaseModel


# ---------------------------------------------------------------------------
# Nested schemas
# ---------------------------------------------------------------------------


class DeviceInfoSchema(BaseModel):
    """HA device grouping info for an exposable entity."""

    identifiers: list[str]
    name: str


class ExposableEntitySchema(BaseModel):
    """One exposable entity in the catalog.

    ``value_getter`` is intentionally excluded — it is a non-serialisable
    callable and is only used internally by the HA Discovery service.
    """

    key: str
    component: str
    device: DeviceInfoSchema
    device_class: str | None
    unit: str
    name: str
    state_class: str | None = None


class CatalogEntrySchema(BaseModel):
    """An entity from the catalog with its current toggle state."""

    entity: ExposableEntitySchema
    enabled: bool


class MqttStatusSchema(BaseModel):
    """Connection status for MQTT and HA Discovery."""

    mqtt_configured: bool
    mqtt_connected: bool
    discovery_enabled: bool


# ---------------------------------------------------------------------------
# Response schemas
# ---------------------------------------------------------------------------


class ExposeResponse(BaseModel):
    """Response for GET /api/expose."""

    catalog: list[CatalogEntrySchema]
    mqtt_status: MqttStatusSchema


class ExposeUpdateResponse(BaseModel):
    """Response for PUT /api/expose (returns updated catalog + status)."""

    catalog: list[CatalogEntrySchema]
    mqtt_status: MqttStatusSchema


class RepublishResponse(BaseModel):
    """Response for POST /api/expose/republish."""

    ok: bool
    message: str


# ---------------------------------------------------------------------------
# Request schemas
# ---------------------------------------------------------------------------


class ExposeUpdateRequest(BaseModel):
    """Request body for PUT /api/expose.

    ``toggles`` is a map from entity key to desired enabled state (bool).
    Only keys present in the map are updated; absent keys are untouched.
    """

    toggles: dict[str, bool]
