"""Button platform for the Maintenance Supporter integration.

Per-task action buttons (complete / skip / reset) on each object's device. All
presses delegate to the same coordinator methods that the panel, services, and
mobile-notification actions use — one action layer, no duplicated logic (DRY).
"""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING

from homeassistant.components.button import ButtonEntity
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback

from .const import (
    CONF_OBJECT,
    CONF_TASK_ENABLED,
    CONF_TASKS,
    GLOBAL_UNIQUE_ID,
    slugify_object_name,
    task_unique_id,
)
from .coordinator import MaintenanceCoordinator
from .entity.entity_base import MaintenanceEntity

if TYPE_CHECKING:
    from . import MaintenanceSupporterConfigEntry

_LOGGER = logging.getLogger(__name__)

PARALLEL_UPDATES = 0

# Per-task action buttons. The English suffix is also used in the entity_id /
# friendly name when the task has a custom entity_slug (mirrors binary_sensor's
# "{slug} overdue" convention).
_TASK_ACTIONS: tuple[tuple[str, str], ...] = (
    ("complete", "Complete"),
    ("skip", "Skip"),
    ("reset", "Reset"),
)


async def async_setup_entry(
    hass: HomeAssistant,
    entry: MaintenanceSupporterConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up button entities for a maintenance object (or the global hub)."""
    if entry.unique_id == GLOBAL_UNIQUE_ID:
        # No global buttons — export belongs to the export_data service, not a
        # button entity (a button can't trigger a browser download).
        return

    runtime_data = entry.runtime_data
    if runtime_data is None or runtime_data.coordinator is None:
        _LOGGER.error("No coordinator found for entry %s", entry.entry_id)
        return

    coordinator = runtime_data.coordinator
    tasks = entry.data.get(CONF_TASKS, {})
    entities = [
        MaintenanceActionButton(coordinator, task_id, action, label) for task_id in tasks for action, label in _TASK_ACTIONS
    ]
    async_add_entities(entities)
    _LOGGER.debug("Added %d button entities for %s", len(entities), entry.title)


class MaintenanceActionButton(MaintenanceEntity, ButtonEntity):
    """A per-task action button (complete / skip / reset).

    Pressing it calls the shared coordinator action method — the same path used
    by the maintenance_supporter services and the mobile-notification actions.
    """

    def __init__(
        self,
        coordinator: MaintenanceCoordinator,
        task_id: str,
        action: str,
        label: str,
    ) -> None:
        """Initialize a per-task action button."""
        super().__init__(coordinator, task_id)
        self._action = action

        obj_data = coordinator.entry.data.get(CONF_OBJECT, {})
        task_data = coordinator.entry.data.get(CONF_TASKS, {}).get(task_id, {})
        object_slug = slugify_object_name(obj_data.get("name", "unknown"))

        self._attr_unique_id = task_unique_id(object_slug, task_id, action)
        self._attr_translation_key = f"button_{action}"
        # Custom entity_slug → stable, language-independent entity_id/name.
        entity_slug = task_data.get("entity_slug")
        if entity_slug:
            self._attr_name = f"{entity_slug} {label}"
        self._attr_translation_placeholders = {"task_name": task_data.get("name", "")}

    @property
    def available(self) -> bool:
        """Available only while the coordinator is up and the task is enabled."""
        if not super().available:
            return False
        if not self._task_data:
            return False
        # Archived task → its complete/skip/reset buttons go unavailable (inert).
        if self._task_data.get("archived_at") is not None:
            return False
        task_cfg = self.coordinator.entry.data.get(CONF_TASKS, {}).get(self._task_id, {})
        return bool(task_cfg.get(CONF_TASK_ENABLED, True))

    async def async_press(self) -> None:
        """Run the action via the shared coordinator method (single source)."""
        if not self._task_data:
            raise HomeAssistantError(f"Task {self._task_id} no longer exists")
        if self._action == "complete":
            await self.coordinator.complete_maintenance(
                self._task_id, notes="Completed from dashboard button", unattended=True
            )
        elif self._action == "skip":
            await self.coordinator.skip_maintenance(self._task_id, reason="Skipped from dashboard button")
        elif self._action == "reset":
            await self.coordinator.reset_maintenance(self._task_id)
