import streamlit as st
import os
import json
import uuid
import re
import subprocess
from io import BytesIO
from streamlit_quill import st_quill
from streamlit_paste_button import paste_image_button

# Вспомогательная функция для чистой инициализации шага
def get_empty_step():
    return {
        "heading": "",
        "text": "",
        "layout": "Без картинок",
        "existing_images": [],
        "existing_video": None,
        "existing_subtitles": None,  # <-- ДОБАВЛЕНО
        "memory_images": [],
        "uploader_key": 0
    }

def transliterate(text):
    dic = {
        'а':'a', 'б':'b', 'в':'v', 'г':'g', 'д':'d', 'е':'e', 'ё':'e',
        'ж':'zh', 'з':'z', 'и':'i', 'й':'y', 'к':'k', 'л':'l', 'м':'m',
        'н':'n', 'о':'o', 'п':'p', 'р':'r', 'с':'s', 'т':'t', 'у':'u',
        'ф':'f', 'х':'h', 'ц':'ts', 'ч':'ch', 'ш':'sh', 'щ':'sch',
        'ъ':'', 'ы':'y', 'ь':'', 'э':'e', 'ю':'yu', 'я':'ya'
    }
    res = []
    for c in text.lower():
        if c in dic: res.append(dic[c])
        elif c.isalnum(): res.append(c)
        elif c == ' ': res.append('_')
    clean_text = re.sub(r'_+', '_', "".join(res)).strip('_')
    return clean_text or "instruction"

