"""Base entity for the Maintenance Supporter integration."""

from __future__ import annotations

from typing import Any

from homeassistant.helpers import device_registry as dr
from homeassistant.helpers.device_registry import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from ..const import CONF_OBJECT, DOMAIN, GLOBAL_UNIQUE_ID
from ..coordinator import MaintenanceCoordinator


class MaintenanceEntity(CoordinatorEntity[MaintenanceCoordinator]):
    """Base class for Maintenance Supporter entities."""

    _attr_has_entity_name = True

    def __init__(
        self,
        coordinator: MaintenanceCoordinator,
        task_id: str,
    ) -> None:
        """Initialize the base entity."""
        super().__init__(coordinator)
        self._task_id = task_id
        self._object_data = coordinator.entry.data.get(CONF_OBJECT, {})

    @property
    def device_info(self) -> DeviceInfo:
        """Return device info for this maintenance object.

        Three shapes (2.19, device attachment):

        * ``ha_device_id`` set → attach to that EXISTING device: return only
          its identifiers/connections so the registry merges us onto it — no
          name/manufacturer, which would overwrite the owning integration's
          metadata (the obj→device forward-sync skips linked objects too).
        * ``parent_entry_id`` set → our own device, nested under the parent
          object's device via ``via_device``.
        * neither → our own stand-alone device (the historical shape).
        """
        obj = self._object_data
        hass = self.coordinator.hass

        if device_id := obj.get("ha_device_id"):
            device = dr.async_get(hass).async_get(device_id)
            if device is not None and (device.identifiers or device.connections):
                info = DeviceInfo()
                if device.identifiers:
                    info["identifiers"] = device.identifiers
                if device.connections:
                    info["connections"] = device.connections
                return info
            # Linked device vanished → fall through to an own device so the
            # entities never end up device-less.

        identifiers = {(DOMAIN, self.coordinator.entry.unique_id or "")}

        device_info = DeviceInfo(
            identifiers=identifiers,
            name=obj.get("name", "Unknown"),
        )

        if obj.get("manufacturer"):
            device_info["manufacturer"] = obj["manufacturer"]
        if obj.get("model"):
            device_info["model"] = obj["model"]
        if obj.get("serial_number"):
            device_info["serial_number"] = obj["serial_number"]
        if obj.get("area_id"):
            device_info["suggested_area"] = obj["area_id"]

        if parent_entry_id := obj.get("parent_entry_id"):
            parent = hass.config_entries.async_get_entry(parent_entry_id)
            if parent is not None and parent.domain == DOMAIN and parent.unique_id and parent.unique_id != GLOBAL_UNIQUE_ID:
                device_info["via_device"] = (DOMAIN, parent.unique_id)

        return device_info

    @property
    def _task_data(self) -> dict[str, Any]:
        """Return the current task data from coordinator."""
        if self.coordinator.data is None:
            return {}
        tasks: dict[str, Any] = self.coordinator.data.get("tasks", {})
        result: dict[str, Any] = tasks.get(self._task_id, {})
        return result
