from __future__ import annotations

from typing import TYPE_CHECKING, Any

from ..._constants import EMPTY_JSON
from ..._endpoints import Account
from ..._internal._builders.account import (
    build_edit_body,
    build_settings_body,
)
from ..._internal._schemas import APIEnvelope
from ..._internal._schemas.account import (
    AccountInfo,
    EditAccountStatus,
    HomeSet,
    OverviewSettings,
)
from .._base import BaseResource

if TYPE_CHECKING:
    from ..._sync_client import SyncClient
else:
    SyncClient = Any


class AccountResource(BaseResource[SyncClient]):
    """Manages the authenticated account (sync).

    Accessible via ``client.account``.
    """

    def me(self) -> APIEnvelope[AccountInfo]:
        """Retrieve information about the authenticated account.

        Returns:
            ``APIEnvelope[AccountInfo]`` — ``.value`` contains account
            details: ID, email, display name, avatar, subscription info,
            and more.

        Example:
            >>> info = client.account.me()
            >>> print(info.value.name, info.value.email)
        """
        env = self._client.request_route(Account.ME, json=EMPTY_JSON)
        return APIEnvelope[AccountInfo].model_validate(env)

    def edit(
        self,
        *,
        avatar_url: str | None = None,
        nickname: str | None = None,
        home_set: HomeSet | None = None,
        overview: OverviewSettings | None = None,
    ) -> APIEnvelope[EditAccountStatus]:
        """Edit account profile settings.

        Only parameters explicitly passed are included in the request.

        Args:
            avatar_url: URL of the new profile avatar image.
            nickname: Account display name.
            home_set: Home page settings (bio, background image, gender
                display, etc.). Pass a ``HomeSet`` instance.
            overview: Controls which sections are visible on the profile
                overview. Pass an ``OverviewSettings`` instance.

        Returns:
            ``APIEnvelope[EditAccountStatus]`` — ``.value.status`` is
            ``1`` on success.

        Example:
            >>> client.account.edit(nickname="Alice")
        """
        body = build_edit_body(
            avatar_url=avatar_url,
            nickname=nickname,
            home_set=home_set,
            overview=overview,
        )
        env = self._client.request_route(
            Account.EDIT,
            json=body.model_dump(exclude_none=True),
        )
        return APIEnvelope[EditAccountStatus].model_validate(env)

    def settings(
        self,
        *,
        auto_pub_community: int | None = None,
        localization: int | None = None,
        ai_video_auto_play: int | None = None,
        auto_save_artwork: int | None = None,
        age_confirm: bool | None = None,
        nsfw_plus: int | None = None,
        mode: int | None = None,
    ) -> APIEnvelope[None]:
        """Update account preference settings.

        Only parameters explicitly passed are included in the request.

        Args:
            auto_pub_community: Whether to automatically publish generated
                content to the community feed.
            localization: Localization setting identifier.
            ai_video_auto_play: Whether AI-generated videos autoplay.
            auto_save_artwork: Whether generated artworks are saved
                automatically.
            age_confirm: Whether the user has confirmed their age.
            nsfw_plus: NSFW content level flag.
            mode: Internal API parameter for various options.

        Returns:
            ``APIEnvelope[None]`` — the server returns no data payload on
            success.

        Example:
            >>> client.account.settings(auto_save_artwork=1)
        """
        body = build_settings_body(
            auto_pub_community=auto_pub_community,
            localization=localization,
            ai_video_auto_play=ai_video_auto_play,
            auto_save_artwork=auto_save_artwork,
            age_confirm=age_confirm,
            nsfw_plus=nsfw_plus,
            mode=mode,
        )
        return APIEnvelope[None].model_validate(
            self._client.request_route(
                Account.SETTINGS,
                json=body.model_dump(exclude_none=True),
            )
        )

    def update_password(
        self, *, new_password: str, current_password: str
    ) -> APIEnvelope[None]:
        """Update the account password.

        Args:
            new_password: New password to set.
            current_password: Current password to confirm the change.

        Returns:
            ``APIEnvelope[None]`` — the server returns no data payload on
            success.

        Raises:
            InvalidPasswordError: If the current password is incorrect.

        Example:
            >>> client.account.update_password(
            ...     current_password="old_pass",
            ...     new_password="new_pass",
            ... )
        """
        return APIEnvelope[None].model_validate(
            self._client.request_route(
                Account.PASSWORD,
                json={"new": new_password, "old": current_password},
            )
        )

    def delete(self, username: str) -> APIEnvelope[None]:
        """Delete (cancel) the current account.

        Note:
            This action is irreversible. All data associated with the
            account may be permanently removed.

        Args:
            username: Account username, used to confirm the deletion.

        Returns:
            ``APIEnvelope[None]`` — the server returns no data payload on
            success.

        Example:
            >>> client.account.delete("my_username")
        """
        return APIEnvelope[None].model_validate(
            self._client.request_route(Account.CANCEL, json={"username": username})
        )
