"""
La marca de agua que se quema en cada resultado: el logo de la compañía en un
badge redondo de vidrio, en la esquina inferior derecha.

Hay tres badges, que comparten forma y aire y sólo cambian de color. Cuál se
quema lo decide la configuración: uno fijo, o **rotar** entre los tres. La
rotación no es al azar sino por pedido: sale del id, así que el mismo pedido
ejecutado dos veces lleva el mismo badge.

Los badges son PNG versionados en `static/`, como las muestras del catálogo: se
preparan una vez y de ahí en adelante sólo se leen. El PNG trae el tinte, el
brillo, el borde y el logo; el desenfoque del vidrio no puede venir en el
archivo, porque depende de lo que haya debajo, y lo agrega
`images.burn_badge` al quemarlo.

Se lee al ejecutar, como el modelo y la calidad: el badge no cambia el prompt,
así que no hay nada que congelar al pedir.
"""

import uuid
from pathlib import Path

from django.contrib.staticfiles import finders
from django.db import models


class Watermark(models.TextChoices):
    """Qué badge se quema en el resultado."""

    BLUE = 'blue', 'Blue'
    CREAM = 'cream', 'Cream'
    CLAY = 'clay', 'Clay'
    ROTATE = 'rotate', 'Rotate'


#: El badge con que arranca la configuración: el logo con sus colores, que es
#: el que mejor se reconoce sobre el tono tierra.
DEFAULT_WATERMARK = Watermark.BLUE

#: Los badges que existen como archivo, en el orden en que rota la rotación.
BADGES: tuple[str, ...] = (Watermark.BLUE, Watermark.CREAM, Watermark.CLAY)


class BadgeMissing(Exception):
    """El archivo del badge no está entre los estáticos."""


def badge_for(choice: str, generation_id: uuid.UUID) -> str:
    """
    El badge que lleva un pedido según la configuración.

    Un valor que no es un badge ni la rotación cae en el de arranque: la
    configuración sólo guarda valores de la lista, y si algún día se saca uno,
    un resultado sin marca sería peor que uno con la marca de siempre.
    """
    if choice == Watermark.ROTATE:
        return BADGES[generation_id.int % len(BADGES)]
    return choice if choice in BADGES else DEFAULT_WATERMARK


def badge_static(badge: str) -> str:
    """La ruta del badge bajo `STATIC_URL`."""
    return f'ai/watermark/{badge}.png'


def badge_path(badge: str) -> Path:
    """
    El archivo del badge, en disco.

    Pasa por el buscador de estáticos por lo mismo que las muestras: en
    desarrollo vive en `static/` y en el servidor en `STATIC_ROOT`.
    """
    found = finders.find(badge_static(badge))
    if found is None:
        raise BadgeMissing(badge)
    return Path(found)


def option_props(static_url: str) -> list[dict]:
    """
    Las opciones para la pantalla «Config», como códigos y con la imagen de cada
    badge; los rótulos los pone el catálogo. La rotación no tiene imagen propia.
    """
    return [
        {
            'value': choice,
            'image': f'{static_url}{badge_static(choice)}' if choice in BADGES else None,
        }
        for choice in Watermark.values
    ]
