"""Maintenance object model."""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import Any
from uuid import uuid4

from ..const import slugify_object_name


@dataclass
class MaintenanceObject:
    """Represents a physical object that requires maintenance.

    Examples: pool pump, car, HVAC system, water softener.
    """

    id: str = field(default_factory=lambda: uuid4().hex)
    name: str = ""
    area_id: str | None = None
    manufacturer: str | None = None
    model: str | None = None
    serial_number: str | None = None
    installation_date: str | None = None  # ISO format YYYY-MM-DD
    warranty_expiry: str | None = None  # ISO YYYY-MM-DD: warranty expiry date (#67)
    documentation_url: str | None = None  # v1.4.0: link to PDF manual / vendor page (#43)
    notes: str | None = None  # v1.4.10: free-form notes — part numbers, procedures (#46)
    # 2.19: attach to an EXISTING HA device — the object's task entities land
    # on that device's page instead of creating an own virtual device.
    ha_device_id: str | None = None
    # 2.19: another maintenance object's entry_id as parent — the object's
    # device nests under it (HA via_device hierarchy).
    parent_entry_id: str | None = None
    # 2.20 (journey N3): seasonal pause. paused_at set = paused (ISO timestamp
    # marker); paused_until (ISO date) optionally auto-resumes on that day.
    paused_at: str | None = None
    paused_until: str | None = None
    # 2.20 (journey N1): replace flow lineage. On the retired predecessor,
    # replaced_by_entry_id points at the successor; on the successor,
    # predecessor_entry_id points back — history stays findable in both
    # directions.
    predecessor_entry_id: str | None = None
    replaced_by_entry_id: str | None = None
    task_ids: list[str] = field(default_factory=list)

    def to_dict(self) -> dict[str, Any]:
        """Serialize to dictionary for config entry storage."""
        return {
            "id": self.id,
            "name": self.name,
            "area_id": self.area_id,
            "manufacturer": self.manufacturer,
            "model": self.model,
            "serial_number": self.serial_number,
            "installation_date": self.installation_date,
            "warranty_expiry": self.warranty_expiry,
            "documentation_url": self.documentation_url,
            "notes": self.notes,
            "ha_device_id": self.ha_device_id,
            "parent_entry_id": self.parent_entry_id,
            "paused_at": self.paused_at,
            "paused_until": self.paused_until,
            "predecessor_entry_id": self.predecessor_entry_id,
            "replaced_by_entry_id": self.replaced_by_entry_id,
            "task_ids": self.task_ids,
        }

    @classmethod
    def from_dict(cls, data: dict[str, Any]) -> MaintenanceObject:
        """Deserialize from dictionary."""
        return cls(
            id=data.get("id", uuid4().hex),
            name=data.get("name", ""),
            area_id=data.get("area_id"),
            manufacturer=data.get("manufacturer"),
            model=data.get("model"),
            serial_number=data.get("serial_number"),
            installation_date=data.get("installation_date"),
            warranty_expiry=data.get("warranty_expiry"),
            documentation_url=data.get("documentation_url"),
            notes=data.get("notes"),
            ha_device_id=data.get("ha_device_id"),
            parent_entry_id=data.get("parent_entry_id"),
            paused_at=data.get("paused_at"),
            paused_until=data.get("paused_until"),
            predecessor_entry_id=data.get("predecessor_entry_id"),
            replaced_by_entry_id=data.get("replaced_by_entry_id"),
            task_ids=data.get("task_ids", []),
        )

    @property
    def slug(self) -> str:
        """Return a slugified version of the name for use in unique IDs."""
        return slugify_object_name(self.name)
