"""Tests for HeyGen-specific tools.

Generated by GRIMLOCK MCP Factory
"""

import json

import httpx
import pytest
import respx

from videogen_mcp.tools.list_avatars import list_avatars
from videogen_mcp.tools.list_voices import list_voices
from videogen_mcp.tools.create_avatar_video import create_avatar_video
from videogen_mcp.tools.list_templates import list_templates
from videogen_mcp.tools.get_template_details import get_template_details
from videogen_mcp.tools.generate_from_template import generate_from_template


class TestListAvatars:
    """Test cases for list_avatars tool."""

    @pytest.mark.asyncio
    async def test_list_avatars_success(
        self, mock_env, mock_httpx_client, sample_avatars_response
    ):
        """Should return list of avatars."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(200, json=sample_avatars_response)
        )

        result = await list_avatars({})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["count"] == 3
        assert len(data["avatars"]) == 3
        assert data["avatars"][0]["avatar_id"] == "Angela-inblackskirt-20220820"

    @pytest.mark.asyncio
    async def test_list_avatars_filter_gender(
        self, mock_env, mock_httpx_client, sample_avatars_response
    ):
        """Should filter avatars by gender."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(200, json=sample_avatars_response)
        )

        result = await list_avatars({"filter_gender": "female"})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["count"] == 2
        assert all(a["gender"] == "female" for a in data["avatars"])

    @pytest.mark.asyncio
    async def test_list_avatars_exclude_instant(
        self, mock_env, mock_httpx_client, sample_avatars_response
    ):
        """Should exclude instant avatars when requested."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(200, json=sample_avatars_response)
        )

        result = await list_avatars({"include_instant": False})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["count"] == 2

    @pytest.mark.asyncio
    async def test_list_avatars_auth_failure(self, mock_env, mock_httpx_client):
        """Should handle authentication failure."""
        mock_httpx_client.get("https://api.heygen.com/v2/avatars").mock(
            return_value=httpx.Response(401, json={"error": "Unauthorized"})
        )

        result = await list_avatars({})
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "AUTH_FAILED"


class TestListVoices:
    """Test cases for list_voices tool."""

    @pytest.mark.asyncio
    async def test_list_voices_success(
        self, mock_env, mock_httpx_client, sample_voices_response
    ):
        """Should return list of voices."""
        mock_httpx_client.get("https://api.heygen.com/v2/voices").mock(
            return_value=httpx.Response(200, json=sample_voices_response)
        )

        result = await list_voices({})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["count"] == 3
        assert len(data["voices"]) == 3

    @pytest.mark.asyncio
    async def test_list_voices_filter_language(
        self, mock_env, mock_httpx_client, sample_voices_response
    ):
        """Should filter voices by language."""
        mock_httpx_client.get("https://api.heygen.com/v2/voices").mock(
            return_value=httpx.Response(200, json=sample_voices_response)
        )

        result = await list_voices({"filter_language": "en"})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert all("en" in v["language"].lower() for v in data["voices"])

    @pytest.mark.asyncio
    async def test_list_voices_filter_gender(
        self, mock_env, mock_httpx_client, sample_voices_response
    ):
        """Should filter voices by gender."""
        mock_httpx_client.get("https://api.heygen.com/v2/voices").mock(
            return_value=httpx.Response(200, json=sample_voices_response)
        )

        result = await list_voices({"filter_gender": "male"})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert all(v["gender"] == "male" for v in data["voices"])


class TestCreateAvatarVideo:
    """Test cases for create_avatar_video tool."""

    @pytest.mark.asyncio
    async def test_create_avatar_video_success(
        self, mock_env, mock_httpx_client, sample_video_generate_response
    ):
        """Should create avatar video successfully."""
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await create_avatar_video({
            "script": "Hello, welcome to our company!",
            "avatar_id": "Angela-inblackskirt-20220820",
            "voice_id": "1bd001e7e50f421d891986aad5158bc8",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["job_id"] == "heygen-video-abc123def456"
        assert data["service"] == "heygen"
        assert data["status"] == "pending"

    @pytest.mark.asyncio
    async def test_create_avatar_video_with_background(
        self, mock_env, mock_httpx_client, sample_video_generate_response
    ):
        """Should create avatar video with custom background."""
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await create_avatar_video({
            "script": "Hello world!",
            "avatar_id": "Angela-inblackskirt-20220820",
            "voice_id": "1bd001e7e50f421d891986aad5158bc8",
            "background": {"type": "color", "value": "#0000FF"},
            "aspect_ratio": "9:16",
        })
        data = json.loads(result[0].text)

        assert data["success"] is True

    @pytest.mark.asyncio
    async def test_create_avatar_video_test_mode(
        self, mock_env, mock_httpx_client, sample_video_generate_response
    ):
        """Should create avatar video in test mode."""
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await create_avatar_video({
            "script": "Test video",
            "avatar_id": "Angela-inblackskirt-20220820",
            "voice_id": "1bd001e7e50f421d891986aad5158bc8",
            "test_mode": True,
        })
        data = json.loads(result[0].text)

        assert data["success"] is True

    @pytest.mark.asyncio
    async def test_create_avatar_video_quota_exceeded(self, mock_env, mock_httpx_client):
        """Should handle quota exceeded error."""
        mock_httpx_client.post("https://api.heygen.com/v2/video/generate").mock(
            return_value=httpx.Response(402, json={"error": "Quota exceeded"})
        )

        result = await create_avatar_video({
            "script": "Hello",
            "avatar_id": "test-avatar",
            "voice_id": "test-voice",
        })
        data = json.loads(result[0].text)

        assert data["error"] is True


class TestListTemplates:
    """Test cases for list_templates tool."""

    @pytest.mark.asyncio
    async def test_list_templates_success(
        self, mock_env, mock_httpx_client, sample_templates_response
    ):
        """Should return list of templates."""
        mock_httpx_client.get("https://api.heygen.com/v2/templates").mock(
            return_value=httpx.Response(200, json=sample_templates_response)
        )

        result = await list_templates({})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["count"] == 2
        assert len(data["templates"]) == 2
        assert data["templates"][0]["template_id"] == "template-001"


class TestGetTemplateDetails:
    """Test cases for get_template_details tool."""

    @pytest.mark.asyncio
    async def test_get_template_details_success(
        self, mock_env, mock_httpx_client, sample_template_details_response
    ):
        """Should return template details with variables."""
        mock_httpx_client.get("https://api.heygen.com/v2/template/template-001").mock(
            return_value=httpx.Response(200, json=sample_template_details_response)
        )

        result = await get_template_details({"template_id": "template-001"})
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["template_id"] == "template-001"
        assert data["name"] == "Product Demo"
        assert len(data["variables"]) == 3

    @pytest.mark.asyncio
    async def test_get_template_details_not_found(self, mock_env, mock_httpx_client):
        """Should handle template not found."""
        mock_httpx_client.get("https://api.heygen.com/v2/template/invalid").mock(
            return_value=httpx.Response(404, json={"error": "Not found"})
        )

        result = await get_template_details({"template_id": "invalid"})
        data = json.loads(result[0].text)

        assert data["error"] is True
        assert data["code"] == "TEMPLATE_NOT_FOUND"


class TestGenerateFromTemplate:
    """Test cases for generate_from_template tool."""

    @pytest.mark.asyncio
    async def test_generate_from_template_success(
        self, mock_env, mock_httpx_client, sample_video_generate_response
    ):
        """Should generate video from template."""
        mock_httpx_client.post("https://api.heygen.com/v2/template/template-001/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await generate_from_template({
            "template_id": "template-001",
            "variables": {
                "product_name": {
                    "name": "product_name",
                    "type": "text",
                    "properties": {"content": "Amazing Product"},
                }
            },
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
        assert data["job_id"] == "heygen-video-abc123def456"
        assert data["service"] == "heygen"

    @pytest.mark.asyncio
    async def test_generate_from_template_with_title(
        self, mock_env, mock_httpx_client, sample_video_generate_response
    ):
        """Should generate video with custom title."""
        mock_httpx_client.post("https://api.heygen.com/v2/template/template-001/generate").mock(
            return_value=httpx.Response(200, json=sample_video_generate_response)
        )

        result = await generate_from_template({
            "template_id": "template-001",
            "variables": {},
            "title": "My Custom Video",
            "test_mode": True,
        })
        data = json.loads(result[0].text)

        assert data["success"] is True
