"""Tests offline (sin red, sin GPU) de comfyui_build_status_effect_icon_workflow.

Verifican que el dict en API format se construye correctamente: clases presentes,
cableado del Rembg, prompt scaffold de icono de estado, y reflejo de los argumentos
(effect, ui_style, size, transparent, lora). No tocan el servidor ComfyUI.
"""
import os
import sys

import pytest

sys.path.insert(0, os.path.join(os.path.dirname(__file__), ".."))

from ml.comfyui_build_status_effect_icon_workflow import (  # noqa: E402
    comfyui_build_status_effect_icon_workflow,
)


def _classes(wf):
    return {n["class_type"] for n in wf.values()}


def _positive_prompt(wf):
    """Texto positivo: el CLIPTextEncode al que apunta KSampler.positive."""
    ks = next(n for n in wf.values() if n["class_type"] == "KSampler")
    pos_id = ks["inputs"]["positive"][0]
    return wf[pos_id]["inputs"]["text"]


def test_golden_transparent():
    """Caso feliz: icono transparente -> Rembg cableado, prompt de estado, clases base."""
    wf = comfyui_build_status_effect_icon_workflow("poison", transparent=True, seed=42)
    cls = _classes(wf)
    for expected in {
        "CheckpointLoaderSimple",
        "KSampler",
        "VAEDecode",
        "SaveImage",
        "Image Rembg (Remove Background)",
    }:
        assert expected in cls, f"falta clase {expected}"

    prompt = _positive_prompt(wf)
    assert "poison" in prompt
    assert "status effect icon" in prompt
    assert "centered" in prompt
    assert "readable at small size" in prompt

    # SaveImage debe tomar la imagen del Rembg, no del VAEDecode.
    save = next(n for n in wf.values() if n["class_type"] == "SaveImage")
    rembg_id = next(
        nid for nid, n in wf.items() if n["class_type"] == "Image Rembg (Remove Background)"
    )
    assert save["inputs"]["images"][0] == rembg_id
    rembg = wf[rembg_id]
    assert rembg["inputs"]["transparency"] is True


def test_edge_transparent_false_no_rembg():
    """transparent=False -> sin nodo Rembg; SaveImage cuelga del VAEDecode."""
    wf = comfyui_build_status_effect_icon_workflow("shield", transparent=False)
    assert "Image Rembg (Remove Background)" not in _classes(wf)
    save = next(n for n in wf.values() if n["class_type"] == "SaveImage")
    vae_id = next(nid for nid, n in wf.items() if n["class_type"] == "VAEDecode")
    assert save["inputs"]["images"][0] == vae_id


def test_edge_size_reflected_square():
    """size se refleja como width == height (cuadrado). Default 256 (icono compacto)."""
    wf = comfyui_build_status_effect_icon_workflow("frozen", size=128)
    latent = next(n for n in wf.values() if n["class_type"] == "EmptyLatentImage")
    assert latent["inputs"]["width"] == 128
    assert latent["inputs"]["height"] == 128

    wf_default = comfyui_build_status_effect_icon_workflow("frozen")
    latent_d = next(n for n in wf_default.values() if n["class_type"] == "EmptyLatentImage")
    assert latent_d["inputs"]["width"] == 256
    assert latent_d["inputs"]["height"] == 256


def test_edge_ui_style_reflected():
    """ui_style se inserta en el prompt positivo."""
    wf = comfyui_build_status_effect_icon_workflow(
        "burning", ui_style="sci-fi HUD status, neon glow"
    )
    assert "sci-fi HUD status, neon glow" in _positive_prompt(wf)


def test_edge_effect_reflected():
    """effect se inserta literal en el prompt positivo."""
    wf = comfyui_build_status_effect_icon_workflow("regeneration")
    assert "regeneration" in _positive_prompt(wf)


def test_edge_lora_injected():
    """lora -> LoraLoader presente con la fuerza dada."""
    wf = comfyui_build_status_effect_icon_workflow(
        "speed boost", lora="SD15_detail_tweaker.safetensors", lora_strength=0.8
    )
    loras = [n for n in wf.values() if n["class_type"] == "LoraLoader"]
    assert len(loras) == 1
    assert loras[0]["inputs"]["lora_name"] == "SD15_detail_tweaker.safetensors"
    assert loras[0]["inputs"]["strength_model"] == pytest.approx(0.8)


def test_error_empty_effect():
    """effect vacio -> ValueError."""
    with pytest.raises(ValueError):
        comfyui_build_status_effect_icon_workflow("   ")


def test_determinism():
    """Mismos argumentos -> mismo dict (funcion pura)."""
    a = comfyui_build_status_effect_icon_workflow("stun", seed=7)
    b = comfyui_build_status_effect_icon_workflow("stun", seed=7)
    assert a == b
