import asyncio
import logging
import signal
import os

from dotenv import load_dotenv
from telegram import Update
from telegram.ext import Application, CommandHandler, CallbackQueryHandler

from bot import database, handlers
from bot import background_tasks

# Enable logging
logging.basicConfig(
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=logging.INFO
)
# Quieten down the HTTPX logger, which is very verbose
logging.getLogger("httpx").setLevel(logging.WARNING)
logger = logging.getLogger(__name__)

# A global event to signal shutdown
shutdown_event = asyncio.Event()

def signal_handler(sig, frame):
    """Gracefully handle shutdown signals."""
    logger.info("Shutdown signal received. Shutting down gracefully...")
    shutdown_event.set()

async def main() -> None:
    """Start the bot and wait for a shutdown signal."""
    load_dotenv()
    TOKEN = os.getenv("TELEGRAM_TOKEN")

    if not TOKEN or TOKEN == "YOUR_TELEGRAM_BOT_TOKEN_HERE":
        logger.error("TELEGRAM_TOKEN is not set! Please edit your .env file.")
        return

    await database.create_tables()

    application = Application.builder().token(TOKEN).build()

    application.add_handler(CommandHandler("start", handlers.start))
    application.add_handler(CommandHandler("map", handlers.export_map))
    application.add_handler(CommandHandler("spawns", handlers.spawn_stats))
    application.add_handler(CallbackQueryHandler(handlers.button_handler))

    async with application:
        await application.start()
        await application.updater.start_polling(allowed_updates=Update.ALL_TYPES)
        logger.info("Bot is running and polling for updates...")
        
        # Start the spawn manager
        from bot import spawn_manager
        await spawn_manager.start_spawn_manager()
        
        # Start the background tasks
        logger.info("Starting background tasks...")
        decay_task = asyncio.create_task(background_tasks.decay_dropped_items(shutdown_event))
        stamina_task = asyncio.create_task(background_tasks.regenerate_stamina(shutdown_event))
        combat_timer_task = asyncio.create_task(background_tasks.check_combat_timers(shutdown_event))
        corpse_decay_task = asyncio.create_task(background_tasks.decay_corpses(shutdown_event))
        status_effects_task = asyncio.create_task(background_tasks.process_status_effects(shutdown_event))
        logger.info("✅ All background tasks started")

        await shutdown_event.wait()

        await application.updater.stop()
        await application.stop()
        
        # Ensure the background tasks are also cancelled on shutdown
        logger.info("Stopping background tasks...")
        decay_task.cancel()
        stamina_task.cancel()
        combat_timer_task.cancel()
        corpse_decay_task.cancel()
        status_effects_task.cancel()
        logger.info("Bot has been shut down.")


if __name__ == "__main__":
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGTERM, signal_handler)

    try:
        asyncio.run(main())
    except (KeyboardInterrupt, SystemExit):
        logger.info("Main function interrupted.")
