from __future__ import annotations

import httpx

from .models import (
    PaginatedTelegramAccountListItemList,
    PaginatedTelegramBotListItemList,
    RegisterResponse,
    TelegramAccountResponse,
    TelegramBotResponse,
    TelegramRegisterAccountRequest,
    TelegramRegisterBotRequest,
    TelegramSetWebhookRequest,
    TelegramVerify2FARequest,
    TelegramVerifyCodeRequest,
)


class TelegramTelegramAPI:
    """API endpoints for Telegram."""

    def __init__(self, client: httpx.AsyncClient):
        """Initialize sub-client with shared httpx client."""
        self._client = client

    async def accounts_deactivate_create(self, alias: str) -> TelegramAccountResponse:
        """
        Deactivate an account (keeps session).
        """
        url = f"/api/telegram/accounts/{alias}/deactivate/"
        response = await self._client.post(url)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramAccountResponse.model_validate(response.json())


    async def accounts_delete_destroy(self, alias: str) -> None:
        """
        Permanently delete account and session.
        """
        url = f"/api/telegram/accounts/{alias}/delete/"
        response = await self._client.delete(url)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return None


    async def accounts_verify_2fa_create(
        self,
        alias: str,
        data: TelegramVerify2FARequest,
    ) -> TelegramAccountResponse:
        """
        Submit 2FA password. Password is NEVER stored.
        """
        url = f"/api/telegram/accounts/{alias}/verify_2fa/"
        response = await self._client.post(url, json=data.model_dump(mode="json", exclude_unset=True, exclude_none=True))
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramAccountResponse.model_validate(response.json())


    async def accounts_verify_code_create(
        self,
        alias: str,
        data: TelegramVerifyCodeRequest,
    ) -> TelegramAccountResponse:
        """
        Submit SMS code to complete sign-in.
        """
        url = f"/api/telegram/accounts/{alias}/verify_code/"
        response = await self._client.post(url, json=data.model_dump(mode="json", exclude_unset=True, exclude_none=True))
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramAccountResponse.model_validate(response.json())


    async def accounts_list_list(
        self,
        ordering: str | None = None,
        page: int | None = None,
        page_size: int | None = None,
        search: str | None = None,
    ) -> list[PaginatedTelegramAccountListItemList]:
        """
        List all accounts for the current API key.
        """
        url = "/api/telegram/accounts/list/"
        _params = {
            k: v for k, v in {
                "ordering": ordering,
                "page": page,
                "page_size": page_size,
                "search": search,
            }.items() if v is not None
        }
        response = await self._client.get(url, params=_params)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return PaginatedTelegramAccountListItemList.model_validate(response.json())


    async def accounts_register_create(
        self,
        data: TelegramRegisterAccountRequest,
    ) -> RegisterResponse:
        """
        Register account + send SMS code to phone.
        """
        url = "/api/telegram/accounts/register/"
        response = await self._client.post(url, json=data.model_dump(mode="json", exclude_unset=True, exclude_none=True))
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return RegisterResponse.model_validate(response.json())


    async def bots_destroy(self, alias: str) -> None:
        """
        Delete a bot

        Permanently remove a bot registration. Webhook is deleted from Telegram
        first.
        """
        url = f"/api/telegram/bots/{alias}/"
        response = await self._client.delete(url)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return None


    async def bots_deactivate_create(self, alias: str) -> TelegramBotResponse:
        """
        Deactivate a bot

        Deactivate a bot. Proxy calls will be rejected. Registration is
        preserved.
        """
        url = f"/api/telegram/bots/{alias}/deactivate/"
        response = await self._client.post(url)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramBotResponse.model_validate(response.json())


    async def bots_set_webhook_create(
        self,
        alias: str,
        data: TelegramSetWebhookRequest,
    ) -> TelegramBotResponse:
        """
        Update callback URL

        Update the callback URL where incoming Telegram updates are forwarded.
        """
        url = f"/api/telegram/bots/{alias}/set_webhook/"
        response = await self._client.post(url, json=data.model_dump(mode="json", exclude_unset=True, exclude_none=True))
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramBotResponse.model_validate(response.json())


    async def bots_list_list(
        self,
        ordering: str | None = None,
        page: int | None = None,
        page_size: int | None = None,
        search: str | None = None,
    ) -> list[PaginatedTelegramBotListItemList]:
        """
        List registered bots

        List all Telegram bots registered under the current API key.
        """
        url = "/api/telegram/bots/list/"
        _params = {
            k: v for k, v in {
                "ordering": ordering,
                "page": page,
                "page_size": page_size,
                "search": search,
            }.items() if v is not None
        }
        response = await self._client.get(url, params=_params)
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return PaginatedTelegramBotListItemList.model_validate(response.json())


    async def bots_register_create(
        self,
        data: TelegramRegisterBotRequest,
    ) -> TelegramBotResponse:
        """
        Register a Telegram bot

        Register a Telegram bot by providing its token. The token is encrypted
        and stored — it is never returned via any API endpoint. If a
        callback_url is provided, the webhook is registered in Telegram
        automatically.
        """
        url = "/api/telegram/bots/register/"
        response = await self._client.post(url, json=data.model_dump(mode="json", exclude_unset=True, exclude_none=True))
        if not response.is_success:
            try:
                error_body = response.json()
            except Exception:
                error_body = response.text
            msg = f"{response.status_code}: {error_body}"
            raise httpx.HTTPStatusError(
                msg, request=response.request, response=response
            )
        return TelegramBotResponse.model_validate(response.json())


