from __future__ import annotations

from typing import TYPE_CHECKING, Any

from ...._constants import EMPTY_JSON
from ...._endpoints import Characters
from ...._internal._builders.characters import build_character_datacards_body
from ...._internal._schemas import APIEnvelope
from ...._internal._schemas.characters.characters_datacards import (
    DataCard,
    Gender,
    MyDataCards,
)
from ..._base import BaseResource

if TYPE_CHECKING:
    from ...._async_client import AsyncClient
else:
    AsyncClient = Any


class AsyncCharactersDataCardsResource(BaseResource[AsyncClient]):
    """Manages user datacards for character interactions (async).

    Datacards are user persona profiles (username, avatar, age, gender,
    likes/dislikes) that get attached to character chat sessions.

    Accessible via ``client.characters.datacards``.
    """

    async def create(
        self,
        *,
        account_id: str | None = None,
        username: str | None = None,
        age: int | None = None,
        avatar_height: int | None = None,
        avatar_url: str | None = None,
        avatar_width: int | None = None,
        dislike: str | None = None,
        extra: str | None = None,
        gender: Gender | None = None,
        is_default: int | None = None,
        is_main: bool | None = None,
        like: str | None = None,
    ) -> APIEnvelope[DataCard]:
        """Create a new user data card.

        All parameters are optional; omit any you do not want to set.
        ``account_id`` defaults to the authenticated account if not provided.

        Note:
            ``avatar_url``, ``avatar_width``, and ``avatar_height`` must all
            be provided together — if any one is missing, the avatar is
            omitted from the request entirely.

        Args:
            account_id: Account to create the card for. Defaults to the
                authenticated account.
            username: Display name shown in character chats.
            age: User age.
            avatar_url: URL of the avatar image.
            avatar_width: Width of the avatar image in pixels.
            avatar_height: Height of the avatar image in pixels.
            dislike: Things the user dislikes (free-form text).
            extra: Additional free-form profile information.
            gender: User gender. Note that ``"femail"`` is a typo in the
                upstream API (not a local one).
            is_default: Whether this card is the default (API-level flag).
            is_main: Whether this card is the main card.
            like: Things the user likes (free-form text).

        Returns:
            ``APIEnvelope[DataCard]`` — ``.value.id`` contains the new
            card's ID.

        Example:
            >>> card = await client.characters.datacards.create(
            ...     username="Alice", age=25, gender="femail",
            ...     like="cats, coffee", dislike="loud noises",
            ... )
            >>> print(card.value.id)
        """
        body = build_character_datacards_body(
            account_id=account_id or await self._client.get_account_id(),
            age=age,
            avatar_height=avatar_height,
            avatar_url=avatar_url,
            avatar_width=avatar_width,
            dislike=dislike,
            extra=extra,
            gender=gender,
            is_default=is_default,
            is_main=is_main,
            like=like,
            username=username,
        )
        env = await self._client.request_route(
            Characters.DataCards.CREATE,
            json=body.model_dump(exclude_none=True),
        )
        return APIEnvelope[DataCard].model_validate(env)

    async def my(self) -> APIEnvelope[MyDataCards]:
        """Retrieve all data cards for the authenticated account.

        Returns:
            ``APIEnvelope[MyDataCards]`` — ``.value.items`` is a list of
            ``DataCard`` objects, each with ``.id``, ``.username``,
            ``.avatar``, ``.age``, ``.gender``, etc.

        Example:
            >>> result = await client.characters.datacards.my()
            >>> for card in result.value.items or []:
            ...     print(card.id, card.username)
        """
        env = await self._client.request_route(
            Characters.DataCards.MY,
            json=EMPTY_JSON,
        )
        return APIEnvelope[MyDataCards].model_validate(env)
