import gradio as gr
from random import randint

import torch
import os

os.environ["CUDA_VISIBLE_DEVICES"] = ""  # Отключаем CUDA


device = "cpu"  # Используем CPU
model_repo_id = "stabilityai/sdxl-turbo"

torch_dtype = torch.float32  # Тип данных для CPU

models = [
    'stabilityai/stable-diffusion-3.5-large-turbo',
    'black-forest-labs/FLUX.1-dev',
    'strangerzonehf/Flux-Isometric-3D-LoRA',
    'ckpt/kivotos-xl-2.0',
    'stabilityai/stable-diffusion-3.5-large',
    'yodayo-ai/clandestine-xl-1.0',
    'yodayo-ai/kivotos-xl-2.0',
    'yodayo-ai/holodayo-xl-2.1',
    'prithivMLmods/SD3.5-Large-Anime-LoRA',
    'FluffyKaeloky/Midnight-Miqu-103B-v1.5',
    'cagliostrolab/animagine-xl-3.1',
    'votepurchase/ponyDiffusionV6XL',
    'eienmojiki/Anything-XL',
    'eienmojiki/Starry-XL-v5.2',
    "digiplay/MilkyWonderland_v1",
    'Sombressoul/Yi-34B-200K-AWQ',
    'digiplay/majicMIX_realistic_v7',
    'votepurchase/counterfeitV30_v30',
    'Linaqruf/animagine-xl-2.0',
    'KBlueLeaf/Kohaku-XL-Epsilon-rev3',
    'KBlueLeaf/Kohaku-XL-Zeta',
    'kayfahaarukku/UrangDiffusion-1.4',
    'Eugeoter/artiwaifu-diffusion-2.0',
    'Raelina/Rae-Diffusion-XL-V2',
    'Raelina/Raemu-XL-V4',
    'Jonjew/NSFWMaster',
]

def load_fn(models):
    global models_load
    models_load = {}
    for model in models:
        if model not in models_load.keys():
            try:
                m = gr.load(f'models/{model}')
            except Exception as error:
                m = gr.Interface(lambda txt: None, ['text'], ['image'])
            models_load.update({model: m})

load_fn(models)

num_models = len(models)
default_models = models[:num_models]

def extend_choices(choices):
    return choices + (num_models - len(choices)) * ['NA']

def update_imgbox(choices):
    choices_plus = extend_choices(choices)
    return [gr.Image(None, label=m, visible=(m != 'NA'), elem_id="custom_image") for m in choices_plus]

def gen_fn(model_str, prompt):
    if model_str == 'NA':
        return None
    noise = str(randint(0, 9999999))
    return models_load[model_str](f'{prompt} {noise}')

def make_me():
    with gr.Row():
        with gr.Column(scale=1):
            txt_input = gr.Textbox(
                label='Your prompt:',
                lines=3,
                container=False,
                elem_id="custom_textbox",
                placeholder="Prompt"
            )
            with gr.Row(): 
                gen_button = gr.Button('Generate images', elem_id="custom_gen_button")
                stop_button = gr.Button('Stop', variant='secondary', interactive=False, elem_id="custom_stop_button")
                
                def on_generate_click():
                    return gr.Button('Generate images', elem_id="custom_gen_button"), gr.Button('Stop', variant='secondary', interactive=True, elem_id="custom_stop_button")
                
                def on_stop_click():
                    return gr.Button('Generate images', elem_id="custom_gen_button"), gr.Button('Stop', variant='secondary', interactive=False, elem_id="custom_stop_button")
                
                gen_button.click(on_generate_click, inputs=None, outputs=[gen_button, stop_button])
                stop_button.click(on_stop_click, inputs=None, outputs=[gen_button, stop_button])
    
    # Делим вывод изображений на два ряда
    with gr.Row():
        half = len(default_models) // 2
        output_row1 = [gr.Image(label=m, min_width=250, height=250, elem_id="custom_image") for m in default_models[:half]]
        output_row2 = [gr.Image(label=m, min_width=250, height=250, elem_id="custom_image") for m in default_models[half:]]
        current_models_row1 = [gr.Textbox(m, visible=False) for m in default_models[:half]]
        current_models_row2 = [gr.Textbox(m, visible=False) for m in default_models[half:]]
        
        # Первый ряд изображений
        for m, o in zip(current_models_row1, output_row1):
            gen_event = gen_button.click(gen_fn, [m, txt_input], o)
            stop_button.click(on_stop_click, inputs=None, outputs=[gen_button, stop_button], cancels=[gen_event])
        
        # Второй ряд изображений
        for m, o in zip(current_models_row2, output_row2):
            gen_event = gen_button.click(gen_fn, [m, txt_input], o)
            stop_button.click(on_stop_click, inputs=None, outputs=[gen_button, stop_button], cancels=[gen_event])
    
    # Разделяем чекбоксы на два ряда
    with gr.Accordion('Model selection', elem_id="custom_accordion"):
        half = len(models) // 2
        model_choice_row1 = models[:half]
        model_choice_row2 = models[half:]
        
        model_choice1 = gr.CheckboxGroup(
            model_choice_row1,
            label=f'{len(model_choice_row1)} models selected',
            value=default_models[:half],
            interactive=True,
            elem_id="custom_checkbox_group"
        )
        model_choice2 = gr.CheckboxGroup(
            model_choice_row2,
            label=f'{len(model_choice_row2)} models selected',
            value=default_models[half:],
            interactive=True,
            elem_id="custom_checkbox_group"
        )
        
        # Обновляем первый ряд
        model_choice1.change(update_imgbox, model_choice1, output_row1)
        model_choice1.change(extend_choices, model_choice1, current_models_row1)
        
        # Обновляем второй ряд
        model_choice2.change(update_imgbox, model_choice2, output_row2)
        model_choice2.change(extend_choices, model_choice2, current_models_row2)

    with gr.Row():
        gr.HTML("")

