"""Support for loading picture from Neato."""

from datetime import timedelta
import logging
from typing import Any, override

from pybotvac.exceptions import NeatoRobotException
from pybotvac.robot import Robot
from urllib3.response import HTTPResponse

from homeassistant.components.camera import Camera
from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback

from . import NeatoConfigEntry
from .const import SCAN_INTERVAL_MINUTES
from .entity import NeatoEntity
from .hub import NeatoHub

_LOGGER = logging.getLogger(__name__)

SCAN_INTERVAL = timedelta(minutes=SCAN_INTERVAL_MINUTES)
ATTR_GENERATED_AT = "generated_at"


async def async_setup_entry(
    hass: HomeAssistant,
    entry: NeatoConfigEntry,
    async_add_entities: AddConfigEntryEntitiesCallback,
) -> None:
    """Set up Neato camera with config entry."""
    hub = entry.runtime_data
    dev = [
        NeatoCleaningMap(hub, robot, hub.map_data)
        for robot in hub.robots
        if "maps" in robot.traits
    ]

    if not dev:
        return

    _LOGGER.debug("Adding robots for cleaning maps %s", dev)
    async_add_entities(dev, True)


class NeatoCleaningMap(NeatoEntity, Camera):
    """Neato cleaning map for last clean."""

    _attr_translation_key = "cleaning_map"

    def __init__(self, neato: NeatoHub, robot: Robot, mapdata: dict[str, Any]) -> None:
        """Initialize Neato cleaning map."""
        super().__init__(robot)
        Camera.__init__(self)
        self.neato = neato
        self._mapdata = mapdata
        self._available = neato is not None
        self._robot_serial: str = self.robot.serial
        self._attr_unique_id = self.robot.serial
        self._generated_at: str | None = None
        self._image_url: str | None = None
        self._image: bytes | None = None

    @override
    def camera_image(
        self, width: int | None = None, height: int | None = None
    ) -> bytes | None:
        """Return image response."""
        self.update()
        return self._image

    def update(self) -> None:
        """Check the contents of the map list."""

        _LOGGER.debug("Running camera update for '%s'", self.entity_id)
        try:
            self.neato.update_robots()
        except NeatoRobotException as ex:
            if self._available:  # Print only once when available
                _LOGGER.error(
                    "Neato camera connection error for '%s': %s", self.entity_id, ex
                )
            self._image = None
            self._image_url = None
            self._available = False
            return

        if self._mapdata:
            map_data: dict[str, Any] = self._mapdata[self._robot_serial]["maps"][0]
        if (image_url := map_data["url"]) == self._image_url:
            _LOGGER.debug(
                "The map image_url for '%s' is the same as old", self.entity_id
            )
            return

        try:
            image: HTTPResponse = self.neato.download_map(image_url)
        except NeatoRobotException as ex:
            if self._available:  # Print only once when available
                _LOGGER.error(
                    "Neato camera connection error for '%s': %s", self.entity_id, ex
                )
            self._image = None
            self._image_url = None
            self._available = False
            return

        self._image = image.read()
        self._image_url = image_url
        self._generated_at = map_data.get("generated_at")
        self._available = True

    @property
    @override
    def available(self) -> bool:
        """Return if the robot is available."""
        return self._available

    @property
    @override
    def extra_state_attributes(self) -> dict[str, Any]:
        """Return the state attributes of the vacuum cleaner."""
        data: dict[str, Any] = {}

        if self._generated_at is not None:
            data[ATTR_GENERATED_AT] = self._generated_at

        return data
