import os
import logging
from telegram import Update, ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import (
    ApplicationBuilder,
    CommandHandler,
    MessageHandler,
    CallbackQueryHandler,
    ContextTypes,
    filters,
    ConversationHandler,
)
from openai import OpenAI
from dotenv import load_dotenv

# Загрузка переменных окружения из .env файла
load_dotenv()

# Настройка логирования
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    level=logging.INFO
)
logger = logging.getLogger(__name__)

# Загрузка токенов из переменных окружения
TELEGRAM_TOKEN = os.getenv("TELEGRAM_TOKEN")
OPENROUTER_API_KEY = os.getenv("OPENROUTER_API_KEY")

if not TELEGRAM_TOKEN or not OPENROUTER_API_KEY:
    logger.error("Отсутствуют необходимые API-ключи. Проверьте файл .env.")
    exit(1)

# Инициализация клиента OpenAI
client = OpenAI(
    base_url="https://openrouter.ai/api/v1",
    api_key=OPENROUTER_API_KEY,
)

# Словарь для хранения контекста разговора для каждого пользователя
user_contexts = {}

# Словарь для хранения выбранной модели для каждого пользователя
user_models = {}

# Доступные модели
available_models = [
    "liquid/lfm-40b:free",
    "nousresearch/hermes-3-llama-3.1-405b:free",
    "meta-llama/llama-3.1-70b-instruct:free",
    "meta-llama/llama-3.1-405b-instruct:free",
    "google/gemini-pro-1.5-exp",
    "google/gemini-flash-1.5-exp"
]

# Состояния для ConversationHandler (если понадобится в будущем)
SELECTING_MODEL = 1

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    user_contexts[user_id] = []
    user_models[user_id] = available_models[0]  # Устанавливаем модель по умолчанию
    await show_main_menu(update, context)

async def show_main_menu(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    current_model = user_models.get(user_id, available_models[0])
    keyboard = [
        [KeyboardButton("🆕 Новый чат")],
        [KeyboardButton("🧹 Очистить контекст")],
        [KeyboardButton("❓ Помощь")],
        [KeyboardButton("⚙️ Выбрать модель")],
        [KeyboardButton(f"📄 Текущая модель: {current_model}")]
    ]
    reply_markup = ReplyKeyboardMarkup(keyboard, resize_keyboard=True)
    await update.message.reply_text('📚 Добро пожаловать в ИИ-бот! Выберите действие:', reply_markup=reply_markup)

async def new_chat(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    user_contexts[user_id] = []
    await update.message.reply_text('🆕 Начат новый чат. Задавайте ваши вопросы!')

async def clear_context(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    user_contexts[user_id] = []
    await update.message.reply_text('🧹 Контекст очищен. Теперь вы можете начать с чистого листа!')

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    help_text = (
        "🤖 *ИИ-Бот Инструкция*\n\n"
        "Вот что вы можете делать:\n"
        "• *Новый чат* - Начать разговор с нуля.\n"
        "• *Очистить контекст* - Удалить текущий разговорный контекст.\n"
        "• *Помощь* - Показать это сообщение.\n"
        "• *Выбрать модель* - Выбрать модель ИИ для генерации ответов.\n\n"
        "Также вы можете использовать следующие команды:\n"
        "/start - Перезапустить бота\n"
        "/new_chat - Начать новый чат\n"
        "/clear_context - Очистить контекст\n"
        "/help - Показать инструкцию\n"
        "/set_model <model_name> - Установить модель для генерации ответов\n\n"
        "📌 *Доступные модели:*\n" +
        "\n".join(f"- {model}" for model in available_models)
    )
    await update.message.reply_text(help_text, parse_mode='Markdown')

async def set_model_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    try:
        model_name = context.args[0]
        if model_name in available_models:
            user_models[user_id] = model_name
            await update.message.reply_text(f'✅ Модель установлена на *{model_name}*', parse_mode='Markdown')
        else:
            await update.message.reply_text(f'❌ Модель *{model_name}* недоступна.', parse_mode='Markdown')
    except IndexError:
        await update.message.reply_text('ℹ️ Пожалуйста, укажите модель. Например: /set_model liquid/lfm-40b:free')

async def select_model(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    keyboard = [
        [InlineKeyboardButton(model, callback_data=model)] for model in available_models
    ]
    keyboard.append([InlineKeyboardButton("🔙 Назад", callback_data="back")])
    reply_markup = InlineKeyboardMarkup(keyboard)
    await update.message.reply_text('📄 *Выберите модель:*', parse_mode='Markdown', reply_markup=reply_markup)

async def button_handler(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    query = update.callback_query
    await query.answer()
    user_id = query.from_user.id

    if query.data == "back":
        await show_main_menu(update, context)
    elif query.data in available_models:
        user_models[user_id] = query.data
        await query.edit_message_text(f'✅ Модель установлена на *{query.data}*', parse_mode='Markdown')
        await show_main_menu(update, context)
    else:
        await query.edit_message_text('❌ Неизвестная команда.')

async def handle_message(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
    user_id = update.effective_user.id
    user_message = update.message.text

    # Игнорируем нажатия кнопок
    if user_message.startswith('/'):
        return

    # Проверка наличия контекста
    if user_id not in user_contexts:
        user_contexts[user_id] = []
        user_models[user_id] = available_models[0]

    user_contexts[user_id].append({"role": "user", "content": user_message})

    # Получение ответа ИИ
    model = user_models.get(user_id, available_models[0])
    try:
        completion = client.chat.completions.create(
            model=model,
            messages=user_contexts[user_id]
        )
        if completion.choices and completion.choices[0].message:
            ai_response = completion.choices[0].message.content
        else:
            ai_response = "❗ Извините, я не смог обработать ваш запрос."
    except Exception as e:
        logger.error(f"Ошибка при получении ответа от ИИ: {e}")
        ai_response = "⚠️ Произошла ошибка при обработке вашего запроса."

    user_contexts[user_id].append({"role": "assistant", "content": ai_response})

    # Отправка ответа ИИ пользователю
    await update.message.reply_text(ai_response)

def main() -> None:
    # Создание приложения и передача ему токена вашего бота.
    application = ApplicationBuilder().token(TELEGRAM_TOKEN).build()

    # Обработка различных команд - ответ в Telegram
    application.add_handler(CommandHandler("start", start))
    application.add_handler(CommandHandler("new_chat", new_chat))
    application.add_handler(CommandHandler("clear_context", clear_context))
    application.add_handler(CommandHandler("help", help_command))
    application.add_handler(CommandHandler("set_model", set_model_command))

    # Обработка нажатий инлайн-кнопок
    application.add_handler(CallbackQueryHandler(button_handler))

    # Обработка некомандных сообщений - взаимодействие с ИИ
    application.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, handle_message))

    # Запуск бота
    application.run_polling()

if __name__ == '__main__':
    main()           Запросы к боту не работаются отдельно от запросов, когда нажимаешь команду боту, он, вместо того чтобы что-то сделать, это направляет ИИ через API ai, хоть не должен так делать.