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

import os
import sys

import pytest

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from ml.comfyui_build_world_map_workflow import (  # noqa: E402
    comfyui_build_world_map_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 _positive(wf, needle):
    return next(
        n
        for n in wf.values()
        if n["class_type"] == "CLIPTextEncode" and needle in n["inputs"]["text"]
    )


def test_golden_plain_recipe():
    wf = comfyui_build_world_map_workflow(
        "a fantasy kingdom with mountains, forests and a coastline",
        map_style="fantasy cartography, aged parchment",
        checkpoint="IMG_dreamshaper_8.safetensors",
        hires=False,
        seed=7,
    )
    cls = _classes(wf)
    # Cadena base txt2img (hires=False por defecto del builder).
    assert "CheckpointLoaderSimple" in cls
    assert "KSampler" in cls
    assert "VAEDecode" in cls
    assert "SaveImage" in cls
    # Sin 2a pasada cuando hires=False.
    assert "UltimateSDUpscale" not in cls
    assert "UpscaleModelLoader" not in cls
    # La region aparece en el prompt positivo con el scaffold de mapa cenital.
    pos = _positive(wf, "a fantasy kingdom with mountains, forests and a coastline")
    assert "fantasy cartography, aged parchment" in pos["inputs"]["text"]
    assert "top-down cartographic view" in pos["inputs"]["text"]
    assert "illustrated game world map" in pos["inputs"]["text"]
    assert "labeled regions" in pos["inputs"]["text"]
    assert "decorative border" in pos["inputs"]["text"]
    # Formato cuadrado por defecto.
    latent = _by_class(wf, "EmptyLatentImage")[0]["inputs"]
    assert latent["width"] == 768
    assert latent["height"] == 768
    # SaveImage toma del VAEDecode directamente (sin hires).
    vd_id = next(nid for nid, n in wf.items() if n["class_type"] == "VAEDecode")
    save = next(n for n in wf.values() if n["class_type"] == "SaveImage")
    assert save["inputs"]["images"] == [vd_id, 0]


def test_edge_hires_chains_upscale():
    wf = comfyui_build_world_map_workflow(
        "a desert continent with an oasis and ruins",
        checkpoint="IMG_dreamshaper_8.safetensors",
        hires=True,
        upscale_by=2.0,
        seed=3,
    )
    cls = _classes(wf)
    assert "UltimateSDUpscale" in cls
    assert "UpscaleModelLoader" in cls
    usd = _by_class(wf, "UltimateSDUpscale")[0]["inputs"]
    assert usd["upscale_by"] == 2.0
    # Regresion: UltimateSDUpscale exige batch_size (input requerido /object_info).
    assert usd["batch_size"] == 1


def test_edge_dims_reflected():
    # Mundo apaisado: banda continental ancha -> width > height.
    wf = comfyui_build_world_map_workflow(
        "a long coastal continent", width=1024, height=576, hires=False
    )
    latent = _by_class(wf, "EmptyLatentImage")[0]["inputs"]
    assert latent["width"] == 1024
    assert latent["height"] == 576


def test_edge_map_style_in_prompt():
    wf = comfyui_build_world_map_workflow(
        "a dark dungeon with branching corridors",
        map_style="hand-drawn ink map",
        hires=False,
    )
    pos = _positive(wf, "a dark dungeon with branching corridors")
    assert "hand-drawn ink map" in pos["inputs"]["text"]


def test_edge_lora_reflected():
    wf = comfyui_build_world_map_workflow(
        "an archipelago of volcanic islands",
        lora="SD15_cartography.safetensors",
        lora_strength=0.9,
        hires=False,
    )
    loras = _by_class(wf, "LoraLoader")
    assert len(loras) == 1
    assert loras[0]["inputs"]["lora_name"] == "SD15_cartography.safetensors"
    assert loras[0]["inputs"]["strength_model"] == 0.9
    # Con lora el KSampler.model ya NO viene del checkpoint directo.
    ksampler = _by_class(wf, "KSampler")[0]
    lora_id = next(nid for nid, n in wf.items() if n["class_type"] == "LoraLoader")
    assert ksampler["inputs"]["model"] == [lora_id, 0]


def test_edge_lora_strength_clamped():
    wf = comfyui_build_world_map_workflow(
        "a frozen tundra region", lora="x.safetensors", lora_strength=5.0, hires=False
    )
    loras = _by_class(wf, "LoraLoader")
    assert loras[0]["inputs"]["strength_model"] == 2.0  # clamp a [0.0, 2.0]


def test_error_empty_region():
    with pytest.raises(ValueError):
        comfyui_build_world_map_workflow("   ", hires=False)


def test_determinism():
    a = comfyui_build_world_map_workflow("a swamp lowland map", hires=False, seed=3)
    b = comfyui_build_world_map_workflow("a swamp lowland map", hires=False, seed=3)
    assert a == b
