"""Define /home user management endpoints.

This module contains the HomeUser class for managing shared users
within a Kwikset home, including inviting, updating, and removing users.
"""

from __future__ import annotations

from typing import Any

from .const import (
    DELETE_HOME_USER_URL,
    GET_HOME_USERS_URL,
    INVITE_HOME_USER_URL,
    UPDATE_HOME_USER_URL,
)
from .types import RequestProtocol


class HomeUser:
    """Define an object to handle home user management API endpoints.

    :param request: An async callable conforming to RequestProtocol
    :type request: ``RequestProtocol``
    """

    __slots__ = ("_request",)

    def __init__(self, request: RequestProtocol) -> None:
        """Initialize the HomeUser endpoint handler."""
        self._request: RequestProtocol = request

    async def get_users(self, home_id: str) -> list[dict[str, Any]]:
        """Return all shared users for a home.

        :param home_id: Unique identifier for the home
        :type home_id: ``str``
        :rtype: ``list[dict[str, Any]]``
        """
        response: dict[str, Any] = await self._request(
            "get",
            GET_HOME_USERS_URL % home_id,
        )
        result: list[dict[str, Any]] = response.get("data", [])
        return result

    async def invite_user(
        self,
        home_id: str,
        email: str,
        access_level: str,
        nickname: str,
        allowed_devices: list[str],
        access_time: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        """Invite a new shared user to a home.

        :param home_id: Unique identifier for the home
        :type home_id: ``str``
        :param email: Email address of the user to invite
        :type email: ``str``
        :param access_level: Access level to grant the user
        :type access_level: ``str``
        :param nickname: Display nickname for the shared user
        :type nickname: ``str``
        :param allowed_devices: List of device IDs the user can access
        :type allowed_devices: ``list[str]``
        :param access_time: Optional access time restrictions. Supports
            DATE_RANGE (startdate/enddate) and WEEKLY (starttime/endtime/days).
        :type access_time: ``dict[str, Any] | None``
        :rtype: ``dict[str, Any]``
        """
        body: dict[str, Any] = {
            "email": email,
            "accesslevel": access_level,
            "shareenickname": nickname,
            "alloweddevices": allowed_devices,
        }
        if access_time is not None:
            body["accesstime"] = access_time
        response: dict[str, Any] = await self._request(
            "post",
            INVITE_HOME_USER_URL % home_id,
            json=body,
        )
        return response

    async def update_user(
        self,
        home_id: str,
        email: str,
        access_level: str,
        allowed_devices: list[str],
        access_time: dict[str, Any] | None = None,
    ) -> dict[str, Any]:
        """Update a shared user's access settings.

        :param home_id: Unique identifier for the home
        :type home_id: ``str``
        :param email: Email address of the user to update
        :type email: ``str``
        :param access_level: New access level for the user
        :type access_level: ``str``
        :param allowed_devices: Updated list of device IDs the user can access
        :type allowed_devices: ``list[str]``
        :param access_time: Optional access time restrictions
        :type access_time: ``dict[str, Any] | None``
        :rtype: ``dict[str, Any]``
        """
        body: dict[str, Any] = {
            "accesslevel": access_level,
            "alloweddevices": allowed_devices,
            "accesstime": access_time if access_time is not None else {},
        }
        response: dict[str, Any] = await self._request(
            "patch",
            UPDATE_HOME_USER_URL % (home_id, email),
            json=body,
        )
        return response

    async def delete_user(self, home_id: str, email: str) -> dict[str, Any]:
        """Remove a shared user from a home.

        :param home_id: Unique identifier for the home
        :type home_id: ``str``
        :param email: Email address of the user to remove
        :type email: ``str``
        :rtype: ``dict[str, Any]``
        """
        response: dict[str, Any] = await self._request(
            "delete",
            DELETE_HOME_USER_URL % (home_id, email),
        )
        return response
