"""Home Assistant source schemas (CRUD + test + entities)."""

from datetime import datetime
from typing import List, Optional

from pydantic import BaseModel, Field


class HomeAssistantSourceCreate(BaseModel):
    """Request to create a Home Assistant source."""

    name: str = Field(description="Source name", min_length=1, max_length=100)
    host: str = Field(description="HA host:port (e.g. '192.168.1.100:8123')", min_length=1)
    token: str = Field(description="Long-Lived Access Token", min_length=1)
    use_ssl: bool = Field(default=False, description="Use wss:// instead of ws://")
    entity_filters: List[str] = Field(
        default_factory=list, description="Entity ID filter patterns (e.g. ['sensor.*'])"
    )
    description: Optional[str] = Field(None, description="Optional description", max_length=500)
    tags: List[str] = Field(default_factory=list, description="User-defined tags")


class HomeAssistantSourceUpdate(BaseModel):
    """Request to update a Home Assistant source."""

    name: Optional[str] = Field(None, description="Source name", min_length=1, max_length=100)
    host: Optional[str] = Field(None, description="HA host:port", min_length=1)
    token: Optional[str] = Field(None, description="Long-Lived Access Token", min_length=1)
    use_ssl: Optional[bool] = Field(None, description="Use wss://")
    entity_filters: Optional[List[str]] = Field(None, description="Entity ID filter patterns")
    description: Optional[str] = Field(None, description="Optional description", max_length=500)
    tags: Optional[List[str]] = None


class HomeAssistantSourceResponse(BaseModel):
    """Home Assistant source response."""

    id: str = Field(description="Source ID")
    name: str = Field(description="Source name")
    host: str = Field(description="HA host:port")
    use_ssl: bool = Field(description="Whether SSL is enabled")
    entity_filters: List[str] = Field(default_factory=list, description="Entity filter patterns")
    connected: bool = Field(default=False, description="Whether the WebSocket connection is active")
    entity_count: int = Field(default=0, description="Number of cached entities")
    description: Optional[str] = Field(None, description="Description")
    tags: List[str] = Field(default_factory=list, description="User-defined tags")
    created_at: datetime = Field(description="Creation timestamp")
    updated_at: datetime = Field(description="Last update timestamp")


class HomeAssistantSourceListResponse(BaseModel):
    """List of Home Assistant sources."""

    sources: List[HomeAssistantSourceResponse] = Field(description="List of HA sources")
    count: int = Field(description="Number of sources")


class HomeAssistantEntityResponse(BaseModel):
    """A single HA entity."""

    entity_id: str = Field(description="Entity ID (e.g. 'sensor.temperature')")
    state: str = Field(description="Current state value")
    friendly_name: str = Field(description="Human-readable name")
    domain: str = Field(description="Entity domain (e.g. 'sensor', 'binary_sensor')")


class HomeAssistantEntityListResponse(BaseModel):
    """List of entities from a HA instance."""

    entities: List[HomeAssistantEntityResponse] = Field(description="List of entities")
    count: int = Field(description="Number of entities")


class HomeAssistantTestResponse(BaseModel):
    """Connection test result."""

    success: bool = Field(description="Whether connection and auth succeeded")
    ha_version: Optional[str] = Field(None, description="Home Assistant version")
    entity_count: int = Field(default=0, description="Number of entities found")
    error: Optional[str] = Field(None, description="Error message if connection failed")


class HomeAssistantConnectionStatus(BaseModel):
    """Connection status for dashboard indicators."""

    source_id: str
    name: str
    connected: bool
    entity_count: int


class HomeAssistantStatusResponse(BaseModel):
    """Overall HA integration status for dashboard."""

    connections: List[HomeAssistantConnectionStatus]
    total_sources: int
    connected_count: int
