import os
import sys
import json
import shutil
import subprocess
import requests
import telebot

# Load configuration
CONFIG_PATH = os.path.join(os.path.dirname(__file__), "config.json")
try:
    with open(CONFIG_PATH, "r") as f:
        config = json.load(f)
except Exception as e:
    print(f"Error loading config.json: {e}")
    sys.exit(1)

TOKEN = config.get("TELEGRAM_BOT_TOKEN")
CF_TOKEN = config.get("CLOUDFLARE_API_TOKEN")
CF_ZONE_ID = config.get("CLOUDFLARE_ZONE_ID")
DOMAIN_NAME = config.get("DOMAIN_NAME")
SERVER_IP = config.get("SERVER_IP")
WEB_ROOT_DIR = config.get("WEB_ROOT_DIR")
FRONTEND_DIR = config.get("FRONTEND_DIR", "/Users/aryanrai/.gemini/antigravity/scratch/kuro-panel")
UPDATES_DIR = config.get("UPDATES_DIR", "/Users/aryanrai/kuro-updates")

if not TOKEN or "YOUR_TELEGRAM" in TOKEN:
    print("Please set your TELEGRAM_BOT_TOKEN inside bot/config.json")
    sys.exit(1)

bot = telebot.TeleBot(TOKEN)
user_sessions = {}

# Session States
STATE_WAIT_NAME = 1
STATE_WAIT_SUBDOMAIN = 2
STATE_WAIT_THEME = 3
STATE_WAIT_VOICE = 4
STATE_WAIT_LOGO = 5

THEMES_LIST = (
    "1. Classic Blue 🔵\n"
    "2. Forest Green 🟢\n"
    "3. Royal Purple 🟣\n"
    "4. Amber Gold 🟡\n"
    "5. Cyber Teal 🌐\n"
    "6. Crimson Red 🔴\n"
    "7. Electric Indigo 🌌\n"
    "8. Steel Grey ⚪\n"
    "9. Hot Pink 🌸\n"
    "10. Orange Flare 🟠\n"
    "11. Mint Frost ❄️\n"
    "12. Deep Navy 🚢\n"
    "13. Rose Gold 🌹\n"
    "14. Cyberpunk Yellow ⚡\n"
    "15. Acid Green 🧪"
)

@bot.message_handler(commands=['start', 'help'])
def send_welcome(message):
    welcome_text = (
        "👋 **Welcome to the Rebranded Panel Creator Bot!**\n\n"
        "Use this bot to instantly spin up new, independent rebranded panels.\n\n"
        "⚡ **Commands:**\n"
        "/create_panel - Start rebranding a new panel.\n"
        "/cancel - Abort current creation process."
    )
    bot.reply_to(message, welcome_text, parse_mode="Markdown")

@bot.message_handler(commands=['cancel'])
def cancel_creation(message):
    chat_id = message.chat.id
    if chat_id in user_sessions:
        # Clean up temporary downloaded logo
        temp_logo = user_sessions[chat_id].get("temp_logo")
        if temp_logo and os.path.exists(temp_logo):
            os.remove(temp_logo)
        del user_sessions[chat_id]
        bot.reply_to(message, "❌ Creation process cancelled.")
    else:
        bot.reply_to(message, "No active creation process to cancel.")

@bot.message_handler(commands=['create_panel'])
def start_create(message):
    chat_id = message.chat.id
    user_sessions[chat_id] = {
        "state": STATE_WAIT_NAME,
        "brand_name": "",
        "subdomain": "",
        "theme": "1",
        "voice": "",
        "temp_logo": ""
    }
    bot.reply_to(message, "🏷️ **Step 1: Enter your Brand Name** (e.g. SHADOW-OPS):")

@bot.message_handler(func=lambda message: message.chat.id in user_sessions)
def handle_steps(message):
    chat_id = message.chat.id
    session = user_sessions[chat_id]
    state = session["state"]

    if state == STATE_WAIT_NAME:
        session["brand_name"] = message.text.strip()
        session["state"] = STATE_WAIT_SUBDOMAIN
        bot.reply_to(
            message,
            "🌐 **Step 2: Enter Subdomain Prefix**\n"
            f"Only enter the prefix (e.g., if you type 'shadow', the panel will be shadow.{DOMAIN_NAME}):"
        )

    elif state == STATE_WAIT_SUBDOMAIN:
        subdomain = message.text.strip().lower().replace(" ", "-")
        # Validate subdomain characters
        if not subdomain.isalnum() and "-" not in subdomain:
            bot.reply_to(message, "❌ Invalid subdomain. Please use letters, numbers, and hyphens only:")
            return

        session["subdomain"] = subdomain
        session["state"] = STATE_WAIT_THEME
        bot.reply_to(
            message,
            f"🎨 **Step 3: Select UI Theme (1-15)**\n\n{THEMES_LIST}\n\nReply with the theme number (e.g., 5):"
        )

    elif state == STATE_WAIT_THEME:
        theme = message.text.strip()
        if not theme.isdigit() or not (1 <= int(theme) <= 15):
            bot.reply_to(message, "❌ Please reply with a valid number between 1 and 15:")
            return

        session["theme"] = theme
        session["state"] = STATE_WAIT_VOICE
        bot.reply_to(
            message,
            "🗣️ **Step 4: Enter Welcome Voice Text**\n"
            "This will be announced in a deep robotic tone when logging in (e.g. 'Welcome to Shadow Cheats'):"
        )

    elif state == STATE_WAIT_VOICE:
        session["voice"] = message.text.strip()
        session["state"] = STATE_WAIT_LOGO
        bot.reply_to(message, "🖼️ **Step 5: Send the logo image file (JPEG or PNG)**:")

