import sqlite3
import subprocess
import os
import json
from aiogram import Bot, Dispatcher, types
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from aiogram.filters import Command

BOT_TOKEN = "8033548149:AAGwdNB13N4PEkVeOqbmIgKAh1wfjHFn9Bo"

bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()

# Функция для работы с status_bots.json
def get_bot_status():
    if os.path.exists('status_bots.json'):
        with open('status_bots.json', 'r') as f:
            return json.load(f)
    return {}

def save_bot_status(status_data):
    with open('status_bots.json', 'w') as f:
        json.dump(status_data, f, indent=4)

def set_bot_status(username, status):
    status_data = get_bot_status()
    status_data[username] = status
    save_bot_status(status_data)

def get_bot_status_by_username(username):
    status_data = get_bot_status()
    return status_data.get(username, False)

# Функция для получения списка ботов из базы данных
def get_bots_list():
    conn = sqlite3.connect('bots.db')
    cursor = conn.cursor()
    cursor.execute('SELECT id, username FROM bots')
    bots = cursor.fetchall()
    conn.close()
    return bots

# Функция для получения пути к боту по ID
def get_bot_path(bot_id):
    conn = sqlite3.connect('bots.db')
    cursor = conn.cursor()
    cursor.execute('SELECT url FROM bots WHERE id = ?', (bot_id,))
    result = cursor.fetchone()
    conn.close()
    if result:
        return result[0].strip('/')
    return None

# Функция для получения username по ID
def get_bot_username(bot_id):
    conn = sqlite3.connect('bots.db')
    cursor = conn.cursor()
    cursor.execute('SELECT username FROM bots WHERE id = ?', (bot_id,))
    result = cursor.fetchone()
    conn.close()
    if result:
        return result[0]
    return None

# Словарь для хранения процессов ботов
bot_processes = {}

# Обработчик команды /start
@dp.message(Command("start"))
async def start_command(message: types.Message):
    bots = get_bots_list()
    
    if not bots:
        await message.answer("Нет доступных ботов.")
        return
    
    keyboard = InlineKeyboardMarkup(inline_keyboard=[])
    
    for bot_id, username in bots:
        status = get_bot_status_by_username(username)
        status_icon = "🟢" if status else "🔴"
        button = InlineKeyboardButton(
            text=f"{status_icon} @{username}", 
            callback_data=f"bot_{bot_id}"
        )
        keyboard.inline_keyboard.append([button])
    
    await message.answer("Выберите бота:", reply_markup=keyboard)

# Обработчик нажатий на инлайн кнопки
@dp.callback_query()
async def handle_callback(callback: types.CallbackQuery):
    data = callback.data
    
    if data.startswith("bot_"):
        bot_id = data.split("_")[1]
        bot_path = get_bot_path(bot_id)
        username = get_bot_username(bot_id)
        
        if bot_path and username:
            status = get_bot_status_by_username(username)
            status_text = "🟢 Включен" if status else "🔴 Выключен"
            
            if status:
                button = InlineKeyboardButton(text="🔴 Выключить", callback_data=f"stop_{bot_id}")
            else:
                button = InlineKeyboardButton(text="🟢 Включить", callback_data=f"start_{bot_id}")
            
            keyboard = InlineKeyboardMarkup(inline_keyboard=[[button]])
            
            await callback.message.edit_text(
                f"Бот: @{username}\n"
                f"Статус: {status_text}\n"
                f"Путь: {bot_path}\n\n"
                f"Выберите действие:",
                reply_markup=keyboard
            )
        else:
            await callback.answer("Бот не найден!", show_alert=True)
    
    elif data.startswith("start_"):
        bot_id = data.split("_")[1]
        bot_path = get_bot_path(bot_id)
        username = get_bot_username(bot_id)
        
        if bot_path and os.path.exists(bot_path) and username:
            try:
                # Запускаем bot.py
                bot_py_path = os.path.join(bot_path, "bot.py")
                if os.path.exists(bot_py_path):
                    # Запускаем процесс в фоне
                    process = subprocess.Popen(
                        ["python", "bot.py"],
                        cwd=bot_path,
                        stdout=subprocess.PIPE,
                        stderr=subprocess.PIPE
                    )
                    
                    # Сохраняем процесс и статус
                    bot_processes[username] = process
                    set_bot_status(username, True)
                    
                    keyboard = InlineKeyboardMarkup(inline_keyboard=[
                        [InlineKeyboardButton(text="🔴 Выключить", callback_data=f"stop_{bot_id}")]
                    ])
                    
                    await callback.message.edit_text(
                        f"✅ Бот @{username} запущен!\n"
                        f"Путь: {bot_path}\n"
                        f"PID: {process.pid}\n\n"
                        f"Статус: 🟢 Включен",
                        reply_markup=keyboard
                    )
                else:
                    await callback.message.edit_text(
                        f"❌ Файл bot.py не найден в папке бота!\n"
                        f"Путь: {bot_path}"
                    )
            except Exception as e:
                await callback.message.edit_text(
                    f"❌ Ошибка при запуске бота:\n{str(e)}"
                )
        else:
            await callback.message.edit_text("❌ Папка бота не найдена!")
    
    elif data.startswith("stop_"):
        bot_id = data.split("_")[1]
        username = get_bot_username(bot_id)
        
        if username:
            try:
                # Останавливаем процесс
                if username in bot_processes:
                    process = bot_processes[username]
                    process.terminate()
                    process.wait()
                    del bot_processes[username]
                
                # Обновляем статус
                set_bot_status(username, False)
                
                keyboard = InlineKeyboardMarkup(inline_keyboard=[
                    [InlineKeyboardButton(text="🟢 Включить", callback_data=f"start_{bot_id}")]
                ])
                
                await callback.message.edit_text(
                    f"🔴 Бот @{username} остановлен!\n\n"
                    f"Статус: 🔴 Выключен",
                    reply_markup=keyboard
                )
            except Exception as e:
                await callback.message.edit_text(
                    f"❌ Ошибка при остановке бота:\n{str(e)}"
                )
        else:
            await callback.message.edit_text("❌ Бот не найден!")

# Запуск бота
async def main():
    # Инициализируем статусы при запуске
    status_data = get_bot_status()
    for username in status_data:
        status_data[username] = False  # Сбрасываем все статусы при перезапуске
    save_bot_status(status_data)
    
    await dp.start_polling(bot)

if __name__ == "__main__":
    import asyncio
    asyncio.run(main())