from typing import Any

from .._base import AsyncBaseResource, AsyncPageIterator, BaseResource, PageIterator, unwrap_response
from ..models import CustomerUser, CustomerUserGroup


class CustomerUsers(BaseResource):
    _path = "/identity/customer/users"

    def list(self, *, limit: int | None = None, email: str | None = None) -> PageIterator[CustomerUser]:
        return self._list(CustomerUser, params={"limit": limit, "email": email})

    def get(self, id: str) -> CustomerUser:
        return self._get(id, CustomerUser)

    def create(
        self,
        *,
        email: str,
        given_name: str,
        family_name: str,
        group_id: str | None = None,
        phone_number: str | None = None,
        preferred_language: str | None = None,
    ) -> CustomerUser:
        data: dict[str, Any] = {
            "email": email,
            "given_name": given_name,
            "family_name": family_name,
        }
        if group_id is not None:
            data["group_id"] = group_id
        if phone_number is not None:
            data["phone_number"] = phone_number
        if preferred_language is not None:
            data["preferred_language"] = preferred_language
        return self._create(CustomerUser, data)

    def update(
        self,
        id: str,
        *,
        email: str,
        given_name: str,
        family_name: str,
        group_id: str | None = None,
        phone_number: str | None = None,
        preferred_language: str | None = None,
    ) -> CustomerUser:
        data: dict[str, Any] = {
            "email": email,
            "given_name": given_name,
            "family_name": family_name,
        }
        if group_id is not None:
            data["group_id"] = group_id
        if phone_number is not None:
            data["phone_number"] = phone_number
        if preferred_language is not None:
            data["preferred_language"] = preferred_language
        return self._update(id, CustomerUser, data, method="PUT")


class CustomerUserGroups(BaseResource):
    _path = "/identity/customer/user_groups"

    def list(self) -> PageIterator[CustomerUserGroup]:
        return self._list(CustomerUserGroup)

    def get(self, id: str) -> CustomerUserGroup:
        return self._get(id, CustomerUserGroup)

    def create(self, *, name: str, user_ids: "list[str] | None" = None) -> CustomerUserGroup:
        data: dict[str, Any] = {"name": name}
        if user_ids is not None:
            data["user_ids"] = user_ids
        return self._create(CustomerUserGroup, data)

    def update(
        self, id: str, *, name: str | None = None, user_ids: "list[str] | None" = None,
    ) -> CustomerUserGroup:
        data: dict[str, Any] = {}
        if name is not None:
            data["name"] = name
        if user_ids is not None:
            data["user_ids"] = user_ids
        return self._update(id, CustomerUserGroup, data)

    def delete(self, id: str) -> None:
        self._delete(id)


class ComponentClientKeys(BaseResource):
    _path = "/identity/component_client_keys"

    def create(
        self,
        *,
        user_id: str | None = None,
        order_id: str | None = None,
        booking_id: str | None = None,
    ) -> str:
        data: dict[str, Any] = {}
        if user_id is not None:
            data["user_id"] = user_id
        if order_id is not None:
            data["order_id"] = order_id
        if booking_id is not None:
            data["booking_id"] = booking_id
        resp = self._transport.request("POST", self._path, json_body={"data": data} if data else {})
        body = unwrap_response(resp)
        return body["data"]["component_client_key"]


class AsyncCustomerUsers(AsyncBaseResource):
    _path = "/identity/customer/users"

    def list(self, *, limit: int | None = None, email: str | None = None) -> AsyncPageIterator[CustomerUser]:
        return self._list(CustomerUser, params={"limit": limit, "email": email})

    async def get(self, id: str) -> CustomerUser:
        return await self._get(id, CustomerUser)

    async def create(
        self,
        *,
        email: str,
        given_name: str,
        family_name: str,
        group_id: str | None = None,
        phone_number: str | None = None,
        preferred_language: str | None = None,
    ) -> CustomerUser:
        data: dict[str, Any] = {
            "email": email,
            "given_name": given_name,
            "family_name": family_name,
        }
        if group_id is not None:
            data["group_id"] = group_id
        if phone_number is not None:
            data["phone_number"] = phone_number
        if preferred_language is not None:
            data["preferred_language"] = preferred_language
        return await self._create(CustomerUser, data)

    async def update(
        self,
        id: str,
        *,
        email: str,
        given_name: str,
        family_name: str,
        group_id: str | None = None,
        phone_number: str | None = None,
        preferred_language: str | None = None,
    ) -> CustomerUser:
        data: dict[str, Any] = {
            "email": email,
            "given_name": given_name,
            "family_name": family_name,
        }
        if group_id is not None:
            data["group_id"] = group_id
        if phone_number is not None:
            data["phone_number"] = phone_number
        if preferred_language is not None:
            data["preferred_language"] = preferred_language
        return await self._update(id, CustomerUser, data, method="PUT")


class AsyncCustomerUserGroups(AsyncBaseResource):
    _path = "/identity/customer/user_groups"

    def list(self) -> AsyncPageIterator[CustomerUserGroup]:
        return self._list(CustomerUserGroup)

    async def get(self, id: str) -> CustomerUserGroup:
        return await self._get(id, CustomerUserGroup)

    async def create(self, *, name: str, user_ids: "list[str] | None" = None) -> CustomerUserGroup:
        data: dict[str, Any] = {"name": name}
        if user_ids is not None:
            data["user_ids"] = user_ids
        return await self._create(CustomerUserGroup, data)

    async def update(
        self, id: str, *, name: str | None = None, user_ids: "list[str] | None" = None,
    ) -> CustomerUserGroup:
        data: dict[str, Any] = {}
        if name is not None:
            data["name"] = name
        if user_ids is not None:
            data["user_ids"] = user_ids
        return await self._update(id, CustomerUserGroup, data)

    async def delete(self, id: str) -> None:
        await self._delete(id)


class AsyncComponentClientKeys(AsyncBaseResource):
    _path = "/identity/component_client_keys"

    async def create(
        self,
        *,
        user_id: str | None = None,
        order_id: str | None = None,
        booking_id: str | None = None,
    ) -> str:
        data: dict[str, Any] = {}
        if user_id is not None:
            data["user_id"] = user_id
        if order_id is not None:
            data["order_id"] = order_id
        if booking_id is not None:
            data["booking_id"] = booking_id
        resp = await self._transport.request("POST", self._path, json_body={"data": data} if data else {})
        body = unwrap_response(resp)
        return body["data"]["component_client_key"]