def run(plugin_info):
    col_title, col_theme = st.columns([7, 3])
    with col_title:
        st.markdown("### 🛠 Конструктор инструкций")
    with col_theme:
        dark_editor = st.toggle("🌙 Тёмный редактор", value=True)

    if dark_editor:
        st.markdown("<style>iframe[title*='quill'] {filter: invert(0.9) hue-rotate(180deg); border-radius: 6px;}</style>", unsafe_allow_html=True)

    # ==================================================
    # ИНИЦИАЛИЗАЦИЯ ПАМЯТИ
    # ==================================================
    if "editor_mode" not in st.session_state:
        st.session_state.editor_mode = "create"
        st.session_state.loaded_data = None
        
        first_uid = str(uuid.uuid4())
        st.session_state.step_uids = [first_uid]
        st.session_state.step_data_store = {first_uid: get_empty_step()}

    colA, colB = st.columns(2)
    with colA:
        if st.button("📝 Создать новую", use_container_width=True, type="primary" if st.session_state.editor_mode == "create" else "secondary"):
            st.session_state.editor_mode = "create"
            st.session_state.loaded_data = None
            new_uid = str(uuid.uuid4())
            st.session_state.step_uids = [new_uid]
            st.session_state.step_data_store = {new_uid: get_empty_step()}
            st.rerun()
    with colB:
        if st.button("✏️ Редактировать", use_container_width=True, type="primary" if st.session_state.editor_mode == "edit" else "secondary"):
            st.session_state.editor_mode = "edit"
            st.session_state.loaded_data = None
            st.rerun()

    st.write("---")

    # ==================================================
    # РЕЖИМ РЕДАКТИРОВАНИЯ
    # ==================================================
    if st.session_state.editor_mode == "edit" and not st.session_state.loaded_data:
        target_dir = os.path.join("CorpHub", "instructions")
        if not os.path.exists(target_dir):
            st.warning("Папка instructions не найдена.")
            return
            
        instructions = []
        for d in os.listdir(target_dir):
            p = os.path.join(target_dir, d)
            if os.path.isdir(p) and os.path.exists(os.path.join(p, "info.json")):
                with open(os.path.join(p, "info.json"), "r", encoding="utf-8") as f:
                    data = json.load(f)
                if data.get("category") == "instruction" or "block_1" in data:
                    instructions.append({"id": d, "data": data})
                    
        if not instructions:
            st.info("Нет инструкций.")
            return

        options = {f"{x['data'].get('title', x['id'])}": x for x in instructions}
        selected_key = st.selectbox("Выберите инструкцию:", list(options.keys()))

        if st.button("⬇️ Загрузить", type="primary"):
            sel = options[selected_key]
            loaded = {
                "inst_id": sel["id"], 
                "title": sel["data"].get("title", ""),
                "desc": sel["data"].get("description", ""),
                "icon": sel["data"].get("icon", "📖"),
                "order": sel["data"].get("order", 999),
            }

            blocks = []
            for k, v in sel["data"].items():
                if k.startswith("block_"):
                    try: blocks.append((int(k.split("_")[1]), v))
                    except: pass
            blocks.sort(key=lambda x: x[0])

            st.session_state.step_uids = []
            st.session_state.step_data_store = {}
            
            for _, b in blocks:
                uid = str(uuid.uuid4())
                st.session_state.step_uids.append(uid)
                
                step_data = get_empty_step()
                if isinstance(b, str):
                    step_data["text"] = b
                elif isinstance(b, dict):
                    step_data["heading"] = b.get("heading", "")
                    step_data["text"] = b.get("text", "")
                    step_data["existing_video"] = b.get("video")
                    
                    if "image" in b:
                        step_data["layout"] = "Маленькая сбоку (image)"
                        step_data["existing_images"] = [b["image"]]
                    elif "big_image" in b:
                        step_data["layout"] = "Широкая снизу (big_image)"
                        step_data["existing_images"] = [b["big_image"]]
                    elif "images" in b:
                        step_data["layout"] = "Галерея в ряд (images)"
                        step_data["existing_images"] = b["images"]
                    elif "video" in b:
                        step_data["layout"] = "🎥 Видео (снизу)"
                        
                st.session_state.step_data_store[uid] = step_data

            if not st.session_state.step_uids:
                new_uid = str(uuid.uuid4())
                st.session_state.step_uids = [new_uid]
                st.session_state.step_data_store = {new_uid: get_empty_step()}

            st.session_state.loaded_data = loaded
            st.rerun()
        return

    # ==================================================
    # ОБЩИЙ ИНТЕРФЕЙС
    # ==================================================
    ld = st.session_state.loaded_data or {}
    is_edit = (st.session_state.editor_mode == "edit")

    with st.container(border=True):
        col1, col2 = st.columns(2)
        with col1:
            title = st.text_input("Заголовок карточки", value=ld.get("title", ""))
            desc = st.text_input("Краткое описание", value=ld.get("desc", ""))
        with col2:
            order = st.number_input("Приоритет", value=ld.get("order", 999), step=1)
            icon = st.text_input("Эмодзи", value=ld.get("icon", "📖"))

    inst_id = ld.get("inst_id") if is_edit else transliterate(title)
            
    st.write("---")
    steps_data_for_save = []

    # ==================================================
    # РЕНДЕР ШАГОВ
    # ==================================================
    for i, uid in enumerate(st.session_state.step_uids):
        step_idx = i + 1
        
        c_title, c_ins, c_del = st.columns([6, 2, 2])
        with c_title: st.markdown(f"#### Шаг {step_idx}")
        with c_ins:
            if st.button("⬆️ Вставить перед", key=f"ins_{uid}", use_container_width=True):
                new_uid = str(uuid.uuid4())
                st.session_state.step_uids.insert(i, new_uid)
                st.session_state.step_data_store[new_uid] = get_empty_step()
                st.rerun()
        with c_del:
            if st.button("🗑️ Удалить шаг", key=f"del_{uid}", use_container_width=True, disabled=(len(st.session_state.step_uids) <= 1)):
                st.session_state.step_uids.pop(i)
                st.rerun()

        with st.container(border=True):
            step_initial = st.session_state.step_data_store[uid]
            
            step_heading = st.text_input("Опциональный заголовок", value=step_initial["heading"], key=f"head_{uid}")
            text_content = st_quill(value=step_initial["text"], html=True, placeholder=f"Текст для шага {step_idx}...", key=f"quill_{uid}")
            
            layout_opts = ["Без картинок", "Маленькая сбоку (image)", "Широкая снизу (big_image)", "Галерея в ряд (images)", "🎥 Видео (снизу)"]
            try: layout_idx = layout_opts.index(step_initial["layout"])
            except: layout_idx = 0
            
            layout = st.radio("Формат медиа:", layout_opts, horizontal=True, index=layout_idx, key=f"layout_{uid}")
            
            uploaded_video = None
            
            # --- ЛОГИКА ДЛЯ ВИДЕО И СУБТИТРОВ ---
            if layout == "🎥 Видео (снизу)":
                if is_edit and step_initial.get("existing_video"):
                    st.info(f"💾 Текущее видео: **{step_initial['existing_video']}**")
                    if st.button("🗑️ Удалить видео", key=f"del_vid_{uid}"):
                        step_initial["existing_video"] = None
                        st.rerun()
                        
                vid_file = st.file_uploader("📹 Загрузите видео (MP4, AVI, MOV, MKV)", type=["mp4", "avi", "mov", "mkv"], key=f"file_{uid}")
                if vid_file:
                    uploaded_video = vid_file
                    st.video(vid_file)
                    
                # --- БЛОК СУБТИТРОВ ---
                if is_edit and step_initial.get("existing_subtitles"):
                    st.info(f"💬 Текущие субтитры: **{step_initial['existing_subtitles']}**")
                    if st.button("🗑️ Удалить субтитры", key=f"del_sub_{uid}"):
                        step_initial["existing_subtitles"] = None
                        st.rerun()
                        
                sub_file = st.file_uploader("💬 Прикрепить субтитры (опционально, формат .vtt или .srt)", type=["vtt", "srt"], key=f"sub_{uid}")

            # --- ЛОГИКА ДЛЯ КАРТИНОК (С АККУМУЛЯТОРОМ) ---
            elif layout != "Без картинок":
                is_gallery = (layout == "Галерея в ряд (images)")
                
                # 1. Показываем старые сохраненные картинки
                if is_edit and step_initial["existing_images"]:
                    st.markdown("**💾 Сохраненные на сервере:**")
                    cols_img = st.columns(4)
                    for c_idx, img_name in enumerate(step_initial["existing_images"]):
                        with cols_img[c_idx % 4]:
                            img_path = os.path.join("CorpHub", "instructions", inst_id, img_name)
                            if os.path.exists(img_path): st.image(img_path, use_container_width=True)
                            if st.button("🗑️", key=f"del_img_{uid}_{c_idx}", use_container_width=True):
                                step_initial["existing_images"].pop(c_idx)
                                st.rerun()

                # 2. Показываем новые зафиксированные картинки (Аккумулятор)
                if step_initial["memory_images"]:
                    st.markdown("**🆕 Новые добавленные картинки:**")
                    cols_new = st.columns(4)
                    for c_idx, m_img in enumerate(step_initial["memory_images"]):
                        with cols_new[c_idx % 4]:
                            st.image(m_img["bytes"], use_container_width=True)
                            if st.button("🗑️", key=f"del_mem_{uid}_{c_idx}", use_container_width=True):
                                step_initial["memory_images"].pop(c_idx)
                                st.rerun()

                # 3. Красивая кнопка буфера обмена с МГНОВЕННЫМ сохранением
                uploader_key = f"file_up_{uid}_{step_initial['uploader_key']}"
                
                if paste_image_button:
                    paste_res = paste_image_button(
                        label="📋 Вставить картинку из буфера",
                        background_color="#262730",       # Родной темный цвет Streamlit
                        hover_background_color="#33343f", # Цвет при наведении мыши
                        text_color="#fafafa",             
                        key=f"paste_{uploader_key}"
                    )
                    if paste_res and paste_res.image_data:
                        # УМНАЯ ЗАМЕНА: Если это не галерея, оставляем только одну картинку
                        if not is_gallery:
                            step_initial["existing_images"] = []
                            step_initial["memory_images"] = []
                            
                        # Конвертируем PIL Image в байты
                        img_byte_arr = BytesIO()
                        paste_res.image_data.save(img_byte_arr, format='PNG')
                        fname = f"clipboard_{uuid.uuid4().hex[:6]}.png"
                        
                        # Мгновенно добавляем в аккумулятор
                        step_initial["memory_images"].append({"name": fname, "bytes": img_byte_arr.getvalue()})
                        
                        # Меняем ключ, чтобы кнопка буфера сбросилась для следующей картинки
                        step_initial["uploader_key"] += 1
                        st.rerun()

                # 4. Стандартный загрузчик для файлов с диска
                files = st.file_uploader("📥 Либо выберите файлы с диска", type=["png", "jpg", "jpeg"], accept_multiple_files=is_gallery, key=uploader_key)
                
                if files:
                    if st.button("➕ Зафиксировать загруженные файлы", key=f"confirm_{uploader_key}", type="primary"):
                        files_list = files if isinstance(files, list) else [files]
                        
                        if not is_gallery:
                            step_initial["existing_images"] = []
                            step_initial["memory_images"] = []
                            
                        for f in files_list:
                            step_initial["memory_images"].append({"name": f.name, "bytes": f.getvalue()})
                            
                        step_initial["uploader_key"] += 1
                        st.rerun()
            
            # Синхронизация данных
            st.session_state.step_data_store[uid]["heading"] = step_heading
            st.session_state.step_data_store[uid]["text"] = text_content or ""
            st.session_state.step_data_store[uid]["layout"] = layout
            
            steps_data_for_save.append({
                "heading": step_heading,
                "text": text_content,
                "layout": layout,
                "memory_images": step_initial["memory_images"],
                "video_file": uploaded_video,
                "sub_file": sub_file, # <-- ДОБАВЛЕНО
                "existing_imgs": step_initial["existing_images"] if is_edit else [],
                "existing_vid": step_initial.get("existing_video") if is_edit else None,
                "existing_sub": step_initial.get("existing_subtitles") if is_edit else None # <-- ДОБАВЛЕНО
            })

    if st.button("➕ Добавить шаг в конец", use_container_width=True):
        new_uid = str(uuid.uuid4())
        st.session_state.step_uids.append(new_uid)
        st.session_state.step_data_store[new_uid] = get_empty_step()
        st.rerun()

    st.write("---")
    
    # ==================================================
    # ФИНАЛЬНОЕ СОХРАНЕНИЕ 
    # ==================================================
    btn_text = "💾 Сохранить изменения" if is_edit else "🚀 Опубликовать инструкцию"
    if st.button(btn_text, type="primary", use_container_width=True):
        if not title:
            st.error("Заполните Заголовок карточки!")
            return
            
        base_folder_path = os.path.join("CorpHub", "instructions", inst_id)
        new_folder_path = base_folder_path
        
        if not is_edit:
            counter = 1
            while os.path.exists(new_folder_path):
                new_folder_path = f"{base_folder_path}_{counter}"
                counter += 1
                
        if not os.path.exists(new_folder_path):
            os.makedirs(new_folder_path)
            
        new_info = {
            "title": title,
            "description": desc,
            "icon": icon,
            "category": "instruction",
            "order": order
        }
        
        for idx, step in enumerate(steps_data_for_save):
            step_num = idx + 1
            block_key = f"block_{step_num}"
            block_content = {}
            
            if step["heading"]: block_content["heading"] = step["heading"]
            if step["text"]: block_content["text"] = step["text"]
                
            # --- СОХРАНЕНИЕ ВИДЕО ---
            if step["layout"] == "🎥 Видео (снизу)":
                if step["video_file"]:
                    vf = step["video_file"]
                    safe_vid_name = f"step{step_num}_video.mp4"
                    temp_vid_path = os.path.join(new_folder_path, f"temp_{vf.name}")
                    final_vid_path = os.path.join(new_folder_path, safe_vid_name)
                    
                    with open(temp_vid_path, "wb") as disk_file:
                        disk_file.write(vf.getbuffer())
                    
                    with st.spinner(f"Конвертация видео для шага {step_num}..."):
                        subprocess.run([
                            "ffmpeg", "-y", "-i", temp_vid_path, 
                            "-vcodec", "libx264", "-acodec", "aac", 
                            "-preset", "fast", final_vid_path
                        ], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
                        
                    os.remove(temp_vid_path)
                    block_content["video"] = safe_vid_name
                elif step["existing_vid"]:
                    block_content["video"] = step["existing_vid"]

            # --- СОХРАНЕНИЕ КАРТИНОК ---
            else:
                saved_filenames = []
                
                if step["existing_imgs"] and step["layout"] != "Без картинок":
                    saved_filenames.extend(step["existing_imgs"])
                    
                if step["memory_images"] and step["layout"] != "Без картинок":
                    for file_idx, m_img in enumerate(step["memory_images"]):
                        order_idx = len(saved_filenames) + file_idx
                        safe_name = f"step{step_num}_{order_idx}_{m_img['name']}"
                        with open(os.path.join(new_folder_path, safe_name), "wb") as disk_file:
                            disk_file.write(m_img["bytes"])
                        saved_filenames.append(safe_name)
                        
                if saved_filenames:
                    if step["layout"] == "Маленькая сбоку (image)":
                        block_content["image"] = saved_filenames[0]
                    elif step["layout"] == "Широкая снизу (big_image)":
                        block_content["big_image"] = saved_filenames[0]
                    elif step["layout"] == "Галерея в ряд (images)":
                        block_content["images"] = saved_filenames
                    
            if not block_content.get("video") and not block_content.get("image") and not block_content.get("big_image") and not block_content.get("images") and step["text"] and not step["heading"]:
                new_info[block_key] = step["text"]
            elif block_content:
                new_info[block_key] = block_content

        with open(os.path.join(new_folder_path, "info.json"), "w", encoding="utf-8") as f:
            json.dump(new_info, f, ensure_ascii=False, indent=2)
            
        st.success("✅ Инструкция успешно сохранена!")
        
        if not is_edit:
            st.session_state.editor_mode = "create"
            st.session_state.loaded_data = None
            first_uid = str(uuid.uuid4())
            st.session_state.step_uids = [first_uid]
            st.session_state.step_data_store = {first_uid: get_empty_step()}