print("DEBUG: Starting bot.py script...")

import os
import asyncio
import sys
import time
from urllib.parse import unquote 

# Check python version
print(f"DEBUG: Python Version: {sys.version}")

try:
    print("DEBUG: Importing libraries...")
    from pyrogram import Client, filters, idle
    from config import Config
    from database import db
    from turboviplay import TurboviplayAPI
    from helpers import progress_bar
    from queue_manager import queue_manager
    print("DEBUG: Libraries imported successfully.")
except ImportError as e:
    print(f"❌ CRITICAL ERROR: Missing library. {e}")
    print("Run: pip install -r requirements.txt")
    sys.exit(1)
except Exception as e:
    print(f"❌ CRITICAL ERROR during import: {e}")
    sys.exit(1)

# Initialize Client
try:
    app = Client(
        "turboviplay_bot",
        api_id=Config.API_ID,
        api_hash=Config.API_HASH,
        bot_token=Config.BOT_TOKEN
    )
except Exception as e:
    print(f"❌ Error setting up Client: {e}")
    sys.exit(1)

# --- Command Handlers ---

@app.on_message(filters.command("start"))
async def start(client, message):
    await message.reply_text(
        "👋 **Welcome to Turboviplay Uploader Bot!**\n\n"
        "1. Send `/setapi YOUR_API_KEY` to authorize.\n"
        "2. Send video files to upload.\n"
        "3. `/cancel` to stop current upload.\n"
        "4. `/clear` to clear your queue."
    )

@app.on_message(filters.command("setapi"))
async def set_api(client, message):
    if len(message.command) < 2:
        return await message.reply_text("⚠ Usage: `/setapi YOUR_KEY`")
    
    api_key = message.command[1].strip()
    user_id = message.from_user.id
    
    msg = await message.reply_text("🔄 Validating API Key...")
    
    uploader = TurboviplayAPI(api_key)
    is_valid, reason = await uploader.validate_key()
    
    if is_valid:
        if db.set_api_key(user_id, api_key):
            await msg.edit("✅ **API Key Verified & Saved!**\nYou can now send files to upload.")
        else:
            await msg.edit("❌ Database Error while saving key.")
    else:
        await msg.edit(f"❌ **Invalid API Key.**\nServer response: {reason}")

@app.on_message(filters.command("delapi"))
async def del_api(client, message):
    user_id = message.from_user.id
    if db.delete_api_key(user_id):
        await message.reply_text("🗑 API Key deleted.")
    else:
        await message.reply_text("❌ Error deleting API Key.")

@app.on_message(filters.command("cancel"))
async def cancel_process(client, message):
    user_id = message.from_user.id
    if await queue_manager.cancel_current(user_id):
        await message.reply_text("⏹ Process cancelled.")
    else:
        await message.reply_text("⚠ No active process to cancel.")

@app.on_message(filters.command("clear"))
async def clear_queue_cmd(client, message):
    user_id = message.from_user.id
    count = queue_manager.clear_queue(user_id)
    await message.reply_text(f"🧹 Queue cleared. Removed {count} items.")

@app.on_message(filters.video | filters.document)
async def incoming_video(client, message):
    user_id = message.from_user.id
    api_key = db.get_api_key(user_id)
    
    if not api_key:
        return await message.reply_text("⚠ Please set your API key first using `/setapi`.")
    
    # 1. Send the "Added to queue" message immediately
    queue_pos = queue_manager.queues[user_id].qsize() + 1
    reply_msg = await message.reply_text(f"✅ Added to queue at position {queue_pos}.")
    
    # 2. Add BOTH the user message and the bot's reply message to the queue
    # We pass a tuple: (user_message, bot_reply_message)
    await queue_manager.add(user_id, (message, reply_msg))
    
    if not queue_manager.workers_running[user_id]:
        asyncio.create_task(process_user_queue(client, user_id))

