import asyncio
import logging
import os
from logging.handlers import RotatingFileHandler
from aiogram import Bot, Dispatcher, types
from aiogram.filters import Command
from aiogram.types import BotCommand

from config import BOT_TOKEN, ALLOWED_CHAT_ID
from prompts import SYSTEM_PROMPT
from llm import ask_llm
from chat_history import load_history, add_message
from scheduler import BytikScheduler

LOG_DIR = "logs"
os.makedirs(LOG_DIR, exist_ok=True)

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[
        RotatingFileHandler(
            os.path.join(LOG_DIR, "bytik.log"),
            maxBytes=5*1024*1024,
            backupCount=3,
            encoding="utf-8",
        ),
        logging.StreamHandler(),
    ],
)
logger = logging.getLogger(__name__)

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

def is_allowed_chat(chat_id: int) -> bool:
    return chat_id == ALLOWED_CHAT_ID

@dp.message(Command("start"))
async def cmd_start(message: types.Message):
    if not is_allowed_chat(message.chat.id):
        logger.warning(f"Попытка /start из неразрешённого чата: {message.chat.id}")
        return
    await message.answer("Привет, Егор! 👋 Я Байтик, твой робот-помощник! Спрашивай меня о чём угодно! 🤖")

@dp.message(Command("clear"))
async def cmd_clear(message: types.Message):
    if not is_allowed_chat(message.chat.id):
        return
    from chat_history import clear_history
    clear_history(message.from_user.id)
    await message.answer("История наших разговоров очищена! 🧹")

@dp.message()
async def handle_message(message: types.Message):
    if not message.text:
        return

    if not is_allowed_chat(message.chat.id):
        logger.debug(f"Игнорирую сообщение из чата {message.chat.id}")
        return

    user_message = message.text.strip()
    logger.info(f"Сообщение от user {message.from_user.id}: {user_message[:100]}")

    typing_msg = await message.answer("Думаю... 🤔")

    history = load_history(message.from_user.id)
    messages_for_llm = [{"role": "system", "content": SYSTEM_PROMPT}] + history
    messages_for_llm.append({"role": "user", "content": user_message})

    add_message(message.from_user.id, "user", user_message)

    answer = await ask_llm(messages_for_llm)

    add_message(message.from_user.id, "assistant", answer)

    try:
        await typing_msg.edit_text(answer)
    except Exception:
        await message.answer(answer)

@dp.my_chat_member()
async def handle_bot_status_change(update: types.ChatMemberUpdated):
    chat_id = update.chat.id
    new_status = update.new_chat_member.status

    if new_status == "member" and chat_id != ALLOWED_CHAT_ID:
        logger.warning(f"Бот добавлен в неразрешённый чат {chat_id}. Покидаю.")
        await bot.leave_chat(chat_id)
    elif new_status == "left":
        logger.info(f"Бот удалён из чата {chat_id}")

async def set_commands():
    commands = [
        BotCommand(command="start", description="Начать общение"),
        BotCommand(command="clear", description="Очистить историю диалога"),
    ]
    await bot.set_my_commands(commands)

async def main():
    global scheduler
    await set_commands()

    scheduler = BytikScheduler(bot)
    scheduler.start()

    logger.info(f"Бот запущен. Whitelist chat_id: {ALLOWED_CHAT_ID}")
    await dp.start_polling(bot)

async def on_shutdown():
    if scheduler:
        scheduler.shutdown()
    await bot.session.close()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except (KeyboardInterrupt, SystemExit):
        logger.info("Бот остановлен")