custom_css = """
:root {
    --body-background-fill: #2d3d4f;
}

body {
    background-color: var(--body-background-fill) !important;
    color: #2d3d4f;
    margin: 0;
    padding: 0;
    font-family: Arial, sans-serif;
    height: 100vh;
    overflow-y: auto;
}

.gradio-container {
    background-color: #2d3d4f;
    color: #c5c6c7;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    width: 100%;
    max-width: 1200px;
    margin: 20px auto;
    display: block;
    min-height: 100vh;
}

.app_title {
    background-color: #2d3d4f;
    color: #c5c6c7;
    padding: 10px 20px;
    border-bottom: 1px solid #3b4252;
    text-align: center;
    font-size: 24px;
    font-weight: bold;
    width: 100%;
    box-sizing: border-box;
    margin-bottom: 20px;
}

.custom_textbox {
    background-color: #2d343f;
    border: 1px solid #3b4252;
    color: #7f8184;
    padding: 10px;
    border-radius: 4px;
    margin-bottom: 10px;
    width: 100%;
    box-sizing: border-box;
}

.custom_gen_button {
    background-color: #8b38ff;
    border: 1px solid #ffffff;
    color: blue;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    transition: transform 0.2s, box-shadow 0.2s;
    border-radius: 4px;
}
.custom_gen_button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 10px rgba(0, 0, 0, 0.3);
}
.custom_stop_button {
    background-color: #6200ea;
    border: 1px solid #ffffff;
    color: blue;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 16px;
    margin: 4px 2px;
    cursor: pointer;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
    transition: transform 0.2s, box-shadow 0.2s;
    border-radius: 4px;
}
.custom_stop_button:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 10px rgba(0, 0, 0, 0.3);
}

.custom_image {
    border: 1px solid #3b4252;
    background-color: #2d343f;
    border-radius: 4px;
    margin: 10px;
    max-width: 100%;
    box-sizing: border-box;
}

.custom_accordion {
    background-color: #2d3d4f;
    color: #7f8184;
    border: 1px solid #3b4252;
    border-radius: 4px;
    margin-top: 20px;
    width: 100%;
    box-sizing: border-box;
    transition: margin 0.2s ease;
}

.custom_accordion .gr-accordion-header {
    background-color: #2d3d4f;
    color: #7f8184;
    padding: 10px 20px;
    border-bottom: 1px solid #5b6270;
    cursor: pointer;
    font-size: 18px;
    font-weight: bold;
    height: 40px;
    display: flex;
    align-items: center;
}

.custom_accordion .gr-accordion-header:hover {
    background-color: #2d3d4f;
}

.custom_accordion .gr-accordion-content {
    padding: 10px 20px;
    background-color: #2d3d4f;
    border-top: 1px solid #5b6270;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease;
}

.custom_accordion .gr-accordion-content.open {
    max-height: 500px;
}

.custom_checkbox_group {
    background-color: #2d343f;
    border: 1px solid #3b4252;
    color: #7f8184;
    border-radius: 4px;
    padding: 10px;
    width: 100%;
    box-sizing: border-box;
}

@media (max-width: 768px) {
   .gradio-container {
        width: 100%;
        margin: 0;
        padding: 10px;
    }
   .custom_textbox,.custom_image,.custom_checkbox_group {
        width: 100%;
        box-sizing: border-box;
    }
}
"""

with gr.Blocks(css=custom_css) as demo: 
    make_me()
# Очередь и запуск интерфейса с параметрами
demo.queue(default_concurrency_limit=340, max_size=400)
demo.launch(max_threads=400, ssr_mode=False)


demo.queue(concurrency_count=50)
demo.launch()