"""MQTT source data model.

An MQTTSource represents a connection to an MQTT broker.
Referenced by MQTTLEDClient (MQTT devices), MQTTRule (automations),
and state publishing.
"""

from dataclasses import dataclass, field
from datetime import datetime, timezone
from typing import List, Optional


def _parse_common(data: dict) -> dict:
    """Extract common fields from a dict, parsing timestamps."""
    created = data.get("created_at", "")
    updated = data.get("updated_at", "")
    return {
        "id": data["id"],
        "name": data["name"],
        "created_at": (
            datetime.fromisoformat(created)
            if isinstance(created, str) and created
            else datetime.now(timezone.utc)
        ),
        "updated_at": (
            datetime.fromisoformat(updated)
            if isinstance(updated, str) and updated
            else datetime.now(timezone.utc)
        ),
        "description": data.get("description"),
        "tags": data.get("tags") or [],
    }


@dataclass
class MQTTSource:
    """MQTT broker connection configuration."""

    id: str
    name: str
    created_at: datetime
    updated_at: datetime
    broker_host: str = "localhost"
    broker_port: int = 1883
    username: str = ""
    password: str = ""
    client_id: str = "ledgrab"
    base_topic: str = "ledgrab"
    description: Optional[str] = None
    tags: List[str] = field(default_factory=list)

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "broker_host": self.broker_host,
            "broker_port": self.broker_port,
            "username": self.username,
            "password": self.password,
            "client_id": self.client_id,
            "base_topic": self.base_topic,
            "description": self.description,
            "tags": self.tags,
            "created_at": self.created_at.isoformat(),
            "updated_at": self.updated_at.isoformat(),
        }

    @staticmethod
    def from_dict(data: dict) -> "MQTTSource":
        common = _parse_common(data)
        return MQTTSource(
            **common,
            broker_host=data.get("broker_host", "localhost"),
            broker_port=int(data.get("broker_port", 1883)),
            username=data.get("username", ""),
            password=data.get("password", ""),
            client_id=data.get("client_id", "ledgrab"),
            base_topic=data.get("base_topic", "ledgrab"),
        )
