import asyncio
import os
import time
from pyrogram import Client, filters
from database import get_api_key
from streamhg_api import StreamHG
from helpers import progress_helper

user_queues = {}
cancel_signals = {} 

async def add_to_queue(client, message, user_id):
    if user_id not in user_queues:
        user_queues[user_id] = {"queue": asyncio.Queue(), "is_running": False}
    
    q_size = user_queues[user_id]["queue"].qsize() + 1
    queue_msg = await message.reply_text(f"✅ **Added to queue** at position: `{q_size}`")
    
    await user_queues[user_id]["queue"].put((message, queue_msg))
    
    if not user_queues[user_id]["is_running"]:
        user_queues[user_id]["is_running"] = True
        asyncio.create_task(process_queue(client, user_id))

async def process_queue(client, user_id):
    queue = user_queues[user_id]["queue"]
    
    while True:
        if queue.empty():
            break

        if cancel_signals.get(user_id, False):
            while not queue.empty():
                try: queue.get_nowait(); queue.task_done()
                except: break
            cancel_signals[user_id] = False
            user_queues[user_id]["is_running"] = False
            await client.send_message(user_id, "🚫 Queue stopped and cleared.")
            return

        try:
            task_data = queue.get_nowait()
        except asyncio.QueueEmpty:
            break

        message = task_data[0]
        status_msg = task_data[1]
        api_key = get_api_key(user_id)
        
        if not api_key:
            await safe_edit(status_msg, "⚠️ API Key not found. Please login.")
            queue.task_done()
            continue

        await safe_edit(status_msg, "⬇️ **Downloading file...**")
        
        if not os.path.exists("downloads"):
            os.makedirs("downloads")

        file_name = message.video.file_name if message.video else (message.document.file_name if message.document else "video.mp4")
        safe_filename = "".join([c for c in file_name if c.isalpha() or c.isdigit() or c in "._-"]).strip() or "video.mp4"
        file_path = f"downloads/{user_id}_{message.id}_{safe_filename}"
        
        # We use a list to store last update time so it can be updated inside the callback
        dl_update_store = [0]
        ul_update_store = [0]
        start_time = time.time()
        ul_start_time = time.time()

        try:
            # 1. Download
            path = await client.download_media(
                message,
                file_name=file_path,
                progress=progress_helper.progress_for_pyrogram,
                progress_args=("⬇️ Downloading", status_msg, start_time, dl_update_store)
            )
            
            # 2. Upload
            await safe_edit(status_msg, "⬆️ **Starting Upload...**")
            ul_start_time = time.time()

            async def upload_progress(current, total):
                await progress_helper.progress_for_pyrogram(
                    current, total, "⬆️ Uploading", status_msg, ul_start_time, ul_update_store
                )

            response = await StreamHG.upload_file(api_key, path, progress_callback=upload_progress)
            
            # 3. Result
            if response.get("status") == 200:
                files = response.get("files", [])
                if files:
                    file_code = files[0].get("filecode")
                    file_name_res = files[0].get("filename")
                    embed_link = f"https://hglink.to/e/{file_code}"
                    
                    # Force final edit
                    await safe_edit(status_msg, 
                        f"✅ **Upload Complete!**\n\n"
                        f"📂 **File:** `{file_name_res}`\n"
                        f"🔗 **Embed:** `{embed_link}`\n"
                        f"🔗 **Direct:** `https://streamhg.com/{file_code}`"
                    )
                else:
                     await safe_edit(status_msg, f"❌ Upload failed: No file data.")
            else:
                await safe_edit(status_msg, f"❌ Error: {response.get('msg')}")

        except Exception as e:
            await safe_edit(status_msg, f"❌ **Error:** {str(e)}")
        finally:
            if os.path.exists(file_path):
                try: os.remove(file_path)
                except: pass
            queue.task_done()

    user_queues[user_id]["is_running"] = False
    
    # Double check queue
    if not queue.empty():
         user_queues[user_id]["is_running"] = True
         asyncio.create_task(process_queue(client, user_id))
    else:
         await client.send_message(user_id, "🏁 **Queue Finished!**")

async def safe_edit(message, text):
    try:
        await message.edit(text)
    except Exception:
        pass