@bot.message_handler(content_types=['photo', 'document'], func=lambda message: message.chat.id in user_sessions)
def handle_logo(message):
    chat_id = message.chat.id
    session = user_sessions[chat_id]
    
    if session["state"] != STATE_WAIT_LOGO:
        return

    # Download image file
    try:
        if message.content_type == 'photo':
            file_id = message.photo[-1].file_id
        else:
            file_id = message.document.file_id

        file_info = bot.get_file(file_id)
        downloaded_file = bot.download_file(file_info.file_path)
        
        # Save temp logo
        temp_logo_path = os.path.join(os.path.dirname(__file__), f"temp_logo_{chat_id}.jpg")
        with open(temp_logo_path, 'wb') as new_file:
            new_file.write(downloaded_file)
            
        session["temp_logo"] = temp_logo_path
    except Exception as e:
        bot.reply_to(message, f"❌ Failed to download image: {e}. Please send again:")
        return

    bot.reply_to(message, "⚙️ **Processing rebranding & compilation... Please wait (this takes about 15-20 seconds)**")
    
    # Run the dynamic compiler
    try:
        # Create Cloudflare DNS Record
        cf_success = create_cloudflare_dns(session["subdomain"])
        if not cf_success:
            bot.send_message(chat_id, "⚠️ Warning: Could not create DNS record in Cloudflare automatically. Proceeding with files...")
        
        # Output folder for new subdomain
        subdomain_dir = os.path.join(WEB_ROOT_DIR, f"{session['subdomain']}.{DOMAIN_NAME}")
        os.makedirs(subdomain_dir, exist_ok=True)
        os.makedirs(os.path.join(subdomain_dir, "public"), exist_ok=True)

        # Check if compiler exists, otherwise fall back to pre-compiled master template installer.php
        compiler_path = os.path.join(FRONTEND_DIR, "rebrand_compile.py")
        master_installer_path = os.path.join(UPDATES_DIR, "installer.php")
        dest_installer = os.path.join(subdomain_dir, "public", "installer.php")

        if os.path.exists(compiler_path):
            print("Found rebrand_compile.py. Running compilation...")
            subprocess.run([
                "python3", compiler_path,
                "--name", session["brand_name"],
                "--voice", session["voice"],
                "--theme", session["theme"],
                "--logo", session["temp_logo"],
                "--frontend_dir", FRONTEND_DIR,
                "--updates_dir", UPDATES_DIR
            ], check=True)
            
            safe_brand_name = session["brand_name"].lower().replace(" ", "_").replace("-", "_")
            compiled_installer = os.path.join(UPDATES_DIR, f"installer_{safe_brand_name}.php")
            if os.path.exists(compiled_installer):
                shutil.copyfile(compiled_installer, dest_installer)
            else:
                raise Exception("Compiled installer not found after build.")
        elif os.path.exists(master_installer_path):
            print("Using pre-compiled master template installer...")
            shutil.copyfile(master_installer_path, dest_installer)
        else:
            raise Exception("Neither compiler nor master installer.php template was found.")

        os.chmod(dest_installer, 0755)

        # Execute installer locally to run migrations, seeds, and unpack assets with environment injection
        print(f"Running installer CLI extraction for {session['subdomain']}...")
        env = os.environ.copy()
        env["BRAND_NAME"] = session["brand_name"]
        env["WELCOME_VOICE"] = session["voice"]
        env["THEME_INDEX"] = session["theme"]
        subprocess.run([
            "php", dest_installer
        ], cwd=subdomain_dir, env=env, check=True)

        # Clean up installer script for security
        if os.path.exists(dest_installer):
            os.remove(dest_installer)

        # Success message
        panel_url = f"https://{session['subdomain']}.{DOMAIN_NAME}"
        connect_url = f"https://{session['subdomain']}.{DOMAIN_NAME}/api"
        
        success_message = (
            "🎉 **Rebranded Panel Created Successfully!**\n\n"
            f"🔗 **Panel Link:** {panel_url}\n"
            f"📡 **Connect Link (API):** `{connect_url}`\n\n"
            "👤 **Admin Login Credentials:**\n"
            "• **ID:** `OWNER`\n"
            "• **Password:** `OWNER1234`\n\n"
            "💡 _(Make sure to change the admin password after logging in for security)_"
        )
        bot.send_message(chat_id, success_message, parse_mode="Markdown")

    except Exception as e:
        bot.send_message(chat_id, f"❌ Failed to compile or build panel: {e}")
    finally:
        # Clean up temp logo file & clear session
        if os.path.exists(session["temp_logo"]):
            os.remove(session["temp_logo"])
        del user_sessions[chat_id]

def create_cloudflare_dns(subdomain_prefix):
    """
    Creates an A DNS record in Cloudflare for the new subdomain.
    """
    if "YOUR_CLOUDFLARE" in CF_TOKEN or "YOUR_ZONE" in CF_ZONE_ID:
        print("Skipping Cloudflare API: credentials not configured.")
        return False

    url = f"https://api.cloudflare.com/client/v4/zones/{CF_ZONE_ID}/dns_records"
    headers = {
        "Authorization": f"Bearer {CF_TOKEN}",
        "Content-Type": "application/json"
    }
    data = {
        "type": "A",
        "name": f"{subdomain_prefix}.{DOMAIN_NAME}",
        "content": SERVER_IP,
        "ttl": 1,  # Auto
        "proxied": True
    }
    try:
        response = requests.post(url, json=data, headers=headers)
        res_data = response.json()
        return res_data.get("success", False)
    except Exception as e:
        print(f"Cloudflare API Request failed: {e}")
        return False

if __name__ == "__main__":
    print("Telegram Bot Daemon running... Press Ctrl+C to stop.")
    bot.infinity_polling()
