import telebot
from gradio_client import Client
import sqlite3
from datetime import datetime
import random

# Создание клиента Gradio
client = Client("yuntian-deng/ChatGPT")

# Создание Telegram-бота
TOKEN = '<TRUFFLEHOG_REDACTED_TELEGRAMBOTTOKEN>'
bot = telebot.TeleBot(TOKEN)

# База данных
db_connection = sqlite3.connect('chatbot.db', check_same_thread=False)
cursor = db_connection.cursor()

# Создание таблиц, если их еще нет
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
    user_id INTEGER PRIMARY KEY,
    username TEXT,
    is_blocked INTEGER DEFAULT 0
)''')

cursor.execute('''
CREATE TABLE IF NOT EXISTS chat_history (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    user_id INTEGER,
    user_message TEXT,
    bot_response TEXT,
    timestamp DATETIME,
    FOREIGN KEY(user_id) REFERENCES users(user_id)
)''')

db_connection.commit()

# Список администраторов
admins = [1013039772]

# Контекст чата для пользователей
chat_context = {}

# Команда /start
@bot.message_handler(commands=['start'])
def start(message):
    name = message.chat.first_name if message.chat.first_name else "N/A"
    cursor.execute('INSERT OR IGNORE INTO users (user_id, username) VALUES (?, ?)',
                   (message.chat.id, name))
    db_connection.commit()
    bot.reply_to(message, "Привет! Напиши что-нибудь, и я отвечу.")
    print(f"Пользователь добавлен: ID = {message.chat.id}, Name = {name}")  # Диагностика

# Команда для отправки сообщения пользователю
@bot.message_handler(commands=['send_message'])
def send_message(message):
    if message.chat.id in admins:
        parts = message.text.split(maxsplit=2)
        if len(parts) > 2:
            user_id = int(parts[1])
            user_message = parts[2]
            bot.send_message(user_id, f"Администратор: {user_message}")
            bot.reply_to(message, f"Сообщение отправлено пользователю {user_id}.")
        else:
            bot.reply_to(message, "Пожалуйста, укажите ID пользователя и текст сообщения.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда ahelp для получения списка админских команд
@bot.message_handler(commands=['ahelp'])
def admin_help(message):
    if message.chat.id in admins:
        help_text = (
            "/admin_clear [ID] - Очистить память пользователя\n"
            "/list_users - Показать всех пользователей\n"
            "/history [ID] - Показать историю сообщений пользователя\n"
            "/user_stats [ID] - Показать статистику пользователя\n"
            "/allmsg [сообщение] - Отправить сообщение всем пользователям\n"
            "/send_message [ID] [сообщение] - Отправить личное сообщение пользователю\n"
            "/block [ID] - Заблокировать пользователя\n"
            "/unblock [ID] - Разблокировать пользователя\n"
            "/clear_all - Очистить всю историю чата (требуется подтверждение)\n" # Added line
        )
        bot.reply_to(message, help_text)
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

@bot.message_handler(commands=['help'])
def help_command(message):
    help_text = (
        "Список команд:\n"
        "/start - Начать работу с ботом\n"
        "/admin (сообщение ) - обратиться к администратору\n"
        "/help - Показать этот список команд\n"
    )
    bot.reply_to(message, help_text)

# Команда для отправки сообщения всем пользователям
@bot.message_handler(commands=['allmsg'])
def allmsg(message):
    if message.chat.id in admins:
        parts = message.text.split(maxsplit=1)
        if len(parts) > 1:
            admin_message = f"Админ: {parts[1]}"
            cursor.execute('SELECT user_id FROM users')
            users = cursor.fetchall()
            for user in users:
                try:
                    bot.send_message(user[0], admin_message)
                except Exception as e:
                    print(f"Не удалось отправить сообщение пользователю {user[0]}: {str(e)}")
            bot.reply_to(message, "Сообщение отправлено всем пользователям.")
        else:
            bot.reply_to(message, "Пожалуйста, укажите текст сообщения.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда для просмотра истории пользователя
@bot.message_handler(commands=['history'])
def user_history(message):
    if message.chat.id in admins:
        try:
            user_id = int(message.text.split()[1])
            cursor.execute('SELECT user_message, bot_response, timestamp FROM chat_history WHERE user_id = ?', (user_id,))
            history = cursor.fetchall()
            if history:
                history_text = "\n".join([f"{row[2]} - Вы: {row[0]}\nБот: {row[1]}" for row in history])
                bot.reply_to(message, history_text)
            else:
                bot.reply_to(message, f"Нет истории сообщений для пользователя {user_id}.")
        except IndexError:
            bot.reply_to(message, "Пожалуйста, укажите ID пользователя.")
        except ValueError:
            bot.reply_to(message, "Неверный формат ID пользователя.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда для просмотра статистики пользователя
@bot.message_handler(commands=['user_stats'])
def user_stats(message):
    if message.chat.id in admins:
        try:
            user_id = int(message.text.split()[1])
            cursor.execute('SELECT COUNT(*) FROM chat_history WHERE user_id = ?', (user_id,))
            message_count = cursor.fetchone()[0]
            bot.reply_to(message, f"Пользователь {user_id} отправил {message_count} сообщений.")
        except IndexError:
            bot.reply_to(message, "Пожалуйста, укажите ID пользователя.")
        except ValueError:
            bot.reply_to(message, "Неверный формат ID пользователя.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда для очистки памяти любого пользователя
@bot.message_handler(commands=['admin_clear'])
def admin_clear_memory(message):
    if message.chat.id in admins:
        try:
            user_id = int(message.text.split()[1])
            cursor.execute('DELETE FROM chat_history WHERE user_id = ?', (user_id,))
            db_connection.commit()
            if user_id in chat_context:
                del chat_context[user_id]
            bot.reply_to(message, f"Память пользователя {user_id} очищена, контекст удалён.")
        except IndexError:
            bot.reply_to(message, "Пожалуйста, укажите ID пользователя.")
        except ValueError:
            bot.reply_to(message, "Неверный формат ID пользователя.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

@bot.message_handler(commands=['admin'])
def admin_message(message):
    user_id = message.chat.id
    msg = message.text.split(maxsplit=1)

    # Fetch username from the database
    cursor.execute("SELECT username FROM users WHERE user_id = ?", (user_id,))
    user_data = cursor.fetchone()
    username = user_data[0] if user_data else "Unknown User" # Handle case where user isn't in the database

    if len(msg) > 1:
        user_message = f"Пользователь {username}: {msg[1]}"
    else:
        user_message = f"Пользователь {username} обратился к администратору."

    for admin_id in admins:
        try:
            bot.send_message(admin_id, user_message)
        except Exception as e:
            print(f"Не удалось отправить сообщение администратору {admin_id}: {str(e)}")
    bot.reply_to(message, "Ваше сообщение отправлено администратору.")

@bot.message_handler(commands=['clear_all'])
def clear_all_chat_history(message):
    if message.chat.id in admins:
        bot.reply_to(message, "Вы уверены, что хотите удалить ВСЮ историю чата?  Введите 'да' для подтверждения.")
        bot.register_next_step_handler(message, confirm_clear_all)
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

def confirm_clear_all(message):
    if message.text.lower() == 'да':
        try:
            cursor.execute("DELETE FROM chat_history")
            db_connection.commit()
            bot.reply_to(message, "История чата успешно очищена.")
        except Exception as e:
            bot.reply_to(message, f"Произошла ошибка при очистке истории чата: {str(e)}")
    else:
        bot.reply_to(message, "Очистка истории чата отменена.")


# Команда для блокировки пользователя
@bot.message_handler(commands=['block'])
def block_user(message):
    if message.chat.id in admins:
        try:
            user_id = int(message.text.split()[1])
            cursor.execute('UPDATE users SET is_blocked = 1 WHERE user_id = ?', (user_id,))
            db_connection.commit()
            bot.reply_to(message, f"Пользователь {user_id} заблокирован.")
        except IndexError:
            bot.reply_to(message,"Пожалуйста, укажите ID пользователя.")
        except ValueError: bot.reply_to(message, "Неверный формат ID пользователя.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда для разблокировки пользователя
@bot.message_handler(commands=['unblock'])
def unblock_user(message):
    if message.chat.id in admins:
        try:
            user_id = int(message.text.split()[1])
            cursor.execute('UPDATE users SET is_blocked = 0 WHERE user_id = ?', (user_id,))
            db_connection.commit()
            bot.reply_to(message, f"Пользователь {user_id} разблокирован.")
        except IndexError:
            bot.reply_to(message, "Пожалуйста, укажите ID пользователя.")
        except ValueError:
            bot.reply_to(message, "Неверный формат ID пользователя.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Команда для просмотра списка пользователей
@bot.message_handler(commands=['list_users'])
def list_users(message):
    if message.chat.id in admins:
        cursor.execute('SELECT user_id, username FROM users')
        users = cursor.fetchall()
        print(f"Пользователи в базе данных: {users}")  # Диагностика

        if users:
            user_list = "\n".join([f"ID: {user[0]}, Username: {user[1] or 'N/A'}" for user in users])
            bot.reply_to(message, f"Список пользователей:\n{user_list}")
        else:
            bot.reply_to(message, "Нет пользователей в базе данных.")
    else:
        bot.reply_to(message, "У вас нет прав для выполнения этой команды.")

# Обработка текстовых сообщений
@bot.message_handler(func=lambda message: True)
def handle_message(message):
    user_id = message.chat.id
    cursor.execute('SELECT is_blocked FROM users WHERE user_id = ?', (user_id,))
    blocked = cursor.fetchone()
    if blocked and blocked[0] == 1:
        bot.reply_to(message, "Вы заблокированы и не можете отправлять сообщения.")
        return

    if user_id not in chat_context:
        chat_context[user_id] = []

    try:
        result = client.predict(
            inputs=message.text,
            top_p=1,
            temperature=1,
            chat_counter=len(chat_context[user_id]),
            chatbot=chat_context[user_id],
            api_name="/predict"
        )

        if isinstance(result, tuple) and len(result) > 0 and isinstance(result[0], list) and len(result[0]) > 0:
            response_text = result[0][-1][1] if len(result[0][-1]) > 1 else "Не удалось получить ответ."
        else:
            response_text = "Не удалось получить ответ."

        # Сохранение сообщения и ответа в базу данных
        cursor.execute('INSERT INTO chat_history (user_id, user_message, bot_response, timestamp) VALUES (?, ?, ?, ?)',
                       (user_id, message.text, response_text, datetime.now()))
        db_connection.commit()

        # Отправка ответа, если он слишком длинный
        max_message_length = 4000
        while len(response_text) > max_message_length:
            bot.send_message(message.chat.id, response_text[:max_message_length])
            response_text = response_text[max_message_length:]

        bot.send_message(message.chat.id, response_text)

        # Обновление контекста чата
        chat_context[user_id].append((message.text, response_text))

    except Exception as e:
        bot.reply_to(message, f"Произошла ошибка: {str(e)}")

# Запуск бота
if __name__ == '__main__':
    bot.polling(none_stop=True)
что можно добавить?