from types import SimpleNamespace

import pytest

from app.services.generate_ai_image.config import GenerateAiImageServiceConfig
from app.services.generate_ai_image.models.requests import GenerateAiImageRequest
from app.services.generate_ai_image.service import GenerateAiImageService
from app.services.generate_ai_image import service as service_module


@pytest.mark.anyio("asyncio")
async def test_generate_ai_image_uses_responses_api_and_logs_analytics(monkeypatch):
    captured = {}

    class FakeResponses:
        async def create(self, **kwargs):
            captured["responses_kwargs"] = kwargs
            return SimpleNamespace(
                id="resp_123",
                status="completed",
                output=[SimpleNamespace(type="image_generation_call", result="ZmFrZS1pbWFnZQ==")],
                usage=SimpleNamespace(
                    input_tokens=11,
                    output_tokens=22,
                    total_tokens=33,
                    input_tokens_details=SimpleNamespace(cached_tokens=4),
                    output_tokens_details=SimpleNamespace(reasoning_tokens=5),
                ),
            )

    class FakeClient:
        responses = FakeResponses()

    def fake_get_client(api_key):
        captured["api_key"] = api_key
        return FakeClient()

    async def fake_log_manual_analytics(**kwargs):
        captured["analytics"] = kwargs

    monkeypatch.setattr(service_module.openai_client, "get_client", fake_get_client)
    monkeypatch.setattr(service_module.openai_client, "log_manual_analytics", fake_log_manual_analytics)

    config = GenerateAiImageServiceConfig(
        enabled=True,
        bearer_token=None,
        openai_api_key="test-create-offer-key",
        generate_ai_image_model="gpt-5.5",
        timeout=30.0,
        image_size="1024x1280",
        image_quality="high",
    )
    service = GenerateAiImageService(config)

    request = GenerateAiImageRequest(
        system_prompt="System poster rules",
        user_prompt="Create poster",
        language="Macedonian",
        content="Скопско пиво - 120 ден\nРакия - 190 ден\nСалата - 240 ден",
        logo_image_url="https://example.com/logo.png",
        reference_image_url="https://example.com/reference.png",
        reference_image_url_2="https://example.com/reference-2.png",
        city="sofia",
        zavedenia_id=3054,
    )

    result = await service.generate_ai_image(request)

    assert captured["api_key"] == "test-create-offer-key"
    assert captured["responses_kwargs"]["model"] == "gpt-5.5"
    assert captured["responses_kwargs"]["tools"] == [
        {"type": "image_generation", "size": "1024x1280", "quality": "high"}
    ]
    assert "System poster rules" in captured["responses_kwargs"]["input"][0]["content"][0]["text"]
    assert "All visible text in the generated image must be written in Macedonian" in captured["responses_kwargs"]["input"][0]["content"][0]["text"]
    assert "Use natural shadows, realistic reflections, authentic textures, believable depth of field, and cinematic lighting." in captured["responses_kwargs"]["input"][0]["content"][0]["text"]
    assert "Reference images are mandatory visual inputs whenever provided" in captured["responses_kwargs"]["input"][0]["content"][0]["text"]
    assert "Preserve bottle shape, label or etiquette color, packaging color, glass shape, object proportions, and distinctive visual details as faithfully as possible." in captured["responses_kwargs"]["input"][0]["content"][0]["text"]
    assert captured["responses_kwargs"]["input"][1]["content"][0]["type"] == "input_text"
    assert "Create poster" in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "Use every additional attached image as required primary visual guidance" in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "main subject, setting, style" in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "Do not modify the identity of important objects from the reference images." in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "bottle shapes, label or etiquette colors, packaging colors, glassware forms, and distinctive product details unchanged" in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "Keep the final image ultra realistic with believable materials, natural shadows, realistic reflections, premium food styling, and authentic photography depth." in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert "Скопско пиво - 120 ден" in captured["responses_kwargs"]["input"][1]["content"][0]["text"]
    assert captured["responses_kwargs"]["input"][1]["content"][1:] == [
        {"type": "input_text", "text": "Input image 1 is the restaurant logo. Use it as the brand mark."},
        {"type": "input_image", "image_url": "https://example.com/logo.png"},
        {
            "type": "input_text",
            "text": (
                "Input image 2 is a required restaurant reference image. "
                "Use this image visibly as primary guidance for the generated poster's subject, "
                "setting, style, colors, lighting, materials, and composition."
            ),
        },
        {"type": "input_image", "image_url": "https://example.com/reference.png"},
        {
            "type": "input_text",
            "text": (
                "Input image 3 is a required restaurant reference image. "
                "Use this image visibly as primary guidance for the generated poster's subject, "
                "setting, style, colors, lighting, materials, and composition."
            ),
        },
        {"type": "input_image", "image_url": "https://example.com/reference-2.png"},
    ]
    assert result["image_base64"] == "ZmFrZS1pbWFnZQ=="
    assert result["input_tokens"] == 11
    assert result["output_tokens"] == 22
    assert result["total_tokens"] == 33
    assert captured["analytics"]["city"] == "sofia"
    assert captured["analytics"]["zavedenia_id"] == 3054
    assert captured["analytics"]["service"] == "generate_ai_image"
    assert captured["analytics"]["data_input"]["language"] == "Macedonian"
    assert "Скопско пиво" in captured["analytics"]["data_input"]["content"]
    assert captured["analytics"]["tokens_input"]["prompt_tokens"] == 11
    assert captured["analytics"]["tokens_output"]["completion_tokens"] == 22
