from __future__ import annotations

from typing import Any

from .client import UniServerClient


_default_client = UniServerClient()


def get_client() -> UniServerClient:
    return _default_client


def configure(
    *,
    base_url: str | None = None,
    account_api_key: str | None = None,
    timeout: float | None = None,
) -> UniServerClient:
    if base_url is not None:
        _default_client.set_base_url(base_url)

    if account_api_key is not None:
        _default_client.set_account_api_key(account_api_key)

    if timeout is not None:
        if timeout <= 0:
            raise ValueError("timeout must be greater than zero.")
        _default_client.timeout = float(timeout)

    return _default_client


def set_account_api_key(account_api_key: str) -> None:
    _default_client.set_account_api_key(account_api_key)


def clear_account_api_key() -> None:
    _default_client.clear_account_api_key()


def set_project_api_key(project_id: int | str, project_api_key: str) -> None:
    _default_client.set_project_api_key(project_id, project_api_key)


def get_project_api_key(project_id: int | str) -> str | None:
    return _default_client.get_project_api_key(project_id)


def clear_project_api_key(project_id: int | str) -> None:
    _default_client.clear_project_api_key(project_id)


def clear_all_project_api_keys() -> None:
    _default_client.clear_all_project_api_keys()


def health() -> dict[str, Any] | None:
    return _default_client.health()


def create_account(account_id: str | None = None, display_name: str | None = None) -> dict[str, Any]:
    return _default_client.create_account(account_id=account_id, display_name=display_name)


def get_account(account_api_key: str | None = None) -> dict[str, Any]:
    return _default_client.get_account(account_api_key=account_api_key)


def create_account_api_key(
    label: str | None = None,
    expires_at: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.create_account_api_key(
        label=label,
        expires_at=expires_at,
        account_api_key=account_api_key,
    )


def delete_account_api_key(api_key: str, account_api_key: str | None = None) -> dict[str, Any] | None:
    return _default_client.delete_account_api_key(
        api_key=api_key,
        account_api_key=account_api_key,
    )


def create_project(
    name: str,
    account_api_key: str | None = None,
    remember_project_key: bool = True,
) -> dict[str, Any]:
    return _default_client.create_project(
        name=name,
        account_api_key=account_api_key,
        remember_project_key=remember_project_key,
    )


def list_projects(account_api_key: str | None = None) -> dict[str, Any]:
    return _default_client.list_projects(account_api_key=account_api_key)


def get_project(
    project_id: int | str,
    account_api_key: str | None = None,
    remember_project_key: bool = False,
) -> dict[str, Any]:
    return _default_client.get_project(
        project_id=project_id,
        account_api_key=account_api_key,
        remember_project_key=remember_project_key,
    )


def update_project(project_id: int | str, name: str, account_api_key: str | None = None) -> dict[str, Any]:
    return _default_client.update_project(
        project_id=project_id,
        name=name,
        account_api_key=account_api_key,
    )


def delete_project(project_id: int | str, account_api_key: str | None = None) -> dict[str, Any] | None:
    return _default_client.delete_project(project_id=project_id, account_api_key=account_api_key)


def create_project_api_key(
    project_id: int | str,
    scopes: list[str] | tuple[str, ...] = ("read", "write"),
    expires_at: str | None = None,
    account_api_key: str | None = None,
    remember_project_key: bool = True,
) -> dict[str, Any]:
    return _default_client.create_project_api_key(
        project_id=project_id,
        scopes=scopes,
        expires_at=expires_at,
        account_api_key=account_api_key,
        remember_project_key=remember_project_key,
    )


def delete_project_api_key(
    project_id: int | str,
    api_key: str,
    account_api_key: str | None = None,
) -> dict[str, Any] | None:
    return _default_client.delete_project_api_key(
        project_id=project_id,
        api_key=api_key,
        account_api_key=account_api_key,
    )


def list_kv(
    project_id: int | str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.list_kv(
        project_id=project_id,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def get_kv(
    project_id: int | str,
    item_key: str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.get_kv(
        project_id=project_id,
        item_key=item_key,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def put_kv(
    project_id: int | str,
    item_key: str,
    value: Any,
    expected_version: int | None = None,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.put_kv(
        project_id=project_id,
        item_key=item_key,
        value=value,
        expected_version=expected_version,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def delete_kv(
    project_id: int | str,
    item_key: str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any] | None:
    return _default_client.delete_kv(
        project_id=project_id,
        item_key=item_key,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def list_objects(
    project_id: int | str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.list_objects(
        project_id=project_id,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def get_object(
    project_id: int | str,
    item_key: str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.get_object(
        project_id=project_id,
        item_key=item_key,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def put_object(
    project_id: int | str,
    item_key: str,
    object_type: str,
    serialized: Any,
    encoding: str = "json",
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any]:
    return _default_client.put_object(
        project_id=project_id,
        item_key=item_key,
        object_type=object_type,
        serialized=serialized,
        encoding=encoding,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )


def delete_object(
    project_id: int | str,
    item_key: str,
    project_api_key: str | None = None,
    account_api_key: str | None = None,
) -> dict[str, Any] | None:
    return _default_client.delete_object(
        project_id=project_id,
        item_key=item_key,
        project_api_key=project_api_key,
        account_api_key=account_api_key,
    )
