"""Tests for SpeechEngineClient and AsyncSpeechEngineClient wrapper methods."""

from unittest.mock import AsyncMock, MagicMock, patch

import pytest

from elevenlabs.speech_engine.client import AsyncSpeechEngineClient as AutogeneratedAsyncSpeechEngineClient
from elevenlabs.speech_engine.client import SpeechEngineClient as AutogeneratedSpeechEngineClient
from elevenlabs.speech_engine.resource import SpeechEngineResource
from elevenlabs.speech_engine_custom import AsyncSpeechEngineClient, SpeechEngineClient
from elevenlabs.types.speech_engine_config import SpeechEngineConfig
from elevenlabs.types.speech_engine_response import SpeechEngineResponse


def _make_sync_client() -> SpeechEngineClient:
    return SpeechEngineClient(client_wrapper=MagicMock())


def _make_async_client() -> AsyncSpeechEngineClient:
    return AsyncSpeechEngineClient(client_wrapper=MagicMock())


# ---------------------------------------------------------------------------
# Sync
# ---------------------------------------------------------------------------


def test_create_returns_resource() -> None:
    client = _make_sync_client()
    mock_response = MagicMock(spec=SpeechEngineResponse, speech_engine_id="seng_abc")

    with patch.object(AutogeneratedSpeechEngineClient, "create", return_value=mock_response):
        result = client.create(speech_engine=SpeechEngineConfig(ws_url="wss://test"))

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"


def test_get_returns_resource() -> None:
    client = _make_sync_client()

    with patch.object(AutogeneratedSpeechEngineClient, "get", return_value=None):
        result = client.get("seng_abc")

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"


def test_update_returns_resource() -> None:
    client = _make_sync_client()

    with patch.object(AutogeneratedSpeechEngineClient, "update", return_value=None):
        result = client.update("seng_abc", name="Renamed")

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"


# ---------------------------------------------------------------------------
# Async
# ---------------------------------------------------------------------------


@pytest.mark.asyncio
async def test_async_create_returns_resource() -> None:
    client = _make_async_client()
    mock_response = MagicMock(spec=SpeechEngineResponse, speech_engine_id="seng_abc")

    with patch.object(AutogeneratedAsyncSpeechEngineClient, "create", new_callable=AsyncMock, return_value=mock_response):
        result = await client.create(speech_engine=SpeechEngineConfig(ws_url="wss://test"))

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"


@pytest.mark.asyncio
async def test_async_get_returns_resource() -> None:
    client = _make_async_client()

    with patch.object(AutogeneratedAsyncSpeechEngineClient, "get", new_callable=AsyncMock, return_value=None):
        result = await client.get("seng_abc")

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"


@pytest.mark.asyncio
async def test_async_update_returns_resource() -> None:
    client = _make_async_client()

    with patch.object(AutogeneratedAsyncSpeechEngineClient, "update", new_callable=AsyncMock, return_value=None):
        result = await client.update("seng_abc", name="Renamed")

    assert isinstance(result, SpeechEngineResource)
    assert result.engine_id == "seng_abc"
