"""Tests offline de comfyui_build_sprite_sheet_workflow (estructura del dict, sin GPU)."""

import os
import sys

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from ml.comfyui_build_sprite_sheet_workflow import (  # noqa: E402
    comfyui_build_sprite_sheet_workflow,
)


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


def _by_class(wf, cls):
    return [n for n in wf.values() if n["class_type"] == cls]


def _id_of(wf, cls):
    return next(nid for nid, n in wf.items() if n["class_type"] == cls)


def test_golden_full_recipe():
    wf = comfyui_build_sprite_sheet_workflow(
        "a knight in silver armor",
        ref_image="faceref.png",
        pose_skeleton="pose_front.png",
        transparent=True,
    )
    cls = _classes(wf)
    assert "IPAdapterUnifiedLoaderFaceID" in cls
    assert "IPAdapterFaceID" in cls
    assert "ControlNetApplyAdvanced" in cls
    assert "Image Rembg (Remove Background)" in cls
    # KSampler.positive/negative vienen del ControlNetApplyAdvanced.
    cna_id = _id_of(wf, "ControlNetApplyAdvanced")
    ks = next(n for n in wf.values() if n["class_type"] == "KSampler")
    assert ks["inputs"]["positive"] == [cna_id, 0]
    assert ks["inputs"]["negative"] == [cna_id, 1]
    # SaveImage toma la imagen del Rembg.
    rembg_id = _id_of(wf, "Image Rembg (Remove Background)")
    save = next(n for n in wf.values() if n["class_type"] == "SaveImage")
    assert save["inputs"]["images"] == [rembg_id, 0]
    # ControlNetApplyAdvanced con end_percent<1.0.
    cna = _by_class(wf, "ControlNetApplyAdvanced")[0]
    assert cna["inputs"]["end_percent"] == 0.8


def test_edge_no_ref_image():
    wf = comfyui_build_sprite_sheet_workflow("a goblin", pose_skeleton="pose.png")
    cls = _classes(wf)
    assert "IPAdapterFaceID" not in cls
    assert "CheckpointLoaderSimple" in cls
    assert "ControlNetApplyAdvanced" in cls


def test_edge_opaque_no_rembg():
    wf = comfyui_build_sprite_sheet_workflow("a mage", transparent=False)
    assert "Image Rembg (Remove Background)" not in _classes(wf)
    # SaveImage toma del VAEDecode directamente.
    vd_id = _id_of(wf, "VAEDecode")
    save = next(n for n in wf.values() if n["class_type"] == "SaveImage")
    assert save["inputs"]["images"] == [vd_id, 0]


def test_edge_char_lora():
    wf = comfyui_build_sprite_sheet_workflow(
        "a hero", char_lora="SD15_anime_style_box.safetensors", lora_strength=0.8
    )
    loras = _by_class(wf, "LoraLoader")
    assert len(loras) == 1
    assert loras[0]["inputs"]["lora_name"] == "SD15_anime_style_box.safetensors"


def test_error_empty_subject():
    try:
        comfyui_build_sprite_sheet_workflow("  ")
        assert False
    except ValueError as e:
        assert "subject" in str(e)


def test_determinism():
    a = comfyui_build_sprite_sheet_workflow("a knight", pose_skeleton="p.png", seed=4)
    b = comfyui_build_sprite_sheet_workflow("a knight", pose_skeleton="p.png", seed=4)
    assert a == b
