"""Support for Litter-Robot updates."""

from __future__ import annotations

from datetime import timedelta
from typing import Any

from pylitterbot import LitterRobot4

from homeassistant.components.update import (
    UpdateDeviceClass,
    UpdateEntity,
    UpdateEntityDescription,
    UpdateEntityFeature,
)
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from .const import DOMAIN
from .coordinator import LitterRobotConfigEntry
from .entity import LitterRobotEntity, whisker_command

PARALLEL_UPDATES = 1

SCAN_INTERVAL = timedelta(days=1)

FIRMWARE_UPDATE_ENTITY = UpdateEntityDescription(
    key="firmware",
    device_class=UpdateDeviceClass.FIRMWARE,
)
RELEASE_URL = "https://www.litter-robot.com/releases.html"


async def async_setup_entry(
    hass: HomeAssistant,
    entry: LitterRobotConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up Litter-Robot update platform."""
    coordinator = entry.runtime_data
    known_robots: set[str] = set()

    def _check_robots() -> None:
        all_robots = list(coordinator.litter_robots())
        current_robots = {robot.serial for robot in all_robots}
        new_robots = current_robots - known_robots
        if new_robots:
            known_robots.update(new_robots)
            entities = (
                RobotUpdateEntity(
                    robot=robot,
                    coordinator=coordinator,
                    description=FIRMWARE_UPDATE_ENTITY,
                )
                for robot in all_robots
                if robot.serial in new_robots
                if isinstance(robot, LitterRobot4)
            )
            async_add_entities(entities, True)

    _check_robots()
    entry.async_on_unload(coordinator.async_add_listener(_check_robots))


class RobotUpdateEntity(LitterRobotEntity[LitterRobot4], UpdateEntity):
    """A class that describes robot update entities."""

    _attr_release_url = RELEASE_URL
    _attr_supported_features = (
        UpdateEntityFeature.INSTALL | UpdateEntityFeature.PROGRESS
    )

    @property
    def installed_version(self) -> str:
        """Version installed and in use."""
        return self.robot.firmware

    @property
    def in_progress(self) -> bool:
        """Update installation progress."""
        return self.robot.firmware_update_triggered

    @property
    def should_poll(self) -> bool:
        """Set polling to True."""
        return True

    async def async_update(self) -> None:
        """Update the entity."""
        # If the robot has a firmware update already in progress, checking for the
        # latest firmware informs that an update has already been triggered, no
        # firmware information is returned and we won't know the latest version.
        if not self.robot.firmware_update_triggered:
            latest_version = await self.robot.get_latest_firmware(True)
            if not await self.robot.has_firmware_update():
                latest_version = self.robot.firmware
            self._attr_latest_version = latest_version

    @whisker_command
    async def async_install(
        self, version: str | None, backup: bool, **kwargs: Any
    ) -> None:
        """Install an update."""
        if await self.robot.has_firmware_update(True):
            if not await self.robot.update_firmware():
                raise HomeAssistantError(
                    translation_domain=DOMAIN,
                    translation_key="firmware_update_failed",
                    translation_placeholders={"name": self.robot.name},
                )
