import sys, random, re
sys.stdout.reconfigure(encoding='utf-8')
from pathlib import Path

ROOT_DIR = Path(__file__).resolve().parent.parent
sys.path.append(str(ROOT_DIR))

from Engine.prompt_builder import PromptBuilder
from Engine.api_client import ForgeClient

pbuilder = PromptBuilder(ROOT_DIR)
forge = ForgeClient()

# Lista de 20 candidatos curados y seleccionados con rigor (enfocados en 1girl, solo o parejas limpias, con entornos coherentes)
candidates = [
    {
        'id': 'cand_01',
        'char_name': 'Columbina',
        'char_line': '<lora:columbina_gnsn:0.8> columbina, genshin impact, blue eyes, pink hair, two-tone hair, long hair, halo, wings',
        'level': 'explicito',
        'pose_tags': 'indoors, luxurious bedroom, dark velvet bed, on_bed, on_stomach, ass_up, blindfold, feet_up, looking_at_viewer, erect_nipples, seductive, from side'
    },
    {
        'id': 'cand_02',
        'char_name': 'Nicole_Demara',
        'char_line': '<lora:Hoseki_ZenlessZoneZero_NicoleDemara_IllustriousXL_v1:0.8> n1c0le, large breasts, green eyes, pink hair, long hair, two side up',
        'level': 'spicy',
        'pose_tags': 'outdoors, urban alleyway, neon lights, brick wall, leotard, fishnet_pantyhose, spread_legs, three_quarter_view, solo'
    },
    {
        'id': 'cand_03',
        'char_name': 'Shouko_Komi',
        'char_line': '<lora:Shouko_Komi_Komi_Cant_Communicate_-_Illustrious_V2:0.8> sh0uk0, 1girl, solo, dark purple hair, long hair, purple eyes, medium breasts',
        'level': 'spicy',
        'pose_tags': 'indoors, quiet library, reading desk, leaning_forward, sideboob, open_mouth, blush, from_behind, solo'
    },
    {
        'id': 'cand_04',
        'char_name': 'Rias_Gremory',
        'char_line': 'rias gremory, high school dxd, 1girl, solo, blue eyes, red hair, very long hair, ahoge, huge ahoge, large breasts',
        'level': 'sugerente',
        'pose_tags': 'indoors, private office, wooden desk, sitting, leg_lift, smiling, looking_at_viewer, solo'
    },
    {
        'id': 'cand_05',
        'char_name': 'Tatsumaki',
        'char_line': '<lora:Tatsumaki_OnePunchMan_Ilxl_V1:0.8> ttsumk, green hair, short hair, curl, green eyes, young adult, 1girl, solo',
        'level': 'sugerente',
        'pose_tags': 'outdoors, city rooftop, skyline, wind, floating, arms_crossed, serious expression, solo'
    },
    {
        'id': 'cand_06',
        'char_name': 'Aqua',
        'char_line': '<lora:Aqua_KonoSuba_Ilxl_V1:0.8> aquaknsb, 1girl, solo, blue hair, long hair, blue eyes, water halo, ribbon',
        'level': 'spicy',
        'pose_tags': 'indoors, celestial shrine, marble floor, kneeling, wet clothes, crying, crying expression, solo'
    },
    {
        'id': 'cand_07',
        'char_name': 'Furina',
        'char_line': '<lora:Furina_GenshinImpact_IL_v2:0.8> furina, 1girl, solo, blue eyes, white hair, short hair, asymmetric bangs',
        'level': 'spicy',
        'pose_tags': 'indoors, opera stage, spotlight, dramatic lighting, bow, theatrical pose, looking_at_viewer, solo'
    },
    {
        'id': 'cand_08',
        'char_name': 'Yelan',
        'char_line': '<lora:Yelan_Genshin_Impact_ILL_v1:0.8> yelan, 1girl, solo, blue hair, short hair, purple eyes, coat',
        'level': 'spicy',
        'pose_tags': 'indoors, casino lounge, poker table, sitting, legs crossed, holding dice, confident smile, solo'
    },
    {
        'id': 'cand_09',
        'char_name': 'Makima',
        'char_line': '<lora:Makima_ChainsawMan_ILXL_v2:0.8> makima, 1girl, solo, red hair, long hair, yellow eyes, ringed eyes',
        'level': 'sugerente',
        'pose_tags': 'indoors, public safety office, window light, coat, shirt and tie, sitting, staring intently, solo'
    },
    {
        'id': 'cand_10',
        'char_name': 'Raiden_Shogun',
        'char_line': '<lora:RaidenShogun_GenshinImpact_IL_v1:0.8> raiden shogun, 1girl, solo, purple hair, long hair, braided hair, purple eyes',
        'level': 'spicy',
        'pose_tags': 'indoors, plane of euthymia, purple mist, sitting on floor, sword in lap, solemn expression, solo'
    },
    {
        'id': 'cand_11',
        'char_name': 'Hu_Tao',
        'char_line': '<lora:HuTao_GenshinImpact_IL_v1:0.8> hu tao, 1girl, solo, brown hair, long hair, twin tails, red eyes, plum blossom hat',
        'level': 'sugerente',
        'pose_tags': 'outdoors, wangsheng funeral parlor, night, lantern light, smiling, waving hand, solo'
    },
    {
        'id': 'cand_12',
        'char_name': 'Ganyu',
        'char_line': '<lora:Ganyu_GenshinImpact_IL_v1:0.8> ganyu, 1girl, solo, blue hair, long hair, blue eyes, horns',
        'level': 'sugerente',
        'pose_tags': 'outdoors, mount aocang, snowy mountain, moonlight, standing, looking back, gentle smile, solo'
    },
    {
        'id': 'cand_13',
        'char_name': 'Nilou',
        'char_line': '<lora:Nilou_Genshin_Impact_ILL_v1:0.8> nilou, 1girl, solo, red hair, long hair, blue eyes, horns',
        'level': 'spicy',
        'pose_tags': 'indoors, zubayr theater, stage lights, dancing pose, arms raised, smiling, solo'
    },
    {
        'id': 'cand_14',
        'char_name': 'Clorinde',
        'char_line': '<lora:Clorinde_Genshin_Impact_ILL_v1:0.8> clorinde, 1girl, solo, purple hair, long hair, blue eyes, tricorne hat',
        'level': 'spicy',
        'pose_tags': 'outdoors, court of fonteine, night street, holding pistol, aiming, focused expression, solo'
    },
    {
        'id': 'cand_15',
        'char_name': 'Arlecchino',
        'char_line': '<lora:Arlecchino_Genshin_Impact_ILL_v1:0.8> arlecchino, 1girl, solo, white hair, long hair, black streaks, multicolored eyes',
        'level': 'spicy',
        'pose_tags': 'indoors, fatui headquarters, dark throne room, sitting, crossing legs, intimidating aura, solo'
    },
    {
        'id': 'cand_16',
        'char_name': 'Navia',
        'char_line': '<lora:Navia_Genshin_Impact_ILL_v1:0.8> navia, 1girl, solo, blonde hair, long hair, blue eyes, parasol',
        'level': 'sugerente',
        'outdoors': 'outdoors, fountain plaza, sunny day, holding parasol over shoulder, cheerful smile, solo'
    },
    {
        'id': 'cand_17',
        'char_name': 'Shenhe',
        'char_line': '<lora:Shenhe_GenshinImpact_IL_v1:0.8> shenhe, 1girl, solo, white hair, long hair, blue eyes, red ropes',
        'level': 'sugerente',
        'pose_tags': 'outdoors, mount hulao, mist, standing on rock, holding talismans, calm expression, solo'
    },
    {
        'id': 'cand_18',
        'char_name': 'Eula',
        'char_line': '<lora:Eula_GenshinImpact_IL_v1:0.8> eula, 1girl, solo, blue hair, short hair, blue eyes, headband',
        'level': 'spicy',
        'pose_tags': 'outdoors, dragonspine, snowstorm, holding claymore, dynamic stance, fierce look, solo'
    },
    {
        'id': 'cand_19',
        'char_name': 'Jean',
        'char_line': '<lora:Jean_GenshinImpact_IL_v1:0.8> jean gunnhildr, 1girl, solo, blonde hair, long hair, ponytail, blue eyes',
        'level': 'sugerente',
        'pose_tags': 'indoors, favonius headquarters, office desk, paperwork, reading documents, focused, solo'
    },
    {
        'id': 'cand_20',
        'char_name': 'Lisa',
        'char_line': '<lora:Lisa_GenshinImpact_IL_v1:0.8> lisa minci, 1girl, solo, brown hair, long hair, green eyes, witch hat',
        'level': 'spicy',
        'pose_tags': 'indoors, library archive, bookshelf, leaning against shelf, holding book, teasing smile, solo'
    }
]

