"""Tests for generations resources."""

import httpx
import pytest
from pytest_httpx import HTTPXMock

from midjourney_proxy_mcp.resources import get_generation_by_id, get_generations

pytestmark = pytest.mark.asyncio


class TestGetGenerations:
    """Tests for get_generations function."""

    async def test_get_all_generations(self, httpx_mock: HTTPXMock) -> None:
        """Fetch all generations without filter."""
        httpx_mock.add_response(
            method="GET",
            url=httpx.URL(
                "https://cl.imagineapi.dev/items/images",
                params={"limit": "100", "offset": "0"},
            ),
            json={
                "data": [
                    {
                        "id": "img-1",
                        "prompt": "First image prompt",
                        "status": "completed",
                        "result": "https://cdn.imagineapi.dev/1.png",
                        "url": "https://cdn.imagineapi.dev/1.png",
                        "results": None,
                        "progress": 100,
                        "upscaled_urls": [
                            "https://cdn.imagineapi.dev/1-u1.png",
                            "https://cdn.imagineapi.dev/1-u2.png",
                        ],
                        "upscaled": ["u1-id", "u2-id"],
                        "ref": None,
                        "error": None,
                        "user_created": "user-abc",
                        "date_created": "2024-01-01T00:00:00Z",
                    },
                    {
                        "id": "img-2",
                        "prompt": "Second image prompt",
                        "status": "pending",
                        "result": None,
                        "url": None,
                        "results": None,
                        "progress": None,
                        "upscaled_urls": None,
                        "upscaled": None,
                        "ref": None,
                        "error": None,
                        "user_created": "user-abc",
                        "date_created": "2024-01-02T00:00:00Z",
                    },
                ],
                "meta": {"total": 2},
            },
        )

        result = await get_generations()

        assert len(result) == 2
        assert result[0]["id"] == "img-1"
        assert result[0]["status"] == "completed"
        assert result[0]["url"] == "https://cdn.imagineapi.dev/1.png"
        assert result[0]["upscaled_urls"] == [
            "https://cdn.imagineapi.dev/1-u1.png",
            "https://cdn.imagineapi.dev/1-u2.png",
        ]
        assert result[0]["date_created"] == "2024-01-01T00:00:00Z"
        assert result[1]["id"] == "img-2"
        assert result[1]["status"] == "pending"
        assert "url" not in result[1]
        assert "upscaled_urls" not in result[1]

    async def test_get_generations_with_status_filter(self, httpx_mock: HTTPXMock) -> None:
        """Fetch generations filtered by status."""
        httpx_mock.add_response(
            method="GET",
            url=httpx.URL(
                "https://cl.imagineapi.dev/items/images",
                params={
                    "limit": "100",
                    "offset": "0",
                    "filter[status][_eq]": "completed",
                },
            ),
            json={
                "data": [
                    {
                        "id": "img-completed",
                        "prompt": "Completed image",
                        "status": "completed",
                        "result": "https://cdn.imagineapi.dev/completed.png",
                        "url": "https://cdn.imagineapi.dev/completed.png",
                        "results": None,
                        "progress": 100,
                        "upscaled_urls": None,
                        "upscaled": None,
                        "ref": None,
                        "error": None,
                        "user_created": "user-abc",
                        "date_created": "2024-01-01T00:00:00Z",
                    },
                ],
                "meta": {"total": 1},
            },
        )

        result = await get_generations(status="completed")

        assert len(result) == 1
        assert result[0]["status"] == "completed"

    async def test_get_generations_truncates_long_prompt(self, httpx_mock: HTTPXMock) -> None:
        """Long prompts are truncated to 100 characters."""
        long_prompt = "A" * 150

        httpx_mock.add_response(
            method="GET",
            url=httpx.URL(
                "https://cl.imagineapi.dev/items/images",
                params={"limit": "100", "offset": "0"},
            ),
            json={
                "data": [
                    {
                        "id": "img-long",
                        "prompt": long_prompt,
                        "status": "pending",
                        "result": None,
                        "url": None,
                        "results": None,
                        "progress": None,
                        "upscaled_urls": None,
                        "upscaled": None,
                        "ref": None,
                        "error": None,
                        "user_created": "user-abc",
                        "date_created": "2024-01-01T00:00:00Z",
                    },
                ],
                "meta": None,
            },
        )

        result = await get_generations()

        assert len(result[0]["prompt"]) == 103  # 100 + "..."
        assert result[0]["prompt"].endswith("...")

    async def test_get_generations_empty_list(self, httpx_mock: HTTPXMock) -> None:
        """Return empty list when no generations exist."""
        httpx_mock.add_response(
            method="GET",
            url=httpx.URL(
                "https://cl.imagineapi.dev/items/images",
                params={"limit": "100", "offset": "0"},
            ),
            json={"data": [], "meta": {"total": 0}},
        )

        result = await get_generations()

        assert result == []