async def process_user_queue(client, user_id):
    queue_manager.workers_running[user_id] = True
    
    while True:
        # Unpack the tuple
        item = await queue_manager.get_next(user_id)
        if item is None:
            break
            
        msg, status_msg = item  # msg = user file, status_msg = "Added to queue" message
            
        current_task = asyncio.current_task()
        queue_manager.set_task(user_id, current_task)
        
        # We edit the EXISTING "Added to queue" message
        await status_msg.edit("⏳ **Initializing process...**")
        file_path = None
        
        try:
            # 1. Download
            start_time = time.time()
            api_key = db.get_api_key(user_id)
            
            async def dl_progress(current, total):
                await progress_bar(current, total, status_msg, start_time, "Downloading")

            file_path = await client.download_media(
                msg, 
                file_name=Config.DOWNLOAD_PATH,
                progress=dl_progress
            )
            
            if not file_path:
                await status_msg.edit("❌ Download failed.")
                continue

            # 2. Get Upload Server
            uploader = TurboviplayAPI(api_key)
            upload_url, error_msg = await uploader.get_upload_server()
            
            if not upload_url:
                await status_msg.edit(f"❌ Failed to get upload server.\nReason: {error_msg}")
                continue
            
            # 3. Upload
            await status_msg.edit("⬆ **Starting Upload...**")
            start_time_up = time.time()
            
            async def up_progress(current, total):
                await progress_bar(current, total, status_msg, start_time_up, "Uploading")

            response = await uploader.upload_file(file_path, upload_url, up_progress)
            
            # 4. Handle Response
            if response and isinstance(response, dict):
                # Debug print to help if issues persist
                print(f"DEBUG: Upload Response: {response}")

                # CASE A: Standard Success (as seen in screenshot)
                # {'videoID': 'slug_string', 'title': 'encoded_title'}
                if 'videoID' in response and isinstance(response['videoID'], str):
                    slug = response['videoID']
                    raw_title = response.get('title', 'Unknown')
                    title = unquote(raw_title) # Decode %20, %28 etc
                    
                    embed_link = f"https://turbovidhls.com/t/{slug}"
                    download_link = f"https://turbovidhls.com/d/{slug}"
                    
                    await status_msg.edit(
                        f"✅ **Upload Completed Successfully!**\n\n"
                        f"📂 **File Name:**\n`{title}`\n\n"
                        f"🔗 **Embed Link:**\n`{embed_link}`\n\n"
                        f"📥 **Download Link:**\n`{download_link}`",
                        disable_web_page_preview=True
                    )
                
                # CASE B: Nested structure (Documentation style)
                # {'videoID': {'slug': '...', ...}}
                elif 'videoID' in response and isinstance(response['videoID'], dict):
                    vid_data = response['videoID']
                    slug = vid_data.get('slug')
                    title = vid_data.get('title', 'Unknown')
                    
                    if slug:
                        embed_link = f"https://turbovidhls.com/t/{slug}"
                        download_link = f"https://turbovidhls.com/d/{slug}"
                        
                        await status_msg.edit(
                            f"✅ **Upload Completed Successfully!**\n\n"
                            f"📂 **File Name:**\n`{title}`\n\n"
                            f"🔗 **Embed Link:**\n`{embed_link}`\n\n"
                            f"📥 **Download Link:**\n`{download_link}`",
                            disable_web_page_preview=True
                        )
                    else:
                        await status_msg.edit(f"⚠ Upload successful, but Slug missing in response: {response}")

                else:
                    await status_msg.edit(f"⚠ **Upload Ambiguous.**\nServer Response: `{str(response)}`")
            else:
                await status_msg.edit(f"❌ Upload failed. Unexpected response: `{str(response)}`")

        except asyncio.CancelledError:
            await status_msg.edit("⏹ **Operation Cancelled.**")
        except Exception as e:
            print(f"ERROR in worker: {e}")
            await status_msg.edit(f"❌ **Error:** `{str(e)}`")
        finally:
            if file_path and os.path.exists(file_path):
                os.remove(file_path)
            
            queue_manager.clear_task(user_id)
            queue_manager.queues[user_id].task_done()
    
    queue_manager.workers_running[user_id] = False

if __name__ == "__main__":
    print("DEBUG: Entering main block...")
    try:
        print("DEBUG: Starting Client...")
        app.start()
        print("✅ BOT STARTED SUCCESSFULLY!")
        idle()
        app.stop()
    except Exception as e:
        print(f"❌ FATAL ERROR: {e}")