"""
El prompt que la pantalla muestra es, byte a byte, el que el servidor manda.

La pantalla arma el prompt con la receta y el catálogo que le manda el
servidor; el servidor lo arma con `build_prompt`. Son dos implementaciones de
la misma regla, en dos lenguajes, y lo único que las mantiene iguales es esta
comparación: cada juego de respuestas se arma de los dos lados y tiene que dar
exactamente lo mismo, con y sin foto, para los dos tipos.
"""

import pytest

from apps.ai import catalog, prompt
from apps.ai.models import GenerationKind
from tests.frontend.harness import call, needs_frontend, resolve

PROMPT = '@/pages/Ai/ImageGenerator/prompt'

pytestmark = needs_frontend

CASES = {
    'pool_with_spa': (
        GenerationKind.POOL,
        {
            'pool_shape': 'rectangular',
            'want_spa': 'yes',
            'spa_shape': 'square',
            'integrated_spa': 'yes',
            'pool_finish': 'pebble',
            'pool_water_color': 'aqua',
            'pool_deck_material': 'travertine',
            'pool_deck_color_family': 'tan_beige_sand',
        },
    ),
    'pool_without_spa': (
        GenerationKind.POOL,
        {
            'pool_shape': 'kidney',
            'want_spa': 'no',
            # Restos de una rama abandonada: los dos lados los ignoran.
            'spa_shape': 'square',
            'pool_finish': 'tile',
            'pool_water_color': 'dark_blue',
            'pool_deck_material': 'pavers',
            'pool_deck_color_family': 'grey_charcoal',
        },
    ),
    'paver_porcelain': (
        GenerationKind.PAVER,
        {
            'paver_material': 'porcelain',
            'color_family': 'cool_tones',
            'border_accent': 'yes',
            'grass_joint': 'no',
            'driveway_style': 'modern',
        },
    ),
}


def requests() -> dict[str, dict]:
    pending = {}
    for name, (kind, answers) in CASES.items():
        questions = catalog.questions_props(kind, '/static/')
        recipe = prompt.recipe(kind)
        for has_photo in (False, True):
            pending[f'{name}:{has_photo}'] = call(
                PROMPT, 'composePrompt', recipe, questions, answers, has_photo
            )
    return pending


@pytest.fixture(scope='module')
def results():
    return resolve(requests())


@pytest.mark.parametrize('name', list(CASES))
@pytest.mark.parametrize('has_photo', [False, True])
def test_the_screen_composes_exactly_what_the_server_sends(results, name, has_photo):
    kind, answers = CASES[name]
    expected = prompt.build_prompt(kind, prompt.clean_answers(kind, answers), has_photo=has_photo)

    assert results[f'{name}:{has_photo}'] == expected