# Ajuste menor por si el campo de navia se llamaba 'outdoors' en vez de 'pose_tags'
for c in candidates:
    if 'outdoors' in c and 'pose_tags' not in c:
        c['pose_tags'] = c.pop('outdoors')

out_root = ROOT_DIR / 'Output' / 'grand_candidate_batch'
out_root.mkdir(parents=True, exist_ok=True)

print(f"=== INICIANDO LOTE GRANDE DE {len(candidates)} CANDIDATAS CURADAS ===")

manifest = []
for t in candidates:
    print(f"\n[Candidata {t['id']}] -> {t['char_name']} ({t['level'].upper()})")
    master_part = pbuilder.master_prompt
    
    # Aseguramos estricto 1girl, solo y limpieza de cualquier elemento extraño
    char_tramo = f"1girl, solo, {t['char_line']}"
    
    tramos = [master_part, char_tramo, t['pose_tags']]
    full_prompt = "\nBREAK\n".join(tramos)
    neg_prompt = pbuilder.negative_prompt
    
    try:
        images, info = forge.txt2img(
            prompt=full_prompt,
            negative_prompt=neg_prompt,
            width=832,
            height=1216,
            steps=28,
            cfg_scale=6.0,
            sampler_name="DPM++ 2M Karras",
            seed=2026,
            clip_skip=2
        )
        if images:
            file_name = f"{t['id']}_{t['char_name']}.png"
            file_path = out_root / file_name
            file_path.write_bytes(images[0])
            print(f"✓ Guardado en: {file_path}")
            manifest.append({
                "id": t['id'],
                "char": t['char_name'],
                "level": t['level'],
                "file": file_name,
                "prompt": full_prompt
            })
    except Exception as e:
        print(f"❌ Error en candidata {t['id']}: {e}")

if manifest:
    import json
    manifest_path = out_root / "manifest.json"
    manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False), encoding='utf-8')
    print(f"\n✨ Lote grande completado. Manifiesto guardado en {manifest_path}")