class TestGetGenerationById:
    """Tests for get_generation_by_id function."""

    async def test_get_pending_generation(self, httpx_mock: HTTPXMock) -> None:
        """Fetch pending generation details."""
        httpx_mock.add_response(
            method="GET",
            url="https://cl.imagineapi.dev/items/images/img-123",
            json={
                "data": {
                    "id": "img-123",
                    "prompt": "A beautiful sunset over the ocean",
                    "status": "pending",
                    "result": None,
                    "url": None,
                    "results": None,
                    "progress": None,
                    "upscaled_urls": None,
                    "upscaled": None,
                    "ref": "my-ref-id",
                    "error": None,
                    "user_created": "user-abc",
                    "date_created": "2024-01-01T00:00:00Z",
                }
            },
        )

        result = await get_generation_by_id("img-123")

        assert result["id"] == "img-123"
        assert result["prompt"] == "A beautiful sunset over the ocean"
        assert result["status"] == "pending"
        assert result["ref"] == "my-ref-id"
        assert result["date_created"] == "2024-01-01T00:00:00Z"
        assert "progress" not in result
        assert "url" not in result
        assert "upscaled_urls" not in result
        assert "error" not in result

    async def test_get_in_progress_generation(self, httpx_mock: HTTPXMock) -> None:
        """Fetch in-progress generation with progress percentage."""
        httpx_mock.add_response(
            method="GET",
            url="https://cl.imagineapi.dev/items/images/img-456",
            json={
                "data": {
                    "id": "img-456",
                    "prompt": "A majestic mountain landscape",
                    "status": "in-progress",
                    "result": None,
                    "url": None,
                    "results": None,
                    "progress": 65,
                    "upscaled_urls": None,
                    "upscaled": None,
                    "ref": None,
                    "error": None,
                    "user_created": "user-abc",
                    "date_created": "2024-01-01T00:00:00Z",
                }
            },
        )

        result = await get_generation_by_id("img-456")

        assert result["id"] == "img-456"
        assert result["status"] == "in-progress"
        assert result["progress"] == 65
        assert "url" not in result
        assert "ref" not in result

    async def test_get_completed_generation(self, httpx_mock: HTTPXMock) -> None:
        """Fetch completed generation with URLs and upscaled images."""
        httpx_mock.add_response(
            method="GET",
            url="https://cl.imagineapi.dev/items/images/img-789",
            json={
                "data": {
                    "id": "img-789",
                    "prompt": "A cyberpunk cityscape at night",
                    "status": "completed",
                    "result": "https://cdn.imagineapi.dev/images/result.png",
                    "url": "https://cdn.imagineapi.dev/images/result.png",
                    "results": None,
                    "progress": 100,
                    "upscaled_urls": [
                        "https://cdn.imagineapi.dev/images/u1.png",
                        "https://cdn.imagineapi.dev/images/u2.png",
                        "https://cdn.imagineapi.dev/images/u3.png",
                        "https://cdn.imagineapi.dev/images/u4.png",
                    ],
                    "upscaled": ["u1-id", "u2-id", "u3-id", "u4-id"],
                    "ref": "cyberpunk-ref",
                    "error": None,
                    "user_created": "user-xyz",
                    "date_created": "2024-01-01T00:00:00Z",
                }
            },
        )

        result = await get_generation_by_id("img-789")

        assert result["id"] == "img-789"
        assert result["status"] == "completed"
        assert result["url"] == "https://cdn.imagineapi.dev/images/result.png"
        assert len(result["upscaled_urls"]) == 4
        assert result["ref"] == "cyberpunk-ref"
        assert result["date_created"] == "2024-01-01T00:00:00Z"
        assert "progress" not in result
        assert "error" not in result

    async def test_get_failed_generation(self, httpx_mock: HTTPXMock) -> None:
        """Fetch failed generation with error message."""
        httpx_mock.add_response(
            method="GET",
            url="https://cl.imagineapi.dev/items/images/img-failed",
            json={
                "data": {
                    "id": "img-failed",
                    "prompt": "Invalid prompt content",
                    "status": "failed",
                    "result": None,
                    "url": None,
                    "results": None,
                    "progress": None,
                    "upscaled_urls": None,
                    "upscaled": None,
                    "ref": None,
                    "error": "Prompt contains banned content",
                    "user_created": "user-abc",
                    "date_created": "2024-01-01T00:00:00Z",
                }
            },
        )

        result = await get_generation_by_id("img-failed")

        assert result["id"] == "img-failed"
        assert result["status"] == "failed"
        assert result["error"] == "Prompt contains banned content"
        assert "url" not in result
        assert "upscaled_urls" not in result
        assert "progress" not in result

    async def test_get_generation_not_found(self, httpx_mock: HTTPXMock) -> None:
        """Raise error when generation not found."""
        from midjourney_proxy_mcp.client import ImagineAPIError

        httpx_mock.add_response(
            method="GET",
            url="https://cl.imagineapi.dev/items/images/not-exist",
            status_code=404,
            json={"error": "Not found"},
        )

        with pytest.raises(ImagineAPIError) as exc_info:
            await get_generation_by_id("not-exist")

        assert exc_info.value.status_code == 404


@pytest.mark.integration
class TestGenerationsResourcesIntegration:
    """Integration tests for generations resources (requires IMAGINEAPI_TOKEN)."""

    async def test_get_generations_real_api(self) -> None:
        """Fetch generations from real API."""
        result = await get_generations()

        assert isinstance(result, list)
        for item in result:
            assert "id" in item
            assert "prompt" in item
            assert "status" in item
